summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2014-04-01 22:46:43 -0300
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2014-04-01 22:46:43 -0300
commitdbe93591ae5bbf4f43b025e78d0b837fca8a1789 (patch)
tree5621cddcb6aa68ef816028ca1be7edadd4331f08
parentbe9f9fc3f5e7b684d849279765ffd048d3a87c55 (diff)
parent3c125297edfe588dc195925c43c6a1ea54ac7060 (diff)
downloadaskbot-dbe93591ae5bbf4f43b025e78d0b837fca8a1789.tar.gz
askbot-dbe93591ae5bbf4f43b025e78d0b837fca8a1789.tar.bz2
askbot-dbe93591ae5bbf4f43b025e78d0b837fca8a1789.zip
Merge branch 'master' into user-questions-pagination
-rwxr-xr-x.gitignore2
-rw-r--r--README.rst35
-rw-r--r--askbot/__init__.py4
-rw-r--r--askbot/conf/__init__.py1
-rw-r--r--askbot/conf/access_control.py22
-rw-r--r--askbot/conf/group_settings.py4
-rw-r--r--askbot/conf/login_providers.py53
-rw-r--r--askbot/conf/minimum_reputation.py20
-rw-r--r--askbot/conf/settings_wrapper.py36
-rw-r--r--askbot/conf/site_modes.py5
-rw-r--r--askbot/conf/site_settings.py30
-rw-r--r--askbot/conf/user_settings.py13
-rw-r--r--askbot/conf/words.py912
-rw-r--r--askbot/const/__init__.py25
-rw-r--r--askbot/const/message_keys.py32
-rw-r--r--askbot/deps/django_authopenid/forms.py3
-rw-r--r--askbot/deps/django_authopenid/util.py28
-rw-r--r--askbot/deps/django_authopenid/views.py33
-rw-r--r--askbot/deps/livesettings/views.py2
-rw-r--r--askbot/doc/source/askbot/layout.html6
-rw-r--r--askbot/doc/source/changelog.rst15
-rw-r--r--askbot/doc/source/contributors.rst9
-rw-r--r--askbot/doc/source/index.rst4
-rw-r--r--askbot/doc/source/live-settings.rst17
-rw-r--r--askbot/doc/source/localization.rst81
-rw-r--r--askbot/doc/source/management-commands.rst39
-rw-r--r--askbot/doc/source/multilingual.rst46
-rw-r--r--askbot/doc/source/mysql-to-postgres.rst114
-rw-r--r--askbot/doc/source/solr.rst80
-rw-r--r--askbot/doc/source/text-search.rst48
-rw-r--r--askbot/feed.py22
-rw-r--r--askbot/forms.py113
-rw-r--r--askbot/locale/ar/LC_MESSAGES/django.mobin44591 -> 171220 bytes
-rw-r--r--askbot/locale/ar/LC_MESSAGES/django.po2285
-rw-r--r--askbot/locale/ar/LC_MESSAGES/djangojs.mobin10876 -> 12640 bytes
-rw-r--r--askbot/locale/ar/LC_MESSAGES/djangojs.po62
-rw-r--r--askbot/locale/de/LC_MESSAGES/django.mobin143912 -> 143894 bytes
-rw-r--r--askbot/locale/de/LC_MESSAGES/django.po12
-rw-r--r--askbot/locale/en/LC_MESSAGES/django.mobin1180 -> 626 bytes
-rw-r--r--askbot/locale/en/LC_MESSAGES/django.po1893
-rw-r--r--askbot/locale/en/LC_MESSAGES/djangojs.mobin1943 -> 1943 bytes
-rw-r--r--askbot/locale/en/LC_MESSAGES/djangojs.po109
-rw-r--r--askbot/locale/es/LC_MESSAGES/django.mobin170935 -> 183546 bytes
-rw-r--r--askbot/locale/es/LC_MESSAGES/django.po177
-rw-r--r--askbot/locale/fr/LC_MESSAGES/django.mobin178805 -> 180252 bytes
-rw-r--r--askbot/locale/fr/LC_MESSAGES/django.po45
-rw-r--r--askbot/locale/fr/LC_MESSAGES/djangojs.po4
-rw-r--r--askbot/locale/it/LC_MESSAGES/django.mobin98361 -> 98535 bytes
-rw-r--r--askbot/locale/it/LC_MESSAGES/django.po13
-rw-r--r--askbot/locale/it/LC_MESSAGES/djangojs.mobin5661 -> 6504 bytes
-rw-r--r--askbot/locale/it/LC_MESSAGES/djangojs.po29
-rw-r--r--askbot/locale/ko/LC_MESSAGES/django.po2
-rw-r--r--askbot/locale/ko/LC_MESSAGES/djangojs.mobin9819 -> 14052 bytes
-rw-r--r--askbot/locale/ko/LC_MESSAGES/djangojs.po146
-rw-r--r--askbot/locale/nb_NO/LC_MESSAGES/django.mobin145514 -> 157988 bytes
-rw-r--r--askbot/locale/nb_NO/LC_MESSAGES/django.po238
-rw-r--r--askbot/locale/ru/LC_MESSAGES/django.mobin208457 -> 208376 bytes
-rw-r--r--askbot/locale/ru/LC_MESSAGES/django.po6
-rw-r--r--askbot/locale/vi/LC_MESSAGES/django.mobin3335 -> 18802 bytes
-rw-r--r--askbot/locale/vi/LC_MESSAGES/django.po302
-rw-r--r--askbot/locale/vi/LC_MESSAGES/djangojs.mobin698 -> 13426 bytes
-rw-r--r--askbot/locale/vi/LC_MESSAGES/djangojs.po361
-rw-r--r--askbot/locale/zh_CN/LC_MESSAGES/django.mobin130934 -> 142943 bytes
-rw-r--r--askbot/locale/zh_CN/LC_MESSAGES/django.po406
-rw-r--r--askbot/locale/zh_HK/LC_MESSAGES/django.mobin2134 -> 2362 bytes
-rw-r--r--askbot/locale/zh_HK/LC_MESSAGES/django.po10
-rw-r--r--askbot/locale/zh_TW/LC_MESSAGES/django.mobin24545 -> 29926 bytes
-rw-r--r--askbot/locale/zh_TW/LC_MESSAGES/django.po205
-rw-r--r--askbot/locale/zh_TW/LC_MESSAGES/djangojs.mobin5142 -> 7032 bytes
-rw-r--r--askbot/locale/zh_TW/LC_MESSAGES/djangojs.po83
-rw-r--r--askbot/mail/__init__.py28
-rw-r--r--askbot/management/commands/askbot_add_osqa_content.py481
-rw-r--r--askbot/management/commands/askbot_add_xml_content.py558
-rw-r--r--askbot/management/commands/base.py240
-rw-r--r--askbot/management/commands/dump_forum.py36
-rw-r--r--askbot/management/commands/export_osqa.py215
-rw-r--r--askbot/management/commands/find_bodyless_questions.py19
-rw-r--r--askbot/management/commands/fix_comment_counts.py34
-rw-r--r--askbot/management/commands/fix_question_tags.py147
-rw-r--r--askbot/management/commands/generate_post_snippets.py18
-rw-r--r--askbot/management/commands/init_postgresql_full_text_search.py4
-rw-r--r--askbot/management/commands/load_forum.py16
-rw-r--r--askbot/management/commands/merge_users.py45
-rw-r--r--askbot/management/commands/rename_tags.py5
-rw-r--r--askbot/management/commands/rename_tags_id.py4
-rw-r--r--askbot/management/commands/send_accept_answer_reminders.py11
-rw-r--r--askbot/management/commands/send_email_alerts.py4
-rw-r--r--askbot/management/commands/send_unanswered_question_reminders.py6
-rw-r--r--askbot/media/jquery-openid/jquery.openid.js5
-rw-r--r--askbot/media/js/live_search.js4
-rw-r--r--askbot/media/js/post.js124
-rw-r--r--askbot/media/js/tag_selector.js8
-rw-r--r--askbot/media/js/user.js2
-rw-r--r--askbot/media/js/utils.js42
-rw-r--r--askbot/media/js/wmd/wmd.js17
-rw-r--r--askbot/media/style/style.css315
-rw-r--r--askbot/media/style/style.less378
-rw-r--r--askbot/middleware/cancel.py2
-rw-r--r--askbot/middleware/forum_mode.py9
-rw-r--r--askbot/migrations/0006_add_subscription_setting_for_comments_and_mentions.py2
-rw-r--r--askbot/migrations/0032_auto__del_field_badgedata_multiple__del_field_badgedata_description__d.py3
-rw-r--r--askbot/migrations/0171_auto__add_importedobjectinfo__add_importrun.py439
-rw-r--r--askbot/migrations_api/__init__.py2
-rw-r--r--askbot/models/__init__.py661
-rw-r--r--askbot/models/badges.py165
-rw-r--r--askbot/models/meta.py32
-rw-r--r--askbot/models/post.py90
-rw-r--r--askbot/models/question.py81
-rw-r--r--askbot/models/reply_by_email.py13
-rw-r--r--askbot/models/repute.py16
-rw-r--r--askbot/models/user.py13
-rw-r--r--askbot/search/haystack/__init__.py2
-rw-r--r--askbot/search/state_manager.py1
-rw-r--r--askbot/skins/loaders.py3
-rw-r--r--askbot/startup_procedures.py11
-rw-r--r--askbot/tasks.py5
-rw-r--r--askbot/templates/404.html7
-rw-r--r--askbot/templates/500.html14
-rw-r--r--askbot/templates/answer_edit.html5
-rw-r--r--askbot/templates/ask.html24
-rw-r--r--askbot/templates/authopenid/changeemail.html29
-rw-r--r--askbot/templates/authopenid/providers_javascript.html19
-rw-r--r--askbot/templates/authopenid/signin.html26
-rw-r--r--askbot/templates/authopenid/widget_signin.html14
-rw-r--r--askbot/templates/badges.html3
-rw-r--r--askbot/templates/close.html6
-rw-r--r--askbot/templates/email/delayed_email_alert.html2
-rw-r--r--askbot/templates/email/insufficient_rep_to_post_by_email.html4
-rw-r--r--askbot/templates/email/macros.html87
-rw-r--r--askbot/templates/email/post_as_subthread.html4
-rw-r--r--askbot/templates/email/quoted_post.html6
-rw-r--r--askbot/templates/email/re_welcome_lamson_on.html2
-rw-r--r--askbot/templates/email/welcome_lamson_on.html2
-rw-r--r--askbot/templates/embed/ask_by_widget.html4
-rw-r--r--askbot/templates/embed/widgets.html4
-rw-r--r--askbot/templates/faq_static.html9
-rw-r--r--askbot/templates/list_suggested_tags.html6
-rw-r--r--askbot/templates/livesettings/group_settings.html6
-rw-r--r--askbot/templates/macros.html19
-rw-r--r--askbot/templates/main_page.html4
-rw-r--r--askbot/templates/main_page/headline.html2
-rw-r--r--askbot/templates/main_page/javascript.html1
-rw-r--r--askbot/templates/main_page/nothing_found.html8
-rw-r--r--askbot/templates/main_page/questions_loop.html2
-rw-r--r--askbot/templates/main_page/tab_bar.html2
-rw-r--r--askbot/templates/meta/bottom_scripts.html1
-rw-r--r--askbot/templates/question.html44
-rw-r--r--askbot/templates/question/answer_controls.html6
-rw-r--r--askbot/templates/question/answer_tab_bar.html15
-rw-r--r--askbot/templates/question/answer_vote_buttons.html10
-rw-r--r--askbot/templates/question/closed_question_info.html8
-rw-r--r--askbot/templates/question/content.html6
-rw-r--r--askbot/templates/question/new_answer_form.html25
-rw-r--r--askbot/templates/question/sidebar.html15
-rw-r--r--askbot/templates/question_edit.html14
-rw-r--r--askbot/templates/question_retag.html4
-rw-r--r--askbot/templates/reopen.html12
-rw-r--r--askbot/templates/revisions.html2
-rw-r--r--askbot/templates/search/indexes/auth/user_text.txt2
-rw-r--r--askbot/templates/user_profile/user_answers_list.html8
-rw-r--r--askbot/templates/user_profile/user_email_subscriptions.html2
-rw-r--r--askbot/templates/user_profile/user_favorites.html4
-rw-r--r--askbot/templates/user_profile/user_info.html8
-rw-r--r--askbot/templates/user_profile/user_stats.html11
-rw-r--r--askbot/templates/user_profile/user_tabs.html11
-rw-r--r--askbot/templates/widgets/answer_edit_tips.html20
-rw-r--r--askbot/templates/widgets/ask_button.html8
-rw-r--r--askbot/templates/widgets/ask_form.html2
-rw-r--r--askbot/templates/widgets/group_info.html6
-rw-r--r--askbot/templates/widgets/header.html5
-rw-r--r--askbot/templates/widgets/question_edit_tips.html33
-rw-r--r--askbot/templates/widgets/question_summary.html9
-rw-r--r--askbot/templates/widgets/scope_nav.html8
-rw-r--r--askbot/templates/widgets/secondary_header.html43
-rw-r--r--askbot/templates/widgets/system_messages.html14
-rw-r--r--askbot/templates/widgets/tag_selector.html2
-rw-r--r--askbot/templates/widgets/three_column_category_selector.html2
-rw-r--r--askbot/templates/widgets/user_perms.html2
-rw-r--r--askbot/templatetags/extra_filters_jinja.py12
-rw-r--r--askbot/tests/db_api_tests.py8
-rw-r--r--askbot/tests/email_alert_tests.py2
-rw-r--r--askbot/tests/form_tests.py3
-rw-r--r--askbot/tests/page_load_tests.py9
-rw-r--r--askbot/tests/permission_assertion_tests.py26
-rw-r--r--askbot/tests/post_model_tests.py2
-rw-r--r--askbot/tests/utils.py11
-rw-r--r--askbot/tests/widget_tests.py5
-rw-r--r--askbot/urls.py31
-rw-r--r--askbot/user_messages/context_processors.py25
-rw-r--r--askbot/utils/get_plurals.py22
-rw-r--r--askbot/utils/html.py2
-rw-r--r--askbot/utils/markup.py4
-rw-r--r--askbot/utils/pluralization.py144
-rw-r--r--askbot/utils/slug.py8
-rw-r--r--askbot/views/commands.py14
-rw-r--r--askbot/views/context.py4
-rw-r--r--askbot/views/meta.py43
-rw-r--r--askbot/views/readers.py5
-rw-r--r--askbot/views/users.py12
-rw-r--r--askbot/views/widgets.py4
-rw-r--r--askbot/views/writers.py70
201 files changed, 8590 insertions, 5117 deletions
diff --git a/.gitignore b/.gitignore
index 011d7bde..296c3c4f 100755
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,8 @@ settings.py
*.iml
lint
env
+.vagrant
+/Vagrantfile
/custom_settings
/static
django
diff --git a/README.rst b/README.rst
index 43befd37..07cfe6b0 100644
--- a/README.rst
+++ b/README.rst
@@ -2,14 +2,39 @@
Askbot - Q&A forum
===================
-This is Askbot project - open source Q&A system, like StackOverflow, Yahoo Answers and some others
+This is Askbot project - open source Q&A system, like StackOverflow, Yahoo Answers and some others.
+Askbot is based on code of CNPROG, originally created by Mike Chen
+and Sailing Cai and some code written for OSQA.
Demos and hosting are available at http://askbot.com.
-**Translators:** please translate at https://www.transifex.com/projects/p/askbot/.
+How to contribute
+=================
+
+**Translators: DO NOT use git to contribute translations!!!** instead - translate at https://www.transifex.com/projects/p/askbot/.
All documentation is in the directory askbot/doc
-Askbot is based on code of CNPROG, originally created by Mike Chen
-and Sailing Cai and some code written for OSQA. Askbot had officially launched
-in April 2010.
+To contribute code, please fork and make pull requests.
+
+If you are planning to add a new feature, please bring it up for discussion at our forum
+(http://askbot.org/en/questions/) and mention that are willing to develop this feature.
+
+We will merge obvious bug fixes without questions, for more complex fixes
+please add a test case that fails before and passes after applying your fix.
+
+**Notes on using git for Askbot.** Please use topic branches only - one per feature or bugfix.
+Do not add multiple features and fixes into the same branch -
+those are much harder to understand and merge.
+
+Follow https://help.github.com/articles/fork-a-repo to to learn how to use
+`fetch` and `push` as well as other help on using git.
+
+License, copyright and trademarks
+=================================
+Askbot software is licensed under GPL, version 3.
+
+Copyright Askbot S.p.A and the project contributors, 2010-2013.
+
+"Askbot" is a trademark and service mark registered in the United States, number 4323777.
+
diff --git a/askbot/__init__.py b/askbot/__init__.py
index e96719c1..2ac9b6fb 100644
--- a/askbot/__init__.py
+++ b/askbot/__init__.py
@@ -7,7 +7,7 @@ basic actions on behalf of the forum application
import os
import platform
-VERSION = (0, 7, 48)
+VERSION = (0, 7, 49)
#keys are module names used by python imports,
#values - the package qualifier to use for pip
@@ -33,7 +33,7 @@ REQUIREMENTS = {
'recaptcha_works': 'django-recaptcha-works',
'openid': 'python-openid',
'pystache': 'pystache==0.3.1',
- 'pytz': 'pytz',
+ 'pytz': 'pytz==2013b',
'tinymce': 'django-tinymce==1.5.1b2',
'longerusername': 'longerusername',
'bs4': 'beautifulsoup4',
diff --git a/askbot/conf/__init__.py b/askbot/conf/__init__.py
index 0f92bf99..c1ed6ef0 100644
--- a/askbot/conf/__init__.py
+++ b/askbot/conf/__init__.py
@@ -28,6 +28,7 @@ import askbot.conf.badges
import askbot.conf.login_providers
import askbot.conf.access_control
import askbot.conf.site_modes
+import askbot.conf.words
#import main settings object
from askbot.conf.settings_wrapper import settings
diff --git a/askbot/conf/access_control.py b/askbot/conf/access_control.py
index 0e3dcb54..c339da6d 100644
--- a/askbot/conf/access_control.py
+++ b/askbot/conf/access_control.py
@@ -1,6 +1,8 @@
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import LOGIN_USERS_COMMUNICATION
from askbot.deps import livesettings
+from askbot.deps.livesettings import BooleanValue
+from askbot.deps.livesettings import StringValue
from django.utils.translation import ugettext_lazy as _
ACCESS_CONTROL = livesettings.ConfigurationGroup(
@@ -10,6 +12,26 @@ ACCESS_CONTROL = livesettings.ConfigurationGroup(
)
settings.register(
+ BooleanValue(
+ ACCESS_CONTROL,
+ 'READ_ONLY_MODE_ENABLED',
+ default=False,
+ description=_('Make site read-only'),
+ )
+)
+
+settings.register(
+ StringValue(
+ ACCESS_CONTROL,
+ 'READ_ONLY_MESSAGE',
+ default=_(
+ 'The site is temporarily read-only. '
+ 'Only viewing of the content is possible at the moment.'
+ )
+ )
+)
+
+settings.register(
livesettings.BooleanValue(
ACCESS_CONTROL,
'ASKBOT_CLOSED_FORUM_MODE',
diff --git a/askbot/conf/group_settings.py b/askbot/conf/group_settings.py
index 804b5502..cacbdacb 100644
--- a/askbot/conf/group_settings.py
+++ b/askbot/conf/group_settings.py
@@ -19,6 +19,7 @@ settings.register(
)
)
+"""
def group_name_update_callback(old_name, new_name):
from askbot.models.tag import clean_group_name
from askbot.models import Group
@@ -32,6 +33,7 @@ def group_name_update_callback(old_name, new_name):
group.name = cleaned_new_name
group.save()
return new_name
+"""
settings.register(
@@ -41,7 +43,7 @@ settings.register(
default = _('everyone'),
description = _('Global user group name'),
help_text = _('All users belong to this group automatically'),
- update_callback=group_name_update_callback
+ #update_callback=group_name_update_callback
)
)
diff --git a/askbot/conf/login_providers.py b/askbot/conf/login_providers.py
index 36f71502..faa6ae8c 100644
--- a/askbot/conf/login_providers.py
+++ b/askbot/conf/login_providers.py
@@ -62,6 +62,59 @@ settings.register(
)
)
+settings.register(
+ livesettings.BooleanValue(
+ LOGIN_PROVIDERS,
+ 'SIGNIN_CUSTOM_OPENID_ENABLED',
+ default=False,
+ description=_('Enable custom OpenID login')
+ )
+)
+
+settings.register(
+ livesettings.StringValue(
+ LOGIN_PROVIDERS,
+ 'SIGNIN_CUSTOM_OPENID_NAME',
+ default=_('Custom OpenID'),
+ description=_('Short name for the custom OpenID provider')
+ )
+)
+
+CUSTOM_OPENID_MODE_CHOICES = (
+ ('openid-direct', _('Direct button login')),
+ ('openid-username', _('Requires username'))
+)
+
+settings.register(
+ livesettings.StringValue(
+ LOGIN_PROVIDERS,
+ 'SIGNIN_CUSTOM_OPENID_MODE',
+ default='openid-direct',
+ description=_('Type of OpenID login'),
+ choices=CUSTOM_OPENID_MODE_CHOICES
+ )
+)
+
+settings.register(
+ livesettings.ImageValue(
+ LOGIN_PROVIDERS,
+ 'SIGNIN_CUSTOM_OPENID_LOGIN_BUTTON',
+ default='/images/logo.gif',
+ description=_('Upload custom OpenID icon'),
+ url_resolver=skin_utils.get_media_url
+ )
+)
+
+settings.register(
+ livesettings.StringValue(
+ LOGIN_PROVIDERS,
+ 'SIGNIN_CUSTOM_OPENID_ENDPOINT',
+ default='http://example.com',
+ description=_('Custom OpenID endpoint'),
+ help_text=_('Important: with the "username" mode must have a %%(username)s placeholder e.g. http://example.com/%%(username)s/'),
+ )
+)
+
providers = (
'local',
'AOL',
diff --git a/askbot/conf/minimum_reputation.py b/askbot/conf/minimum_reputation.py
index fd4df4b3..58b41c18 100644
--- a/askbot/conf/minimum_reputation.py
+++ b/askbot/conf/minimum_reputation.py
@@ -132,15 +132,6 @@ settings.register(
settings.register(
livesettings.IntegerValue(
MIN_REP,
- 'MIN_REP_TO_CLOSE_OWN_QUESTIONS',
- default=25,
- description=_('Close own questions'),
- )
-)
-
-settings.register(
- livesettings.IntegerValue(
- MIN_REP,
'MIN_REP_TO_RETAG_OTHERS_QUESTIONS',
default=50,
description=_('Retag questions posted by other people')
@@ -148,15 +139,6 @@ settings.register(
)
settings.register(
- livesettings.IntegerValue(
- MIN_REP,
- 'MIN_REP_TO_REOPEN_OWN_QUESTIONS',
- default=50,
- description=_('Reopen own questions')
- )
-)
-
-settings.register(
livesettings.IntegerValue(
MIN_REP,
'MIN_REP_TO_EDIT_WIKI',
@@ -188,7 +170,7 @@ settings.register(
MIN_REP,
'MIN_REP_TO_CLOSE_OTHERS_QUESTIONS',
default=200,
- description=_('Close questions asked by others')
+ description=_('Close and reopen questions')
)
)
diff --git a/askbot/conf/settings_wrapper.py b/askbot/conf/settings_wrapper.py
index 0a4ba45f..7fc9540d 100644
--- a/askbot/conf/settings_wrapper.py
+++ b/askbot/conf/settings_wrapper.py
@@ -20,6 +20,7 @@ at run time
askbot.deps.livesettings is a module developed for satchmo project
"""
+from django.conf import settings as django_settings
from django.core.cache import cache
from askbot.deps.livesettings import SortedDotDict, config_register
from askbot.deps.livesettings.functions import config_get
@@ -47,7 +48,11 @@ class ConfigSettings(object):
will be required in code to convert an app
depending on django.conf.settings to askbot.deps.livesettings
"""
- return getattr(self.__instance, key).value
+ hardcoded_setting = getattr(django_settings, 'ASKBOT_' + key, None)
+ if hardcoded_setting is None:
+ return getattr(self.__instance, key).value
+ else:
+ return hardcoded_setting
def get_default(self, key):
"""return the defalut value for the setting"""
@@ -93,24 +98,39 @@ class ConfigSettings(object):
self.__group_map[key] = group_key
def as_dict(self):
- settings = cache.get('askbot-livesettings')
+ cache_key = get_bulk_cache_key()
+ settings = cache.get(cache_key)
if settings:
return settings
else:
- self.prime_cache()
- return cache.get('askbot-livesettings')
+ self.prime_cache(cache_key)
+ return cache.get(cache_key)
@classmethod
- def prime_cache(cls, **kwargs):
+ def prime_cache(cls, cache_key, **kwargs):
"""reload all settings into cache as dictionary
"""
out = dict()
for key in cls.__instance.keys():
#todo: this is odd that I could not use self.__instance.items() mapping here
- out[key] = cls.__instance[key].value
- cache.set('askbot-livesettings', out)
+ hardcoded_setting = getattr(django_settings, 'ASKBOT_' + key, None)
+ if hardcoded_setting is None:
+ out[key] = cls.__instance[key].value
+ else:
+ out[key] = hardcoded_setting
+ cache.set(cache_key, out)
+
+
+def get_bulk_cache_key():
+ from askbot.utils.translation import get_language
+ return 'askbot-settings-' + get_language()
+
+
+def prime_cache_handler(*args, **kwargs):
+ cache_key = get_bulk_cache_key()
+ ConfigSettings.prime_cache(cache_key)
-signals.configuration_value_changed.connect(ConfigSettings.prime_cache)
+signals.configuration_value_changed.connect(prime_cache_handler)
#settings instance to be used elsewhere in the project
settings = ConfigSettings()
diff --git a/askbot/conf/site_modes.py b/askbot/conf/site_modes.py
index feadd32b..29e537db 100644
--- a/askbot/conf/site_modes.py
+++ b/askbot/conf/site_modes.py
@@ -6,7 +6,8 @@ Site modes settings:
"""
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import REP_AND_BADGES
-from askbot.deps.livesettings import ConfigurationGroup, BooleanValue
+from askbot.deps.livesettings import ConfigurationGroup
+from askbot.deps.livesettings import BooleanValue
from django.utils.translation import ugettext_lazy as _
LARGE_SITE_MODE_SETTINGS = {
@@ -20,9 +21,7 @@ LARGE_SITE_MODE_SETTINGS = {
'MIN_REP_TO_DELETE_OTHERS_COMMENTS': 2000,
'MIN_REP_TO_DELETE_OTHERS_POSTS': 5000,
'MIN_REP_TO_UPLOAD_FILES': 60,
- 'MIN_REP_TO_CLOSE_OWN_QUESTIONS': 250,
'MIN_REP_TO_RETAG_OTHERS_QUESTIONS': 500,
- 'MIN_REP_TO_REOPEN_OWN_QUESTIONS': 500,
'MIN_REP_TO_EDIT_WIKI': 750,
'MIN_REP_TO_EDIT_OTHERS_POSTS': 2000,
'MIN_REP_TO_VIEW_OFFENSIVE_FLAGS': 2000,
diff --git a/askbot/conf/site_settings.py b/askbot/conf/site_settings.py
index 805cc5dc..0ac5b081 100644
--- a/askbot/conf/site_settings.py
+++ b/askbot/conf/site_settings.py
@@ -7,8 +7,11 @@ from askbot.conf.super_groups import CONTENT_AND_UI
from askbot.deps import livesettings
from django.utils.translation import ugettext_lazy as _
from django.conf import settings as django_settings
+from django.core.validators import ValidationError, validate_email
+import re
from urlparse import urlparse
+
QA_SITE_SETTINGS = livesettings.ConfigurationGroup(
'QA_SITE_SETTINGS',
_('URLS, keywords & greetings'),
@@ -132,3 +135,30 @@ settings.register(
)
)
)
+
+def feedback_emails_callback(old_value, new_value):
+ """validates the fedback emails list"""
+ emails = []
+ for value in re.split('\s*,\s*', new_value):
+ if not value:
+ continue
+ try:
+ validate_email(value)
+ emails.append(value)
+ except ValidationError:
+ raise ValueError(
+ _("'%(value)s' is not a valid email") % {'value': value})
+ return ", ".join(emails)
+
+settings.register(
+ livesettings.StringValue(
+ QA_SITE_SETTINGS,
+ 'FEEDBACK_EMAILS',
+ description=_('Internal feedback form email recipients'),
+ help_text=_(
+ 'Comma separated list. If left empty, feedback mails are sent '
+ 'to admins and moderators'
+ ),
+ update_callback=feedback_emails_callback
+ )
+)
diff --git a/askbot/conf/user_settings.py b/askbot/conf/user_settings.py
index a2d8d386..d29e9278 100644
--- a/askbot/conf/user_settings.py
+++ b/askbot/conf/user_settings.py
@@ -37,8 +37,17 @@ settings.register(
livesettings.BooleanValue(
USER_SETTINGS,
'EDITABLE_SCREEN_NAME',
- default = True,
- description = _('Allow editing user screen name')
+ default=True,
+ description=_('Allow editing user screen name')
+ )
+)
+
+settings.register(
+ livesettings.BooleanValue(
+ USER_SETTINGS,
+ 'SHOW_ADMINS_PRIVATE_USER_DATA',
+ default=False,
+ description=_('Show email addresses to moderators')
)
)
diff --git a/askbot/conf/words.py b/askbot/conf/words.py
new file mode 100644
index 00000000..be4eb191
--- /dev/null
+++ b/askbot/conf/words.py
@@ -0,0 +1,912 @@
+"""
+General skin settings
+"""
+from askbot.conf.settings_wrapper import settings
+from askbot.deps.livesettings import ConfigurationGroup
+from askbot.deps.livesettings import values
+from django.utils.translation import ugettext_lazy as _
+from askbot.skins import utils as skin_utils
+from askbot import const
+from askbot.conf.super_groups import CONTENT_AND_UI
+
+WORDS = ConfigurationGroup(
+ 'WORDS',
+ _('Site terms vocabulary'),
+ super_group = CONTENT_AND_UI
+ )
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ASK_YOUR_QUESTION',
+ default=_('Ask Your Question'),
+ description=_('Ask Your Question'),
+ help_text=_('Used on a button')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_PLEASE_ENTER_YOUR_QUESTION',
+ default=_('Please enter your question'),
+ description=_('Please enter your question'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ASK_THE_GROUP',
+ default=_('Ask the Group'),
+ description=_('Ask the Group'),
+ help_text=_('Used on a button')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_POST_YOUR_ANSWER',
+ default=_('Post Your Answer'),
+ description=_('Post Your Answer'),
+ help_text=_('Used on a button')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ANSWER_YOUR_OWN_QUESTION',
+ default=_('Answer Your Own Question'),
+ description=_('Answer Your Own Question'),
+ help_text=_('Used on a button')
+ )
+)
+
+settings.register(
+ values.LongStringValue(
+ WORDS,
+ 'WORDS_INSTRUCTION_TO_ANSWER_OWN_QUESTION',
+ default=_(
+ '<span class="big strong">You are welcome to answer your own question</span>, '
+ 'but please make sure to give an <strong>answer</strong>. '
+ 'Remember that you can always <strong>revise your original question</strong>.'
+ ),
+ description=_('Instruction to answer own questions'),
+ help_text=_('HTML is allowed')
+ )
+)
+
+settings.register(
+ values.LongStringValue(
+ WORDS,
+ 'WORDS_INSTRUCTION_TO_POST_ANONYMOUSLY',
+ default=_(
+ '<span class="strong big">Please start posting anonymously</span> - '
+ 'your entry will be published after you log in or create a new account.'
+ ),
+ description=_('Instruction to post anonymously'),
+ help_text=_('HTML is allowed')
+ )
+)
+
+settings.register(
+ values.LongStringValue(
+ WORDS,
+ 'WORDS_INSTRUCTION_TO_GIVE_ANSWERS',
+ default=_(
+ 'Please try to <strong>give a substantial answer</strong>, '
+ 'for discussions, <strong>please use comments</strong> and '
+ '<strong>do remember to vote</strong>.'
+ ),
+ description=_('Instruction to give answers'),
+ help_text=_('HTML is allowed')
+ )
+)
+
+settings.register(
+ values.LongStringValue(
+ WORDS,
+ 'WORDS_INSTRUCTION_FOR_THE_CATEGORY_SELECTOR',
+ default=_(
+ 'Categorize your question using this tag selector or '
+ 'entering text in tag box.'
+ ),
+ description=_('Instruction for the catogory selector'),
+ help_text=_('Plain text only')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_EDIT_YOUR_PREVIOUS_ANSWER',
+ default=_('Edit Your Previous Answer'),
+ description=_('Edit Your Previous Answer'),
+ help_text=_('Used on a button')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ASK_QUESTIONS',
+ default=_('ask questions'),
+ description=_('ask questions')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ASKED',
+ default=_('asked'),
+ description=_('asked'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ASKED_FIRST_QUESTION',
+ default=_('Asked first question'),
+ description=_('Asked first question')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ASKED_BY_ME',
+ default=_('Asked by me'),
+ description=_('Asked by me')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ASKED_A_QUESTION',
+ default=_('Asked a question'),
+ description=_('Asked a question')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ANSWERED_A_QUESTION',
+ default=_('Answered a question'),
+ description=_('Answered a question')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ANSWERED_BY_ME',
+ default=_('Answered by me'),
+ description=_('Answered by me')
+ )
+)
+
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ACCEPTED_AN_ANSWER',
+ default=_('accepted an answer'),
+ description=_('accepted an answer')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_GAVE_ACCEPTED_ANSWER',
+ default=_('Gave accepted answer'),
+ description=_('Gave accepted answer')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ANSWERED',
+ default=_('answered'),
+ description=_('answered'),
+ )
+)
+
+settings.register(
+ values.LongStringValue(
+ WORDS,
+ 'WORDS_QUESTIONS_COUNTABLE_FORMS',
+ default='question\nquestions',
+ description=_('Countable plural forms for "queston"'),
+ help_text=_('Enter one form per line, pay attention')
+ )
+)
+
+settings.register(
+ values.LongStringValue(
+ WORDS,
+ 'WORDS_ANSWERS_COUNTABLE_FORMS',
+ default='answer\nanswers',
+ description=_('Countable plural forms for "answer"'),
+ help_text=_('Enter one form per line, pay attention')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_QUESTION_SINGULAR',
+ default=_('question'),
+ description=_('question (noun, singular)'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_QUESTION_PLURAL',
+ default=_('questions'),
+ description=_('questions (noun, plural)'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_UNANSWERED_QUESTION_SINGULAR',
+ default=_('unanswered question'),
+ description=_('unanswered question (singular)'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_UNANSWERED_QUESTION_PLURAL',
+ default=_('unanswered questions'),
+ description=_('unanswered questions (plural)'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ANSWER_SINGULAR',
+ default=_('answer'),
+ description=_('answer (noun, sungular)'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_QUESTION_VOTED_UP',
+ default=_('Question voted up'),
+ description=_('Question voted up'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ANSWER_VOTED_UP',
+ default=_('Answer voted up'),
+ description=_('Answer voted up'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_UPVOTED_ANSWER',
+ default=_('upvoted answer'),
+ description=_('upvoted answer'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_NICE_ANSWER',
+ default=_('Nice Answer'),
+ description=_('Nice Answer'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_NICE_QUESTION',
+ default=_('Nice Question'),
+ description=_('Nice Question'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_GOOD_ANSWER',
+ default=_('Good Answer'),
+ description=_('Good Answer'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_GOOD_QUESTION',
+ default=_('Good Question'),
+ description=_('Good Question'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_GREAT_ANSWER',
+ default=_('Great Answer'),
+ description=_('Great Answer'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_GREAT_QUESTION',
+ default=_('Great Question'),
+ description=_('Great Question'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_POPULAR_QUESTION',
+ default=_('Popular Question'),
+ description=_('Popular Question'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_NOTABLE_QUESTION',
+ default=_('Notable Question'),
+ description=_('Notable Question'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_FAMOUS_QUESTION',
+ default=_('Famous Question'),
+ description=_('Famous Question'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_STELLAR_QUESTION',
+ default=_('Stellar Question'),
+ description=_('Stellar Question'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_FAVORITE_QUESTION',
+ default=_('Favorite Question'),
+ description=_('Favorite Question'),
+ help_text='Badge name'
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_UPVOTED_ANSWERS',
+ default=_('upvoted answers'),
+ description=_('upvoted answers'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_SHOW_ONLY_QUESTIONS_FROM',
+ default=_('Show only questions from'),
+ description=_('Show only questions from'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_PLEASE_ASK_YOUR_QUESTION_HERE',
+ default=_('Please ask your question here'),
+ description=_('Please ask your question here'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_THIS_QUESTION_HAS_BEEN_DELETED',
+ default=_(
+ 'Sorry, this question has been '
+ 'deleted and is no longer accessible'
+ ),
+ description=_('This question has been deleted')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_PLEASE_ENTER_YOUR_QUESTION',
+ default=_('Please enter your question'),
+ description=_('Please enter your question'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_DELETE_YOUR_QUESTION',
+ default=_('delete your question'),
+ description=_('delete your question'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ASK_A_QUESTION_INTERESTING_TO_THIS_COMMUNITY',
+ default=_('ask a question interesting to this community'),
+ description=_('ask a question interesting to this community'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_NO_QUESTIONS_HERE',
+ default=_('No questions here.'),
+ description=_('No questions here.'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_PLEASE_FOLLOW_QUESTIONS',
+ default=_('Please follow some questions or follow some users.'),
+ description=_('Please follow some questions or follow some users.'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_PLEASE_FEEL_FREE_TO_ASK_YOUR_QUESTION',
+ default=_('Please feel free to ask your question!'),
+ description=_('Please feel free to ask your question!'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_SWAP_WITH_QUESTION',
+ default=_('swap with question'),
+ description=_('swap with question'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_REPOST_AS_A_QUESTION_COMMENT',
+ default=_('repost as a question comment'),
+ description=_('repost as a question comment'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ONLY_ONE_ANSWER_PER_USER_IS_ALLOWED',
+ default=_('(only one answer per user is allowed)'),
+ description=_('Only one answer per user is allowed'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ACCEPT_BEST_ANSWERS_FOR_YOUR_QUESTIONS',
+ default=_('Accept the best answers for your questions'),
+ description=_('Accept the best answers for your questions')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_AUTHOR_OF_THE_QUESTION',
+ default=_('author of the question'),
+ description=_('author of the question')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ACCEPT_OR_UNACCEPT_THE_BEST_ANSWER',
+ default=_('accept or unaccept the best answer'),
+ description=_('accept or unaccept the best answer')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ACCEPT_OR_UNACCEPT_OWN_ANSWER',
+ default=_('accept or unaccept your own answer'),
+ description=_('accept or unaccept your own answer'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_YOU_ALREADY_GAVE_AN_ANSWER',
+ default=_('you already gave an answer'),
+ description=_('you already gave an answer'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_GAVE_AN_ANSWER',
+ default=_('gave an answer'),
+ description=_('gave an answer'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ANSWER_OWN_QUESTIONS',
+ default=_('answer own questions'),
+ description=_('answer own questions'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ANSWERED_OWN_QUESTION',
+ default=_('Answered own question'),
+ description=_('Answered own question'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_REPOST_AS_A_COMMENT_UNDER_THE_OLDER_ANSWER',
+ default=_('repost as a comment under older answer'),
+ description=_('repost as a comment under older answer'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_INVITE_OTHERS_TO_HELP_ANSWER_THIS_QUESTION',
+ default=_('invite other to help answer this question'),
+ description=_('invite other to help answer this question'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_RELATED_QUESTIONS',
+ default=_('Related questions'),
+ description=_('Related questions'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_QUESTION_TOOLS',
+ default=_('Question Tools'),
+ description=_('Question Tools'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_THIS_QUESTION_IS_CURRENTLY_SHARED_ONLY_WITH',
+ default=_('Phrase: this question is currently shared only with:'),
+ description=_('Phrase: this question is currently shared only with:'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_BE_THE_FIRST_TO_ANSWER_THIS_QUESTION',
+ default=_('Be the first one to answer this question!'),
+ description=_('Be the first one to answer this question!'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_FOLLOWED_QUESTIONS',
+ default=_('followed questions'),
+ description=_('followed questions'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_FOLLOW_QUESTIONS',
+ default=_('follow questions'),
+ description=_('follow questions'),
+ help_text=_('Indefinite form')
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_COMMENTS_AND_ANSWERS_TO_OTHERS_QUESTIONS',
+ default = '',
+ description = _('Phrase: comments and answers to others questions'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_YOU_CAN_POST_QUESTIONS_BY_EMAILING_THEM_AT',
+ default=_('You can post questions by emailing them at'),
+ description=_('You can post questions by emailing them at'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_LIST_OF_QUESTIONS',
+ default=_('List of questions'),
+ description=_('List of questions'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_COMMUNITY_GIVES_YOU_AWARDS',
+ default=_('Community gives you awards for your questions, answers and votes'),
+ description=_('Community gives you awards for your questions, answers and votes'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_CLOSE_QUESTION',
+ default=_('Close question'),
+ description=_('Close question'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_CLOSE_QUESTIONS',
+ default=_('close questions'),
+ description=_('close questions'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_EDIT_QUESTION',
+ default=_('Edit question'),
+ description=_('Edit question'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_QUESTION_IN_ONE_SENTENCE',
+ default=_('Question - in one sentence'),
+ description=_('Question - in one sentence'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_RETAG_QUESTION',
+ default=_('Retag question'),
+ description=_('Retag question'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_RETAG_QUESTIONS',
+ default=_('retag questions'),
+ description=_('retag questions'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_REOPEN_QUESTION',
+ default=_('Reopen question'),
+ description=_('Reopen question'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_THERE_ARE_NO_UNANSWERED_QUESTIONS_HERE',
+ default=_('There are no unanswered questions here'),
+ description=_('There are no unanswered questions here'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_THIS_ANSWER_HAS_BEEN_SELECTED_AS_CORRECT',
+ default=_('this answer has been selected as correct'),
+ description=_('this answer has been selected as correct'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_MARK_THIS_ANSWER_AS_CORRECT',
+ default=_('mark this answer as correct'),
+ description=_('mark this answer as correct'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_LOGIN_SIGNUP_TO_ANSWER',
+ default=_('Login/Signup to Answer'),
+ description=_('Login/Signup to Answer'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_YOUR_ANSWER',
+ default=_('Your Answer'),
+ description=_('Your Answer'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ADD_ANSWER',
+ default=_('Add Answer'),
+ description=_('Add Answer'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_GIVE_AN_ANSWER_INTERESTING_TO_THIS_COMMUNITY',
+ default=_('give an answer interesting to this community'),
+ description=_('give an answer interesting to this community'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_GIVE_AN_ANSWER_INTERESTING_TO_THIS_COMMUNITY',
+ default=_('give an answer interesting to this community'),
+ description=_('give an answer interesting to this community'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_GIVE_A_GOOD_ANSWER',
+ default=_('give a substantial answer'),
+ description=_('give a substantial answer'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_TRY_TO_GIVE_AN_ANSWER',
+ default=_('try to give an answer, rather than engage into a discussion'),
+ description=_('try to give an answer, rather than engage into a discussion'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_SHOW_ONLY_SELECTED_ANSWERS_TO_ENQUIRERS',
+ default=_('show only selected answers to enquirers'),
+ description=_('show only selected answers to enquirers'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_UNANSWERED',
+ default = _('UNANSWERED'),
+ description = _('UNANSWERED'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_EDIT_ANSWER',
+ default=_('Edit Answer'),
+ description=_('Edit Answer'),
+ )
+)
+
+settings.register(
+ values.StringValue(
+ WORDS,
+ 'WORDS_ANSWERED',
+ default=_('Answered'),
+ description=_('Answered'),
+ )
+)
diff --git a/askbot/const/__init__.py b/askbot/const/__init__.py
index ff1d0883..35f9b26b 100644
--- a/askbot/const/__init__.py
+++ b/askbot/const/__init__.py
@@ -7,6 +7,7 @@ text in this project, all unicode text go here.
from django.utils.translation import ugettext_lazy as _
import re
+#todo: customize words
CLOSE_REASONS = (
(1, _('duplicate question')),
(2, _('question is off-topic or not relevant')),
@@ -122,6 +123,7 @@ DEFAULT_ANSWER_SORT_METHOD = 'votes'
#of Q.run_advanced_search
DEFAULT_POST_SORT_METHOD = 'activity-desc'
+#todo: customize words
POST_SCOPE_LIST = (
('all', _('all')),
('unanswered', _('unanswered')),
@@ -155,7 +157,9 @@ UNANSWERED_QUESTION_MEANING_CHOICES = (
#to do full string match
#IMPRTANT: tag related regexes must be portable between js and python
TAG_CHARS = r'\w+.#-'
-TAG_REGEX_BARE = r'[%s]+' % TAG_CHARS
+TAG_FIRST_CHARS = r'\w'
+TAG_FORBIDDEN_FIRST_CHARS = r'#'
+TAG_REGEX_BARE = r'%s[%s]+' % (TAG_FIRST_CHARS, TAG_CHARS)
TAG_REGEX = r'^%s$' % TAG_REGEX_BARE
TAG_SPLIT_REGEX = r'[ ,]+'
TAG_SEP = ',' # has to be valid TAG_SPLIT_REGEX char and MUST NOT be in const.TAG_CHARS
@@ -301,13 +305,6 @@ assert(
== set(RESPONSE_ACTIVITY_TYPE_MAP_FOR_TEMPLATES.keys())
)
-TYPE_RESPONSE = {
- 'QUESTION_ANSWERED' : _('answered question'),
- 'QUESTION_COMMENTED': _('commented question'),
- 'ANSWER_COMMENTED' : _('commented answer'),
- 'ANSWER_ACCEPTED' : _('accepted answer'),
-}
-
POST_STATUS = {
'closed': _('[closed]'),
'deleted': _('[deleted]'),
@@ -433,12 +430,12 @@ AVATAR_STATUS_CHOICE = (
SEARCH_ORDER_BY = (
('-added_at', _('date descendant')),
('added_at', _('date ascendant')),
- ('-last_activity_at', _('activity descendant')),
- ('last_activity_at', _('activity ascendant')),
- ('-answer_count', _('answers descendant')),
- ('answer_count', _('answers ascendant')),
- ('-points', _('votes descendant')),
- ('points', _('votes ascendant')),
+ ('-last_activity_at', _('most recently active')),
+ ('last_activity_at', _('least recently active')),
+ ('-answer_count', _('more responses')),
+ ('answer_count', _('fewer responses')),
+ ('-points', _('more votes')),
+ ('points', _('less votes')),
)
DEFAULT_QUESTION_WIDGET_STYLE = """
diff --git a/askbot/const/message_keys.py b/askbot/const/message_keys.py
index 291381cb..bb990d5e 100644
--- a/askbot/const/message_keys.py
+++ b/askbot/const/message_keys.py
@@ -4,12 +4,6 @@ that are used as variables
it is important that a dummy _() function is used here
this way message key will be pulled into django.po
and can still be used as a variable in python files.
-
-In addition, some messages are repeated too many times
-in the code, so we need to be able to retreive them
-by a key. Therefore we have a function here, called
-get_i18n_message(). Possibly all messages included in
-this file could be implemented this way.
'''
_ = lambda v:v
@@ -40,18 +34,14 @@ TAGS_ARE_REQUIRED_MESSAGE = _('tags are required')
TAG_WRONG_CHARS_MESSAGE = _(
'please use letters, numbers and characters "-+.#"'
)
-
-def get_i18n_message(key):
- messages = {
- 'BLOCKED_USERS_CANNOT_POST': _(
- 'Sorry, your account appears to be blocked and you cannot make new posts '
- 'until this issue is resolved. Please contact the forum administrator to '
- 'reach a resolution.'
- ),
- 'SUSPENDED_USERS_CANNOT_POST': _(
- 'Sorry, your account appears to be suspended and you cannot make new posts '
- 'until this issue is resolved. You can, however edit your existing posts. '
- 'Please contact the forum administrator to reach a resolution.'
- )
- }
- return messages[key]
+TAG_WRONG_FIRST_CHAR_MESSAGE = _(
+ '# is not a valid character at the beginning of tags, use only letters and numbers'
+)
+ACCOUNT_CANNOT_PERFORM_ACTION = _(
+ 'Sorry, you cannot %(perform_action)s because %(your_account_is)s'
+)
+MIN_REP_REQUIRED_TO_PERFORM_ACTION = _('>%(min_rep)s points required to %(perform_action)s')
+CANNOT_PERFORM_ACTION_UNTIL = _('Sorry, you will be able to %(perform_action)s after %(until)s')
+MODERATORS_OR_AUTHOR_CAN_PEFROM_ACTION = _(
+ 'Sorry, only moderators or the %(post_author)s %(perform_action)s'
+)
diff --git a/askbot/deps/django_authopenid/forms.py b/askbot/deps/django_authopenid/forms.py
index 97cc90ba..1f08b23c 100644
--- a/askbot/deps/django_authopenid/forms.py
+++ b/askbot/deps/django_authopenid/forms.py
@@ -30,6 +30,7 @@
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import logging
+import cgi
from django import forms
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
@@ -75,7 +76,7 @@ class LoginProviderField(forms.CharField):
if value in providers:
return value
else:
- error_message = 'unknown provider name %s' % value
+ error_message = 'unknown provider name %s' % cgi.escape(value)
logging.critical(error_message)
raise forms.ValidationError(error_message)
diff --git a/askbot/deps/django_authopenid/util.py b/askbot/deps/django_authopenid/util.py
index 06379e1d..deb9ad27 100644
--- a/askbot/deps/django_authopenid/util.py
+++ b/askbot/deps/django_authopenid/util.py
@@ -35,9 +35,9 @@ except:
import time, base64, hmac, hashlib, operator, logging
from models import Association, Nonce
-__all__ = ['OpenID', 'DjangoOpenIDStore', 'from_openid_response', 'clean_next']
+__all__ = ['OpenID', 'DjangoOpenIDStore', 'from_openid_response']
-ALLOWED_LOGIN_TYPES = ('password', 'oauth', 'openid-direct', 'openid-username', 'wordpress')
+ALLOWED_LOGIN_TYPES = ('password', 'oauth', 'oauth2', 'openid-direct', 'openid-username', 'wordpress')
class OpenID:
def __init__(self, openid_, issued, attrs=None, sreg_=None):
@@ -273,6 +273,15 @@ class LoginMethod(object):
self.oauth_authorize_url = self.get_required_attr('OAUTH_AUTHORIZE_URL', for_what)
self.oauth_get_user_id_function = self.get_required_attr('oauth_get_user_id_function', for_what)
+ if self.login_type == 'oauth2':
+ for_what = 'custom OAuth2 login'
+ self.auth_endpoint = self.get_required_attr('OAUTH_ENDPOINT', for_what)
+ self.token_endpoint = self.get_required_attr('OAUTH_TOKEN_ENDPOINT', for_what)
+ self.resource_endpoint = self.get_required_attr('OAUTH_RESOURCE_ENDPOINT', for_what)
+ self.oauth_get_user_id_function = self.get_required_attr('oauth_get_user_id_function', for_what)
+ self.response_parser = getattr(self.mod, 'response_parser', None)
+ self.token_transport = getattr(self.mod, 'token_transport', None)
+
if self.login_type.startswith('openid'):
self.openid_endpoint = self.get_required_attr('OPENID_ENDPOINT', 'custom OpenID login')
if self.login_type == 'openid-username':
@@ -294,7 +303,8 @@ class LoginMethod(object):
'change_password_prompt', 'consumer_key', 'consumer_secret',
'request_token_url', 'access_token_url', 'authorize_url',
'get_user_id_function', 'openid_endpoint', 'tooltip_text',
- 'check_password',
+ 'check_password', 'auth_endpoint', 'token_endpoint',
+ 'resource_endpoint', 'response_parser', 'token_transport'
)
#some parameters in the class have different names from those
#in the dictionary
@@ -388,6 +398,18 @@ def get_enabled_major_login_providers():
'password_changeable': True
}
+ if askbot_settings.SIGNIN_CUSTOM_OPENID_ENABLED:
+ context_dict = {'login_name': askbot_settings.SIGNIN_CUSTOM_OPENID_NAME}
+ data['custom_openid'] = {
+ 'name': 'custom_openid',
+ 'display_name': askbot_settings.SIGNIN_CUSTOM_OPENID_NAME,
+ 'type': askbot_settings.SIGNIN_CUSTOM_OPENID_MODE,
+ 'icon_media_path': askbot_settings.SIGNIN_CUSTOM_OPENID_LOGIN_BUTTON,
+ 'tooltip_text': _('Login with %(login_name)s') % context_dict,
+ 'openid_endpoint': askbot_settings.SIGNIN_CUSTOM_OPENID_ENDPOINT,
+ 'extra_token_name': _('%(login_name)s username') % context_dict
+ }
+
def get_facebook_user_id(client):
"""returns facebook user id given the access token"""
profile = client.request('me')
diff --git a/askbot/deps/django_authopenid/views.py b/askbot/deps/django_authopenid/views.py
index 58c33fea..04b5deca 100644
--- a/askbot/deps/django_authopenid/views.py
+++ b/askbot/deps/django_authopenid/views.py
@@ -30,6 +30,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import cgi
import datetime
from django.http import HttpResponseRedirect, Http404
from django.http import HttpResponse
@@ -212,6 +213,7 @@ def ask_openid(
try:
auth_request = consumer.begin(openid_url)
except DiscoveryFailure:
+ openid_url = cgi.escape(openid_url)
msg = _(u"OpenID %(openid_url)s is invalid" % {'openid_url':openid_url})
logging.debug(msg)
return on_failure(request, msg)
@@ -292,12 +294,12 @@ def complete_oauth2_signin(request):
client_id = getattr(
askbot_settings,
- provider_name.upper() + '_KEY'
+ provider_name.upper() + '_KEY',
)
client_secret = getattr(
askbot_settings,
- provider_name.upper() + '_SECRET'
+ provider_name.upper() + '_SECRET',
)
client = OAuth2Client(
@@ -305,12 +307,13 @@ def complete_oauth2_signin(request):
resource_endpoint=params['resource_endpoint'],
redirect_uri=site_url(reverse('user_complete_oauth2_signin')),
client_id=client_id,
- client_secret=client_secret
+ client_secret=client_secret,
+ token_transport=params.get('token_transport', None)
)
client.request_token(
code=request.GET['code'],
- parser=params['response_parser']
+ parser=params.get('response_parser', None)
)
#todo: possibly set additional parameters here
@@ -327,6 +330,11 @@ def complete_oauth2_signin(request):
request.session['email'] = ''#todo: pull from profile
request.session['username'] = ''#todo: pull from profile
+ if (provider_name == 'facebook'):
+ profile = client.request("me")
+ request.session['email'] = profile['email']
+ request.session['username'] = profile['username']
+
return finalize_generic_signin(
request = request,
user = user,
@@ -735,8 +743,8 @@ def show_signin_view(
'page_class': 'openid-signin',
'view_subtype': view_subtype, #add_openid|default
'page_title': page_title,
- 'question':question,
- 'answer':answer,
+ 'question': question,
+ 'answer': answer,
'login_form': login_form,
'use_password_login': util.use_password_login(),
'account_recovery_form': account_recovery_form,
@@ -1352,16 +1360,3 @@ def account_recover(request):
return show_signin_view(request, view_subtype = 'bad_key')
return HttpResponseRedirect(get_next_url(request))
-
-#internal server view used as return value by other views
-def validation_email_sent(request):
- """this function is called only if EMAIL_VALIDATION setting is
- set to True bolean value"""
- assert(askbot_settings.EMAIL_VALIDATION == True)
- logging.debug('')
- data = {
- 'email': request.user.email,
- 'change_email_url': reverse('user_changeemail'),
- 'action_type': 'validate'
- }
- return render(request, 'authopenid/changeemail.html', data)
diff --git a/askbot/deps/livesettings/views.py b/askbot/deps/livesettings/views.py
index 3beae8de..0c64d23d 100644
--- a/askbot/deps/livesettings/views.py
+++ b/askbot/deps/livesettings/views.py
@@ -62,7 +62,7 @@ def group_settings(request, group, template='livesettings/group_settings.html'):
return render_to_response(template, {
'all_super_groups': mgr.get_super_groups(),
'title': title,
- 'group' : settings,
+ 'settings_group' : settings,
'form': form,
'use_db' : use_db
}, context_instance=RequestContext(request))
diff --git a/askbot/doc/source/askbot/layout.html b/askbot/doc/source/askbot/layout.html
index f1c8b509..6fd6b0d1 100644
--- a/askbot/doc/source/askbot/layout.html
+++ b/askbot/doc/source/askbot/layout.html
@@ -10,10 +10,10 @@
<div class="ab-proj-header">
<a href="/">Home</a> |
<a href="/en/questions/" title="Ask Questions">Ask Questions</a> |
- <a href="/hire-us" alt='Hire Us'>Hire Us</a> |
+ <a href="https://askbot.com/hire-us/" alt='Hire Us'>Consulting Services</a> |
<a href="/doc/index.html" alt="Documentation">Documentation</a> |
- <a href="/contribute" alt='Contribute'>Contribute</a> |
- <a href="/feedback/" alt='contact'>Contact</a>
+ <a href="https://askbot.com/contribute" alt='Contribute'>Contribute</a> |
+ <a href="https://askbot.com/feedback/" alt='contact'>Contact</a>
</div>
{% endblock %}
{% block relbar2 %}
diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst
index 00accbe0..c450ac95 100644
--- a/askbot/doc/source/changelog.rst
+++ b/askbot/doc/source/changelog.rst
@@ -1,8 +1,19 @@
Changes in Askbot
=================
-Development version
--------------------
+Development master branch (only on github)
+------------------------------------------
+* Allowed configurable custom OpenID login button
+* Allowed custom list of feedback recipients (Keto)
+* Added option to show user's emails to the moderators
+* Added Read-Only mode for the site in the "access control" section.
+* Added `askbot_add_osqa_content` management command.
+* Management command to add data from other Askbot site.
+* Allowed simple overrides of livesettings with `ASKBOT_...` prefixed
+ variables in the `settings.py` file.
+
+0.7.49 (Sep 19, 2013)
+---------------------
* Support for Solr search backend (Adolfo)
* Allowed read-only access user groups (Adolfo)
* Added simple read-only API (Adolfo)
diff --git a/askbot/doc/source/contributors.rst b/askbot/doc/source/contributors.rst
index 5e97b608..0dfb942b 100644
--- a/askbot/doc/source/contributors.rst
+++ b/askbot/doc/source/contributors.rst
@@ -49,6 +49,11 @@ Programming, bug fixes and documentation
* `Kevin Porterfield <http://www.shotgunsoftware.com>_`
* `Robert Martin <https://github.com/bobbydavid>_`
* `Director <http://codeflow.co.kr>`_
+* `Stéphane Klein <http://stephane-klein.info>`_
+* `Andrew Chen <https://github.com/yongjhih>`_
+* `Benjamin Abel <https://github.com/BenjaminABEL>`_
+* `Pami Ketolainen <https://github.com/keto>`_
+* `Hamdi <https://github.com/Hamdy>`_
Translations
------------
@@ -66,6 +71,8 @@ please let us know at support@askbot.com.
* Pekka Järvinen - Finnish
* Adi Robian - Romanian
* `Stefano Mancini <https://github.com/xponrails>`_, Dario Ghilardi, Federico Poloni, `Luca Ferroni <http://www.linkedin.com/in/lucaferroni>`_ - Italian
-* `Jordi Bofill <https://github.com/jbofill>`_ - Catalan
+* Cong It, Nguyen Long, ppranhh - Vietnamese
+* `Jordi Bofill <https://github.gom/jbofill>`_ - Catalan
* VaÅ¡ek ChalupníÄek - Chech
* Dario Kolak - Croatian
+.
diff --git a/askbot/doc/source/index.rst b/askbot/doc/source/index.rst
index 680ba0aa..d6703775 100644
--- a/askbot/doc/source/index.rst
+++ b/askbot/doc/source/index.rst
@@ -28,7 +28,9 @@ at the forum_ or by email at admin@askbot.org
Appendix E: Askbot as reusable Django application <askbot-as-reusable-django-application>
Appendix F: Customizing skin in askbot <customizing-skin-in-askbot>
Appendix G: Intranet setup <intranet-setup>
- Appendix H: Haystack with Solr and Apache Tomcat <solr>
+ Appendix H: Language support in Askbot <localization>
+ Appendix I: Configuration of text search <text-search>
+ Appendix J: Migration from MySQL to PostgreSQL <mysql-to-postgres>
Footnotes <footnotes>
Contributors <contributors>
Changelog <changelog>
diff --git a/askbot/doc/source/live-settings.rst b/askbot/doc/source/live-settings.rst
index 12546e6c..bc0d3d72 100644
--- a/askbot/doc/source/live-settings.rst
+++ b/askbot/doc/source/live-settings.rst
@@ -24,7 +24,22 @@ Entering live settings in settings.py file
==========================================
You might want to bypass live settings and enter them directly
-in the ``settings.py`` file in the ``LIVESETTINGS_OPTIONS`` dictionary.
+in the ``settings.py`` file.
+
+Currently there are two ways to do this:
+
+1. Simply add variable with the same name as defined in `askbot/conf` files,
+ but prefixed with `ASKBOT_` and the corresponding value.
+ For example, add `ASKBOT_RSS_ENABLED = False` to disable the rss.
+ In `askbot/conf` this value is defined simply as `RSS_ENABLED`.
+
+2. Put settings into the ``LIVESETTINGS_OPTIONS`` dictionary,
+ this way you can assign livesettings values to specific site by ID,
+ which may or may not be useful for the multi-portal (multi-site) askbot setup.
+
+The first method above overrides the second.
+
+Here is a more detailed description on how to use the `LIVESETTINGS_OPTIONS` method:
Having live settings overridden from the ``settings.py`` file may
somewhat speed up your site
diff --git a/askbot/doc/source/localization.rst b/askbot/doc/source/localization.rst
new file mode 100644
index 00000000..fbf51da6
--- /dev/null
+++ b/askbot/doc/source/localization.rst
@@ -0,0 +1,81 @@
+.. _localization:
+======================================
+Configuring language support in Askbot
+======================================
+
+There are several things to consider when localizing askbot:
+
+* :ref:`setting the site language <default-lang>`
+* :ref:`translation and display of the urls <translate-urls>`
+* :ref:`translation of the strings in the user interface <strings>`
+* :ref:`enabling the multilingual setup <multilingual>`
+* :ref:`configuring the language-specific text search <text-search>`
+
+.. _default-lang:
+
+Setting the site language
+=========================
+
+Specify the language code with the value of `LANGUAGE_CODE` parameter
+in the `settings.py` file::
+
+ LANGUAGE_CODE='es'
+
+.. note::
+ In the :ref:`multi-lingual configuration <multilingual>`
+ this language will be the default and the complete list of
+ language codes and their verbose names
+ is specified with the `LANGUAGES` parameter.
+
+.. _translate-urls:
+
+Translation of the URLs
+=======================
+
+There are also `settings.py` options to translate the urls:
+`ASKBOT_TRANSLATE_URL` and `ALLOW_UNICODE_SLUGS`.
+
+When the `ASKBOT_TRANSLATE_URL` is `True`, most urls will be translated,
+otherwise urls will be in English.
+When the `ALLOW_UNICODE_SLUGS` is `True` the question titles and user names
+will be presented as Unicode, e.g. with the Cyrillic, Chinese
+or Arabic characters, otherwise they will be transliterated into ASCII.
+
+If you are translating URLs (in the transifex you will probably
+find them as strings containing forward slashes) -
+take the following, in order to prevent broken links:
+
+* translation of multiple urls cannot be the same
+ (e.g. /question/ and /questions/ must have different translations)
+* if the same url is present in more than one translation file
+ those translation must be exactly the same
+
+.. _strings:
+
+Translation of strings in Askbot
+================================
+
+Translation of Askbot strings is performed at the `Transifex service <transifex>`_.
+Please `register there <transifex>`_ and work on the localization that interests you.
+We periodically update the source language strings on Transifex and pull
+the translations back into the project. Thanks!
+
+If you intend to translate urls - please :ref:`look here <translate-urls>`.
+
+Please *do not* translate via github (if you know what it means),
+as it's better to have just one source of strings.
+
+The remaining part will will most likely interest developers,
+therefore here we tell what is specific to Askbot and
+refer the developer to the documentation of tools
+used in Askbot.
+
+Firstly - Askbot uses `Jinja2 <http://jinja.pocoo.org/docs/>`_ templates,
+not the Django templates and an Jinja2 adapter module for Django, called
+`Coffin <https://github.com/coffin/coffin/>`_. Please look at how translation
+tags are added to the templates processed by the `coffin` module.
+
+Secondly - instead of the django `makemessages` command - use `jinja2_makemessages`.
+
+Finally - to pull strings from the transifex use the `tx` program from
+`transifex-client pypi package <https://pypi.python.org/pypi/transifex-client>`_.
diff --git a/askbot/doc/source/management-commands.rst b/askbot/doc/source/management-commands.rst
index a56aa47a..1f5c3fa1 100644
--- a/askbot/doc/source/management-commands.rst
+++ b/askbot/doc/source/management-commands.rst
@@ -46,9 +46,6 @@ The bulk of the management commands fall into this group and will probably be th
| `merge_users <from_id> | Merges user accounts and all related data from one user |
| <to_id>` | to another, the "from user" account is deleted. |
+---------------------------------+-------------------------------------------------------------+
-| `dump_forum [--dump-name | Save forum contents into a file. `--dump-name` parameter is |
-| some_name]` | optional |
-+---------------------------------+-------------------------------------------------------------+
| `get_tag_stats [-u|-t] [-e]` | Print tag subscription statistics, per tag (option -t) |
| | or per user (option -u), if option -e is given, empty |
| | records will be shown too (longer versions of the options |
@@ -56,16 +53,6 @@ The bulk of the management commands fall into this group and will probably be th
| | --per-user-tag-subscription-counts for -u, and --print-empty|
| | for -e). |
+---------------------------------+-------------------------------------------------------------+
-| `load_forum <file_name>` | Load forum data from a file saved by the `dump_forum` |
-| | command |
-+---------------------------------+-------------------------------------------------------------+
-| `load_stackexchange <file.zip>` | Load SackExchange dump into Askbot. It is best to run this |
-| | command on empty database. Also - before running, make sure |
-| | that `askbot.importers.stackexchange` is in the list of |
-| | installed apps within your settings.py file (it might also |
-| | be necessary to run `syncdb` command to initiate the |
-| | SE importer tables). |
-+---------------------------------+-------------------------------------------------------------+
| `rename_tags --from <from_tags> | Rename, merge or split tags. User ID is the id of the user |
| --to <to_tags> --user-id | who will be assigned as the performer of the retag action. |
| <user_id>` | If more than is in the `--from` or the `--to` parameters |
@@ -101,6 +88,32 @@ The bulk of the management commands fall into this group and will probably be th
| | foreign key to that object is still present. |
+---------------------------------+-------------------------------------------------------------+
+.. _data-import-commands:
+
+Data import commands
+====================
+
+These commands import or add data to the Askbot forum.
+
++---------------------------------+-------------------------------------------------------------+
+| command | purpose |
++=================================+=============================================================+
+| `load_stackexchange <file.zip>` | Load SackExchange dump into Askbot. It is best to run this |
+| | command on empty database. Also - before running, make sure |
+| | that `askbot.importers.stackexchange` is in the list of |
+| | installed apps within your settings.py file (it might also |
+| | be necessary to run `syncdb` command to initiate the |
+| | SE importer tables). |
++---------------------------------+-------------------------------------------------------------+
+| `askbot_add_xml_content | Add xml Askbot data dumped with the Django command |
+| <file.xml>` | `dumpdata` |
++---------------------------------+-------------------------------------------------------------+
+| `askbot_add_osqa_content | Add xml OSQA data dumped with the Django command |
+| <file.xml>` | `export_osqa` |
++---------------------------------+-------------------------------------------------------------+
+| `askbot_import_jive <file.xml> | Import xml Jive data |
++---------------------------------+-------------------------------------------------------------+
+
.. _email-related-commands:
Email-related commands
diff --git a/askbot/doc/source/multilingual.rst b/askbot/doc/source/multilingual.rst
new file mode 100644
index 00000000..75f93f0a
--- /dev/null
+++ b/askbot/doc/source/multilingual.rst
@@ -0,0 +1,46 @@
+.. _multilingual:
+====================================
+Setting up multilingual Askbot sites
+====================================
+
+Askbot can support multiple languages on a single site, in which case
+urls are modified by a prefix made of a language code, e.g.
+base url /questions/ becomes /de/questions/ for the German localization.
+
+.. note::
+ If you want to learn about configuration of individual languages
+ please look :ref:`here <localization>`
+
+In order to enable the multilingual setup add the following to the
+`settings.py` file::
+
+ ASKBOT_MULTILINGUAL=True
+
+Also, activate the django's locale middleware by adding to the
+`MIDDLEWARE_CLASSES` the following entry::
+
+ 'django.middleware.locale.LocaleMiddleware',
+
+There is a standard Django setting `LANGUAGES`, which enables specific languages.
+By default this setting contains very many languages.
+You will likely want to narrow in the `settings.py` file
+the choice of the available languages::
+
+ #it's important to use ugettext_lazy or ugettext_noop
+ #in the settings.py file
+ from django.utils.translation import ugettext_lazy as _
+ LANGUAGES = (
+ ('de', _('German')),
+ ('en', _('English'))
+ )
+
+More on the usage of this setting can be read in the
+`Django documentation <https://docs.djangoproject.com/en/dev/ref/settings/#languages>`_.
+
+The default language should be specified with the setting `LANGUAGE_CODE`.
+Users will be automatically redirected to the corresponding default language
+page from the non-prefixed urls.
+
+There are a number of `settings.py` options that control the various
+aspects of the site localization - the behaviour of the software depending on the
+currently active language.. Please read more about the :ref:`Localization of Askbot <localization>`.
diff --git a/askbot/doc/source/mysql-to-postgres.rst b/askbot/doc/source/mysql-to-postgres.rst
new file mode 100644
index 00000000..c9c0e477
--- /dev/null
+++ b/askbot/doc/source/mysql-to-postgres.rst
@@ -0,0 +1,114 @@
+.. _mysql-to-postgres:
+
+===========================================================
+Migrating data from MySQL to Postgresql
+===========================================================
+
+In this document we explain how to migrate from MySQL to Postgresql with different approaches.
+
+Askbot is optimized for Postgresql as search functionality works better with this database engine.
+
+.. note::
+ As a general advice, to reduce the database size - run the **cleanup** management command before starting the migration.
+
+
+Simple Migration of small database
+==================================
+
+If your database is small with few users and questions you can follow this steps:
+
+With MySQL as your database engine in your settings.py file run the following command::
+
+ python manage.py dumpdata > data.json
+
+After that change your database engine to Postgresql in settings.py and do::
+
+ python manage.py syncdb --migrate --noinput #create the database structure
+ python manage.py loaddata data.json
+
+
+.. note::
+ This won't work with large datasets because django will load all your
+ data into memory and you might run out of memory if the site data is too large.
+
+ This process can produce warnings that can be ignored.
+
+
+Data migration with py-mysql2pgsql
+==================================
+
+If the database is large this tool will come handy, to install it run::
+
+ pip install py-mysql2pgsql
+
+Create a configuration file called config.yml with the following contents::
+
+ mysql:
+ hostname: localhost
+ port: 3306
+ username: your_user
+ password: your_password
+ database: your_database
+
+ destination:
+ file:
+ postgres:
+ hostname: localhost
+ port: 5432
+ username: your_user
+ password: your_password
+ database: your_database
+
+Then run::
+
+ py-mysql2pgsql -v -f config.yml
+
+The script will start migrating the data and might take a while, depending on the database size.
+
+After the process is finished there are a couple of things left to do.
+
+Enable Postgresql full text search
+----------------------------------
+
+Askbot relies on special postgresql features for better search, in this case the py-mysql2pgsql tool will not
+add these features, so it requires to be added manually.
+
+To fix it run the command::
+
+ python manage.py init_postgresql_full_text_search
+
+This may also take some time, depending on the database size.
+Test this by running a search query on the askbot site.
+
+..
+ If you have an issue with the above command, it is possible to run the search setup sql script manually:
+ 1. Download `thread_and_post_models_10032013.plsql <https://raw.github.com/ASKBOT/askbot-devel/master/askbot/search/postgresql/thread_and_post_models_10032013.plsql>`_
+ 2. Download `user_profile_search_08312012.plsql <https://raw.github.com/ASKBOT/askbot-devel/master/askbot/search/postgresql/user_profile_search_08312012.plsql>`_
+ 3. Apply the scripts to your postgres database::
+ psql your_database < thread_and_post_models_10032013.plsql
+ psql your_database < user_profile_search_08312012.plsql
+
+
+Fixing data types
+-----------------
+
+The py-mysql2pgsql translates datatype a bit different than Django ORM do, to keep the same
+datatypes do the following:
+
+1. Create a new postgresql database and run sync and migrate commands the following way::
+
+ python manage.py syncdb --migrate --noinput --no-initial-data
+
+2. Dump the converted database data with binary format::
+
+ pg_dump --format=c -a database_name > dump_name
+
+3. Restore it into your current Django database::
+
+ pg_restore -a --disable-triggers -d django_database dump_name
+
+
+Links
+=====
+
+* `py-mysql2pgsql <https://github.com/philipsoutham/py-mysql2pgsql>`_
diff --git a/askbot/doc/source/solr.rst b/askbot/doc/source/solr.rst
index 9db6ba2f..8a1de0c2 100644
--- a/askbot/doc/source/solr.rst
+++ b/askbot/doc/source/solr.rst
@@ -8,22 +8,26 @@ Installing Apache Solr with Apache Tomcat 7 in Ubuntu 12.04
This document describes the process of instalation of Apache Solr search engine in Ubuntu Server 12.04
for askbot use. To follow this steps you must have already askbot installed and running.
-Getting the requirements
-========================
+Installation of the required packages
+=====================================
-We need the following packages installed::
+Install packages `tomcat7` and `tomcat7-admin`::
sudo apt-get install tomcat7 tomcat7-admin
-We need to download Apache Solr from the `official site <http://lucene.apache.org/solr/downloads.html>`_::
+Download Apache Solr from the `official site <http://lucene.apache.org/solr/downloads.html>`_::
wget http://www.bizdirusa.com/mirrors/apache/lucene/solr/3.6.2/apache-solr-3.6.2.tgz
+Install `django-haystack` module in your Python environment::
+
+ pip install django-haystack
+
Setting up Tomcat
=================
-After installing tomcat there are some configuration required to make it work. First we are going to add
-Tomcat users. Edit /etc/tomcat7/tomcat-users.xml and add the following::
+After installing Tomcat, add users to the Tomcat server.
+Edit `/etc/tomcat7/tomcat-users.xml` and add the following::
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
@@ -31,15 +35,17 @@ Tomcat users. Edit /etc/tomcat7/tomcat-users.xml and add the following::
<role rolename="admin"/>
<role rolename="admin-gui"/>
<role rolename="manager-gui"/>
- <user username="tomcat" password="tomcat" roles="manager,admin,manager-gui,admin-gui"/>
+ <user username="tomcat" password="tomcat"
+ roles="manager,admin,manager-gui,admin-gui"/>
</tomcat-users>
-This will allow you to connect to the web management interface. After doing it restart the service:
+Then restart the service::
service tomcat7 restart
-To make see if it works go to: http://youripaddress:8080/manager it will ask for your tomcat user password
-described in the tomcat-users.xml
+Now you should be able to connect to the web management interface
+via http://youripaddress:8080/manager
+and entering there user name and password.
Installing Solr under Tomcat
============================
@@ -48,28 +54,30 @@ Extract the solr tar archive from the previous download::
tar -xzf apache-solr-3.6.2.tgz
-Copy the example/ directory from the source to /opt/solr/. Open the file /opt/solr/example/solr/conf/solrconfig.xml
+Copy the `example/` directory from the source to `/opt/solr/`.
+Open the file `/opt/solr/example/solr/conf/solrconfig.xml`
and Modify the dataDir parameter as::
<dataDir>${solr.data.dir:/opt/solr/example/solr/data}</dataDir>
-Copy the .war file in dist directory to /opt/solr::
+Copy the `.war` file in dist directory to `/opt/solr`::
cp dist/apache-solr-3.6.2.war /opt/solr
-Create solr.xml inside of /etc/tomcat/Catalina/localhost/ with the following contents::
+Create `solr.xml` inside of `/etc/tomcat/Catalina/localhost/` with the following contents::
<?xml version="1.0" encoding="utf-8"?>
<Context docBase="/opt/solr/apache-solr-3.6.2.war" debug="0" crossContext="true">
- <Environment name="solr/home" type="java.lang.String" value="/opt/solr/example/solr" override="true"/>
+ <Environment name="solr/home" type="java.lang.String"
+ value="/opt/solr/example/solr" override="true"/>
</Context>
-Restart tomcat server::
+Restart the tomcat server::
service tomcat7 restart
-By now you should be able to see the "solr" application in the tomcat manager and also access it in /solr/admin.
-
+Now you should be able to access the "solr" application
+in the Tomcat manager at `/solr/admin`.
Configuring Askbot with Solr
============================
@@ -103,14 +111,18 @@ The output should be something like::
Indexing 101 posts.
Indexing 101 threads.
-You must be good to go after this, just restart the askbot application and test the search with haystack and solr
+Now all should be ready,
+just restart the askbot application
+and test the search with haystack and solr.
+.. _solr-multilingual:
Multilingual Setup
==================
.. note::
- This is experimental feature, currently xml generation works for: English, Spanish, Chinese, Japanese, Korean and French.
+ This is experimental feature, currently xml generation works for:
+ English, Spanish, Chinese, Japanese, Korean and French.
Add the following to settings.py::
@@ -129,7 +141,6 @@ Configure the HAYSTACK_CONNECTIONS settings with the following format for each l
},
}
-
Generate xml files according to language::
python manage.py askbot_build_solr_schema -l <language_code> > /opt/solr/example/solr/conf/schema-<language_code>.xml
@@ -141,12 +152,13 @@ For each language that you want to support you will need to add a solr core like
http://127.0.0.1:8080/solr/admin/cores?action=CREATE&name=core-<language_code>&instanceDir=.&config=solrconfig.xml&schema=schema-<language_code>.xml&dataDir=data
-For more information on how to handle Solr cores visit `the oficial Solr documetation wiki. <http://wiki.apache.org/solr/CoreAdmin>`_
+For more information on how to handle Solr cores visit the
+`Solr documetation <http://wiki.apache.org/solr/CoreAdmin>`_.
Build the index according to language
-------------------------------------
-For every language supported you'll need to rebuild the index the following way::
+For every active language rebuild the index::
python manage.py askbot_rebuild_index -l <language_code>
@@ -159,24 +171,32 @@ There are several ways to keep the index fresh in askbot with haystack.
Cronjob
-------
-Create a cronjob that executes *askbot_update_index* command for each language installed (in case of multilingual setup).
+Create a cronjob that executes *askbot_update_index* command
+for each of the activated languages.
Real Time Signal
----------------
-The real time signal method updates the index synchronously after each object it's saved or deleted, to enable it add this to settings.py::
+The *real time* signal method updates the index synchronously
+after each object it's saved or deleted,
+to enable it add this to settings.py::
HAYSTACK_SIGNAL_PROCESSOR = 'askbot.search.haystack.signals.AskbotRealtimeSignalProcessor'
-this can delay the requests time of your page, if you have a high traffic site this is not recommended.
+Use of synchronous index updates may slow down your site
+which may not be acceptable for the high traffic sites.
+
+Updating the Index asyncronously with Celery
+--------------------------------------------
-Updating the Index with Celery
-------------------------------
+The *asynchronous signal* method updates the index by adding delayed job to the queue
+after each object is saved or deleted.
-The real time signal method updates the index asynchronously after each object it's saved or deleted using Celery as queue to enable it add this to settings.py::
+To make this work,
+`django-celery <http://celery.readthedocs.org/en/latest/django/first-steps-with-django.html>`_
+must be installed, enabled and configured and the Haystack signal processor configured
+in the `settings.py` file::
HAYSTACK_SIGNAL_PROCESSOR = 'askbot.search.haystack.signals.AskbotCelerySignalProcessor'
#modify CELERY_ALWAYS_EAGER to:
CELERY_ALWAYS_EAGER = False
-
-You will need to enable Celery to make this work.
diff --git a/askbot/doc/source/text-search.rst b/askbot/doc/source/text-search.rst
new file mode 100644
index 00000000..b18e3f33
--- /dev/null
+++ b/askbot/doc/source/text-search.rst
@@ -0,0 +1,48 @@
+.. _text-search:
+======================================
+Configuring full text search in Askbot
+======================================
+
+Currently there are two supported language-aware mechanisms for full text search:
+
+* :ref:`postgresql full text search <postgresql-text-search>`
+* :ref:`Solr search engine <solr-text-search>`
+
+MySQL supports text search only for English and only for the MyISAM storage engine.
+MyISAM engine lacks support of the database transactions,
+therefore it is strongly recommended to use Postgresql.
+
+.. _postgresql-text-search:
+
+Postgresql full text search
+===========================
+
+Postgresql supports full text search in the following languages:
+
+Danish, Dutch, English, Finnish, French, German, Hungarian,
+Italian, Japanese (requires postgresql package `textsearch_ja`), Norwegian,
+Portugese, Romanian, Russian, Spanish, Swedish, Turkish.
+
+To enable this option - just use the postgresql database and
+add in the `settings.py` file
+the corresponding entry in the
+`LANGUAGES setting <https://docs.djangoproject.com/en/dev/ref/settings/#languages>`_.
+
+.. note::
+ Japanese language search in Postgresql requires installation
+ of a "contrib" package called `textsearch_ja`
+
+.. _solr-text-search:
+
+Solr full text search
+=====================
+
+Apache Solr search supports more languages and Askbot supports Solr via the
+module called Haystack.
+
+:ref:`Here <solr>` are detailed instructions on how to enable Solr on
+Ubuntu system version 12.04, which may be helpful for users of other
+distributions of Linux.
+
+In addition to the basic set up of Solr, it will be necessary to configure
+:ref:`multilingual search <solr-multilingual>` under solr.
diff --git a/askbot/feed.py b/askbot/feed.py
index 03e7c7e1..b8f7efb7 100644
--- a/askbot/feed.py
+++ b/askbot/feed.py
@@ -32,7 +32,7 @@ class RssIndividualQuestionFeed(Feed):
def title(self):
return askbot_settings.APP_TITLE + _(' - ') + \
- _('Individual question feed')
+ _('Individual %(question)s feed') % {'question': askbot_settings.WORDS_QUESTION_SINGULAR}
def feed_copyright(self):
return askbot_settings.APP_COPYRIGHT
@@ -85,13 +85,12 @@ class RssIndividualQuestionFeed(Feed):
def item_title(self, item):
"""returns the title for the item
"""
- title = item
if item.post_type == "question":
- self.title = item
+ title = item.thread.title
elif item.post_type == "answer":
- title = "Answer by %s for %s " % (item.author, self.title)
+ title = u'Answer by %s for %s ' % (item.author, item.thread._question_post().summary)
elif item.post_type == "comment":
- title = "Comment by %s for %s" % (item.author, self.title)
+ title = u'Comment by %s for %s' % (item.author, item.parent.summary)
return title
def item_description(self, item):
@@ -106,7 +105,7 @@ class RssLastestQuestionsFeed(Feed):
def title(self):
return askbot_settings.APP_TITLE + _(' - ') + \
- _('Individual question feed')
+ _('Latest %(question)s feed') % {'question': askbot_settings.WORDS_QUESTION_SINGULAR}
def feed_copyright(self):
return askbot_settings.APP_COPYRIGHT
@@ -143,6 +142,9 @@ class RssLastestQuestionsFeed(Feed):
"""
return site_url(item.get_absolute_url(no_slug = True))
+ def item_title(self, item):
+ return item.thread.title
+
def item_description(self, item):
"""returns the description for the item
"""
@@ -177,11 +179,3 @@ class RssLastestQuestionsFeed(Feed):
def get_feed(self, obj, request):
self.request = request
return super(RssLastestQuestionsFeed, self).get_feed(obj, request)
-
-def main():
- """main function for use as a script
- """
- pass
-
-if __name__ == '__main__':
- main()
diff --git a/askbot/forms.py b/askbot/forms.py
index 0c4e15c5..471559bb 100644
--- a/askbot/forms.py
+++ b/askbot/forms.py
@@ -9,6 +9,7 @@ from django.conf import settings as django_settings
from django.core.exceptions import PermissionDenied
from django.forms.util import ErrorList
from django.utils.html import strip_tags
+from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy, string_concat
from django.utils.text import get_text_list
@@ -245,9 +246,7 @@ class TitleField(forms.CharField):
)
self.max_length = 255
self.label = _('title')
- self.help_text = _(
- 'Please enter your question'
- )
+ self.help_text = askbot_settings.WORDS_PLEASE_ENTER_YOUR_QUESTION
self.initial = ''
def clean(self, value):
@@ -263,20 +262,21 @@ class TitleField(forms.CharField):
) % askbot_settings.MIN_TITLE_LENGTH
raise forms.ValidationError(msg)
encoded_value = value.encode('utf-8')
+ question_term = askbot_settings.WORDS_QUESTION_SINGULAR
if len(value) == len(encoded_value):
if len(value) > self.max_length:
raise forms.ValidationError(
_(
- 'The question is too long, maximum allowed size is '
- '%d characters'
- ) % self.max_length
+ 'The %(question)s is too long, maximum allowed size is '
+ '%(length)d characters'
+ ) % {'question': question_term, 'length': self.max_length}
)
elif len(encoded_value) > self.max_length:
raise forms.ValidationError(
_(
- 'The question is too long, maximum allowed size is '
- '%d bytes'
- ) % self.max_length
+ 'The %(question)s is too long, maximum allowed size is '
+ '%(length)d bytes'
+ ) % {'question': question_term, 'length': self.max_length}
)
return value.strip() # TODO: test me
@@ -286,9 +286,6 @@ class EditorField(forms.CharField):
"""EditorField is subclassed by the
:class:`QuestionEditorField` and :class:`AnswerEditorField`
"""
- length_error_template_singular = 'post content must be > %d character',
- length_error_template_plural = 'post content must be > %d characters',
- min_length = 10 # sentinel default value
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
@@ -309,16 +306,18 @@ class EditorField(forms.CharField):
self.label = _('content')
self.help_text = u''
self.initial = ''
+ self.min_length = 10
+ self.post_term_name = _('post')
def clean(self, value):
if value is None:
value = ''
if len(value) < self.min_length:
msg = ungettext_lazy(
- self.length_error_template_singular,
- self.length_error_template_plural,
+ '%(post)s content must be > %(count)d character',
+ '%(post)s content must be > %(count)d characters',
self.min_length
- ) % self.min_length
+ ) % {'post': unicode(self.post_term_name), 'count': self.min_length}
raise forms.ValidationError(msg)
if self.user.is_anonymous():
@@ -342,11 +341,8 @@ class QuestionEditorField(EditorField):
super(QuestionEditorField, self).__init__(
user=user, *args, **kwargs
)
- self.length_error_template_singular = \
- 'question body must be > %d character'
- self.length_error_template_plural = \
- 'question body must be > %d characters'
self.min_length = askbot_settings.MIN_QUESTION_BODY_LENGTH
+ self.post_term_name = askbot_settings.WORDS_QUESTION_SINGULAR
class AnswerEditorField(EditorField):
@@ -354,8 +350,7 @@ class AnswerEditorField(EditorField):
def __init__(self, *args, **kwargs):
super(AnswerEditorField, self).__init__(*args, **kwargs)
- self.length_error_template_singular = 'answer must be > %d character'
- self.length_error_template_plural = 'answer must be > %d characters'
+ self.post_term_name = askbot_settings.WORDS_ANSWER_SINGULAR
self.min_length = askbot_settings.MIN_ANSWER_BODY_LENGTH
@@ -376,9 +371,14 @@ def clean_tag(tag_name):
#todo - this needs to come from settings
tagname_re = re.compile(const.TAG_REGEX, re.UNICODE)
if not tagname_re.search(tag_name):
- raise forms.ValidationError(
- _(message_keys.TAG_WRONG_CHARS_MESSAGE)
- )
+ if tag_name[0] in const.TAG_FORBIDDEN_FIRST_CHARS:
+ raise forms.ValidationError(
+ _(message_keys.TAG_WRONG_FIRST_CHAR_MESSAGE)
+ )
+ else:
+ raise forms.ValidationError(
+ _(message_keys.TAG_WRONG_CHARS_MESSAGE)
+ )
if askbot_settings.FORCE_LOWERCASE_TAGS:
#a simpler way to handle tags - just lowercase thew all
@@ -475,11 +475,6 @@ class WikiField(forms.BooleanField):
'community wiki (karma is not awarded & '
'many others can edit wiki post)'
)
- self.help_text = _(
- 'if you choose community wiki option, the question '
- 'and answer do not generate points and name of '
- 'author will not be shown'
- )
def clean(self, value):
return value and askbot_settings.WIKI_ON
@@ -730,7 +725,6 @@ class FeedbackForm(forms.Form):
email = forms.EmailField(label=_('Email:'), required=False)
message = forms.CharField(
label=_('Your message:'),
- max_length=800,
widget=forms.Textarea(attrs={'cols': 60})
)
no_email = forms.BooleanField(
@@ -751,6 +745,11 @@ class FeedbackForm(forms.Form):
private_key=askbot_settings.RECAPTCHA_SECRET,
public_key=askbot_settings.RECAPTCHA_KEY
)
+ def clean_message(self):
+ message = self.cleaned_data.get('message', '').strip()
+ if not message:
+ raise forms.ValidationError(_('Message is required'))
+ return message
def clean(self):
super(FeedbackForm, self).clean()
@@ -908,18 +907,9 @@ class AskForm(PostAsSomeoneForm, PostPrivatelyForm):
in the cleaned data, and will evaluate to False if the
settings forbids anonymous asking
"""
- title = TitleField()
tags = TagNamesField()
wiki = WikiField()
group_id = forms.IntegerField(required = False, widget = forms.HiddenInput)
- ask_anonymously = forms.BooleanField(
- label=_('ask anonymously'),
- help_text=_(
- 'Check if you do not want to reveal your name '
- 'when asking this question'
- ),
- required=False,
- )
openid = forms.CharField(
required=False, max_length=255,
widget=forms.TextInput(attrs={'size': 40, 'class': 'openid-input'})
@@ -929,7 +919,14 @@ class AskForm(PostAsSomeoneForm, PostPrivatelyForm):
user = kwargs.pop('user', None)
super(AskForm, self).__init__(*args, **kwargs)
#it's important that this field is set up dynamically
+ self.fields['title'] = TitleField()
self.fields['text'] = QuestionEditorField(user=user)
+
+ self.fields['ask_anonymously'] = forms.BooleanField(
+ label=_('post anonymously'),
+ required=False,
+ )
+
#hide ask_anonymously field
if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False):
self.fields['language'] = LanguageField()
@@ -954,19 +951,15 @@ ASK_BY_EMAIL_SUBJECT_HELP = _(
class AskWidgetForm(forms.Form, FormWithHideableFields):
'''Simple form with just the title to ask a question'''
- title = TitleField()
ask_anonymously = forms.BooleanField(
label=_('ask anonymously'),
- help_text=_(
- 'Check if you do not want to reveal your name '
- 'when asking this question'
- ),
required=False,
)
def __init__(self, include_text=True, *args, **kwargs):
user = kwargs.pop('user', None)
super(AskWidgetForm, self).__init__(*args, **kwargs)
+ self.fields['title'] = TitleField()
#hide ask_anonymously field
if not askbot_settings.ALLOW_ASK_ANONYMOUSLY:
self.hide_field('ask_anonymously')
@@ -1206,16 +1199,10 @@ class RevisionForm(forms.Form):
self.fields['revision'].initial = latest_revision.revision
class EditQuestionForm(PostAsSomeoneForm, PostPrivatelyForm):
- title = TitleField()
tags = TagNamesField()
summary = SummaryField()
wiki = WikiField()
reveal_identity = forms.BooleanField(
- help_text=_(
- 'You have asked this question anonymously, '
- 'if you decide to reveal your identity, please check '
- 'this box.'
- ),
label=_('reveal identity'),
required=False,
)
@@ -1230,6 +1217,7 @@ class EditQuestionForm(PostAsSomeoneForm, PostPrivatelyForm):
super(EditQuestionForm, self).__init__(*args, **kwargs)
#it is important to add this field dynamically
self.fields['text'] = QuestionEditorField(user=self.user)
+ self.fields['title'] = TitleField()
self.fields['title'].initial = revision.title
self.fields['text'].initial = revision.text
self.fields['tags'].initial = revision.tagnames
@@ -1520,22 +1508,15 @@ class EditUserEmailFeedsForm(forms.Form):
'mentions_and_comments': 'i',
}
- asked_by_me = EmailFeedSettingField(
- label=_('Asked by me')
- )
- answered_by_me = EmailFeedSettingField(
- label=_('Answered by me')
- )
- individually_selected = EmailFeedSettingField(
- label=_('Individually selected')
- )
- all_questions = EmailFeedSettingField(
- label=_('Entire forum (tag filtered)'),
- )
-
- mentions_and_comments = EmailFeedSettingField(
- label=_('Comments and posts mentioning me'),
- )
+ def __init__(self, *args, **kwargs):
+ super(EditUserEmailFeedsForm, self).__init__(*args, **kwargs)
+ self.fields = SortedDict((
+ ('asked_by_me', EmailFeedSettingField(label=askbot_settings.WORDS_ASKED_BY_ME)),
+ ('answered_by_me', EmailFeedSettingField(label=askbot_settings.WORDS_ANSWERED_BY_ME)),
+ ('individually_selected', EmailFeedSettingField(label=_('Individually selected'))),
+ ('all_questions', EmailFeedSettingField(label=_('Entire forum (tag filtered)'))),
+ ('mentions_and_comments', EmailFeedSettingField(label=_('Comments and posts mentioning me')))
+ ))
def set_initial_values(self, user=None):
from askbot import models
diff --git a/askbot/locale/ar/LC_MESSAGES/django.mo b/askbot/locale/ar/LC_MESSAGES/django.mo
index b53e71b5..22f09343 100644
--- a/askbot/locale/ar/LC_MESSAGES/django.mo
+++ b/askbot/locale/ar/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/ar/LC_MESSAGES/django.po b/askbot/locale/ar/LC_MESSAGES/django.po
index 039bc5b2..f09eab69 100644
--- a/askbot/locale/ar/LC_MESSAGES/django.po
+++ b/askbot/locale/ar/LC_MESSAGES/django.po
@@ -6,6 +6,7 @@
# Ahmad Khayyat <akhayyat@gmail.com>, 2013
# Ahmad Khayyat <akhayyat@gmail.com>, 2012
# AminosAmigos <aminosamigos@gmail.com>, 2012
+# evgeny <evgeny.fadeev@gmail.com>, 2009
# Fahad Al-Fattani <fahadaaf@gmail.com>, 2012
# Husam M. ALFarra <husamfarra@gmail.com>, 2013
# Khalid A Sam <kifcaliph@hotmail.com>, 2012
@@ -17,7 +18,7 @@ msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:06-0500\n"
-"PO-Revision-Date: 2013-08-02 10:49+0000\n"
+"PO-Revision-Date: 2013-09-11 05:36+0000\n"
"Last-Translator: mustafaalbazy <mustafa@albazy.com>\n"
"Language-Team: Arabic (http://www.transifex.com/projects/p/askbot/language/ar/)\n"
"MIME-Version: 1.0\n"
@@ -74,7 +75,7 @@ msgstr[5] ""
#: forms.py:220
msgid "minor edit (don't send alerts)"
-msgstr ""
+msgstr "تعديل بسيط (لا ترسل تنبيهات)"
#: forms.py:247 templates/widgets/markdown_help.html:20
#: templates/widgets/markdown_help.html:24
@@ -83,7 +84,7 @@ msgstr "العنوان"
#: forms.py:249 templates/embed/ask_by_widget.html:170
msgid "Please enter your question"
-msgstr ""
+msgstr "عنوان السؤال"
#: forms.py:260
#, python-format
@@ -99,12 +100,12 @@ msgstr[5] ""
#: forms.py:270
#, python-format
msgid "The question is too long, maximum allowed size is %d characters"
-msgstr ""
+msgstr "هذا السؤال كبير جداً، الحد الأقصى المسموح به هو %d حرÙ"
#: forms.py:277
#, python-format
msgid "The question is too long, maximum allowed size is %d bytes"
-msgstr ""
+msgstr "هذا السؤال كبير جداً، الحد الأقصى المسموح به هو %d بايت"
#: forms.py:309
msgid "content"
@@ -125,7 +126,7 @@ msgstr[5] "يجب أن تتكون كل بطاقة من %(max_chars)d حرÙاً
msgid ""
"We ran out of space for recording the tags. Please shorten or delete some of"
" them."
-msgstr ""
+msgstr "لقد تجاوزت المساحة المسموح بها للموضوع، Ùضلاً قصرهم او احذ٠بعضهم."
#: forms.py:410 forms.py:1006 models/widgets.py:27
#: templates/widgets/edit_post.html:32 templates/widgets/meta_nav.html:6
@@ -171,7 +172,7 @@ msgstr "ويكي مجتمع (لا يتم منح كارما ويمكن للآخر
msgid ""
"if you choose community wiki option, the question and answer do not generate"
" points and name of author will not be shown"
-msgstr ""
+msgstr "إذا أخترت أن يكون السؤال ويكي، السؤال والأجوبة لن يحصلا على نقاط كما ان أسم الكاتب لن يظهر، حيث يعتبر ان الويكي مساهمة جماعية."
#: forms.py:496
msgid "update summary:"
@@ -252,7 +253,7 @@ msgstr "نص الرسالة"
#: forms.py:727
msgid "Your name (optional):"
-msgstr "اسمك (إختياري):"
+msgstr "أسمك (إختياري):"
#: forms.py:728
msgid "Email:"
@@ -264,11 +265,11 @@ msgstr "رسالتك"
#: forms.py:735
msgid "I don't want to give my email or receive a response:"
-msgstr "لا أريد إعطاء البريد الإلكتروني و لا أريد إستلام رد:"
+msgstr "لا أريد أعطاء بريدي او أستقبال رد:"
#: forms.py:758
msgid "Please mark \"I dont want to give my mail\" field."
-msgstr "يرجى وضع علامة \"أنا لا أريد أن إعطاء بريدي\" للحقل."
+msgstr "Ùضلاً حدد حقل \"لا أريد أعطاء بريدي\""
#: forms.py:791
msgid "keep private within your groups"
@@ -276,7 +277,7 @@ msgstr ""
#: forms.py:830
msgid "User name:"
-msgstr ""
+msgstr "أسم المستخدم"
#: forms.py:832
msgid "Enter name to post on behalf of someone else. Can create new accounts."
@@ -284,11 +285,11 @@ msgstr ""
#: forms.py:839
msgid "Email address:"
-msgstr ""
+msgstr "عنوان البريد"
#: forms.py:889
msgid "User name is required with the email"
-msgstr ""
+msgstr "أسمك مطلوب مع البريد"
#: forms.py:894
msgid "Email is required if user name is added"
@@ -414,14 +415,14 @@ msgstr "العنوان"
#: forms.py:1676 templates/groups.html:32
msgid "Description"
-msgstr ""
+msgstr "الوصÙ"
#: forms.py:1695 templates/tags.html:3 templates/tags/header.html:9
#: templates/tags/list_bulk_tag_subscription.html:12
#: templates/widgets/edit_post.html:26 templates/widgets/related_tags.html:3
#: templates/widgets/tag_category_selector.html:2
msgid "Tags"
-msgstr "علامات"
+msgstr "المواضيع"
#: tasks.py:98
msgid "An edit for my answer"
@@ -434,11 +435,11 @@ msgstr ""
#: tasks.py:119
#, python-format
msgid "Your post at %(site_name)s is now published"
-msgstr ""
+msgstr "تم نشرك مشاركتك ÙÙŠ %(site_name)s"
#: urls.py:44
msgid "questions"
-msgstr "أسئلة"
+msgstr "questions"
#: urls.py:56
msgid "question/"
@@ -454,7 +455,7 @@ msgstr "users/"
#: urls.py:71
msgid "by-group/"
-msgstr ""
+msgstr "by-group/"
#: urls.py:78 urls.py:159 urls.py:226 urls.py:520
msgid "edit/"
@@ -466,11 +467,11 @@ msgstr "subscriptions/"
#: urls.py:94
msgid "select_languages/"
-msgstr ""
+msgstr "select_languages/"
#: urls.py:105
msgid "groups/"
-msgstr ""
+msgstr "groups/"
#: urls.py:110
msgid "users/update_has_custom_avatar/"
@@ -498,7 +499,7 @@ msgstr "privacy/"
#: urls.py:157
msgid "help/"
-msgstr "مساعدة/"
+msgstr "help/"
#: urls.py:159 urls.py:164
msgid "answers/"
@@ -535,23 +536,23 @@ msgstr "answer/"
#: urls.py:314
msgid "tags/subscriptions/"
-msgstr ""
+msgstr "topcis/subscriptions/"
#: urls.py:319
msgid "tags/subscriptions/delete/"
-msgstr ""
+msgstr "topics/subscriptions/delete/"
#: urls.py:324
msgid "tags/subscriptions/create/"
-msgstr ""
+msgstr "topics/subscriptions/create/"
#: urls.py:329
msgid "tags/subscriptions/edit/"
-msgstr ""
+msgstr "topics/subscriptions/edit/"
#: urls.py:334
msgid "suggested-tags/"
-msgstr ""
+msgstr "suggested-topics/"
#: urls.py:459
msgid "messages/"
@@ -564,19 +565,19 @@ msgstr "markread/"
#: urls.py:490 urls.py:495 urls.py:500 urls.py:505 urls.py:510 urls.py:515
#: urls.py:520 urls.py:525 urls.py:530
msgid "widgets/"
-msgstr "ودجة/"
+msgstr "widgets/"
#: urls.py:510 deps/django_authopenid/urls.py:20
msgid "complete/"
-msgstr ""
+msgstr "complete/"
#: urls.py:515
msgid "create/"
-msgstr ""
+msgstr "create/"
#: urls.py:525
msgid "delete/"
-msgstr ""
+msgstr "delete/"
#: urls.py:560
msgid "upload/"
@@ -589,39 +590,39 @@ msgstr "account/"
#: conf/access_control.py:8
msgid "Access control settings"
-msgstr ""
+msgstr "إعدادات الوصول"
#: conf/access_control.py:17
msgid "Allow only registered user to access the forum"
-msgstr "السماح Ùقط للمستخدمين المسجلين بالدخول الى المنتدى"
+msgstr "السماح Ùقط للأعضاء المسجلين لدخول هذا المنتدى"
#: conf/access_control.py:22
msgid "nothing - not required"
-msgstr ""
+msgstr "لا شيء - غير مطلوب"
#: conf/access_control.py:23
msgid "access to content"
-msgstr ""
+msgstr "الوصول للمحتوى"
#: conf/access_control.py:34
msgid "Require valid email for"
-msgstr ""
+msgstr "البريد مطلوب من اجل"
#: conf/access_control.py:44
msgid "Allowed email addresses"
-msgstr ""
+msgstr "عناوين البريد المسموح بها"
#: conf/access_control.py:45
msgid "Please use space to separate the entries"
-msgstr ""
+msgstr "أستخدم المساÙØ© للÙصل بينهم"
#: conf/access_control.py:54
msgid "Allowed email domain names"
-msgstr ""
+msgstr "عنوان نطاقات البريد المسموح بها"
#: conf/access_control.py:55
msgid "Please use space to separate the entries, do not use the @ symbol!"
-msgstr ""
+msgstr "يرجى إستخدام المساÙات Ù„Ùصل المدخلات، لا تستخدم رمز @"
#: conf/badges.py:13
msgid "Badge settings"
@@ -629,15 +630,15 @@ msgstr "إعدادات الشارات"
#: conf/badges.py:23
msgid "Disciplined: minimum upvotes for deleted post"
-msgstr ""
+msgstr "Disciplined: minimum upvotes for deleted post"
#: conf/badges.py:32
msgid "Peer Pressure: minimum downvotes for deleted post"
-msgstr ""
+msgstr "Peer Pressure: minimum downvotes for deleted post"
#: conf/badges.py:41
msgid "Teacher: minimum upvotes for the answer"
-msgstr ""
+msgstr "Teacher: minimum upvotes for the answer"
#: conf/badges.py:50
msgid "Nice Answer: minimum upvotes for the answer"
@@ -665,43 +666,43 @@ msgstr "سؤال عظيم: الحد الأدني من الأصوات للسؤاÙ
#: conf/badges.py:104
msgid "Popular Question: minimum views"
-msgstr ""
+msgstr "Popular Question: minimum views"
#: conf/badges.py:113
msgid "Notable Question: minimum views"
-msgstr ""
+msgstr "Notable Question: minimum views"
#: conf/badges.py:122
msgid "Famous Question: minimum views"
-msgstr ""
+msgstr "Famous Question: minimum views"
#: conf/badges.py:131
msgid "Self-Learner: minimum answer upvotes"
-msgstr ""
+msgstr "Self-Learner: minimum answer upvotes"
#: conf/badges.py:140
msgid "Civic Duty: minimum votes"
-msgstr ""
+msgstr "Civic Duty: minimum votes"
#: conf/badges.py:149
msgid "Enlightened Duty: minimum upvotes"
-msgstr ""
+msgstr "Enlightened Duty: minimum upvotes"
#: conf/badges.py:158
msgid "Guru: minimum upvotes"
-msgstr ""
+msgstr "Guru: minimum upvotes"
#: conf/badges.py:167
msgid "Necromancer: minimum upvotes"
-msgstr ""
+msgstr "Necromancer: minimum upvotes"
#: conf/badges.py:176
msgid "Necromancer: minimum delay in days"
-msgstr ""
+msgstr "Necromancer: minimum delay in days"
#: conf/badges.py:185
msgid "Associate Editor: minimum number of edits"
-msgstr ""
+msgstr "Associate Editor: minimum number of edits"
#: conf/badges.py:194
msgid "Favorite Question: minimum stars"
@@ -709,19 +710,19 @@ msgstr "سؤال Ù…Ùضل: الحد الأدني من النجوم"
#: conf/badges.py:203
msgid "Stellar Question: minimum stars"
-msgstr ""
+msgstr "Stellar Question: minimum stars"
#: conf/badges.py:212
msgid "Commentator: minimum comments"
-msgstr ""
+msgstr "Commentator: minimum comments"
#: conf/badges.py:221
msgid "Taxonomist: minimum tag use count"
-msgstr ""
+msgstr "Taxonomist: minimum tag use count"
#: conf/badges.py:230
msgid "Enthusiast: minimum days"
-msgstr ""
+msgstr "Enthusiast: minimum days"
#: conf/email.py:15
msgid "Email and email alert settings"
@@ -735,15 +736,15 @@ msgstr "تصدير سطر العنوان للرسائل الإلكترونية"
msgid ""
"This setting takes default from the django settingEMAIL_SUBJECT_PREFIX. A "
"value entered here will overridethe default."
-msgstr ""
+msgstr "This setting takes default from the django settingEMAIL_SUBJECT_PREFIX. A value entered here will overridethe default."
#: conf/email.py:44
msgid "Site administrator email address"
-msgstr ""
+msgstr "عنوان بريد مدير الموقع"
#: conf/email.py:53
msgid "Enable email alerts"
-msgstr "تÙعيل تنبهات البريد"
+msgstr "تÙعيل تنبيهات البريد"
#: conf/email.py:62
msgid "Maximum number of news entries in an email alert"
@@ -751,54 +752,54 @@ msgstr "العدد الأقصى من الأخبار لكل رسالة تنبيه
#: conf/email.py:72
msgid "Default notification frequency all questions"
-msgstr ""
+msgstr "Default notification frequency all questions"
#: conf/email.py:74
msgid "Option to define frequency of emailed updates for: all questions."
-msgstr ""
+msgstr "Option to define frequency of emailed updates for: all questions."
#: conf/email.py:86
msgid "Default notification frequency questions asked by the user"
-msgstr ""
+msgstr "Default notification frequency questions asked by the user"
#: conf/email.py:88
msgid ""
"Option to define frequency of emailed updates for: Question asked by the "
"user."
-msgstr ""
+msgstr "Option to define frequency of emailed updates for: Question asked by the user."
#: conf/email.py:100
msgid "Default notification frequency questions answered by the user"
-msgstr ""
+msgstr "Default notification frequency questions answered by the user"
#: conf/email.py:102
msgid ""
"Option to define frequency of emailed updates for: Question answered by the "
"user."
-msgstr ""
+msgstr "Option to define frequency of emailed updates for: Question answered by the user."
#: conf/email.py:114
msgid ""
"Default notification frequency questions individually"
" selected by the user"
-msgstr ""
+msgstr "Default notification frequency questions individually selected by the user"
#: conf/email.py:117
msgid ""
"Option to define frequency of emailed updates for: Question individually "
"selected by the user."
-msgstr ""
+msgstr "Option to define frequency of emailed updates for: Question individually selected by the user."
#: conf/email.py:129
msgid ""
"Default notification frequency for mentions and "
"comments"
-msgstr ""
+msgstr "Default notification frequency for mentions and comments"
#: conf/email.py:132
msgid ""
"Option to define frequency of emailed updates for: Mentions and comments."
-msgstr ""
+msgstr "Option to define frequency of emailed updates for: Mentions and comments."
#: conf/email.py:143
msgid "Send periodic reminders about unanswered questions"
@@ -809,7 +810,7 @@ msgid ""
"NOTE: in order to use this feature, it is necessary to run the management "
"command \"send_unanswered_question_reminders\" (for example, via a cron job "
"- with an appropriate frequency) "
-msgstr ""
+msgstr "NOTE: in order to use this feature, it is necessary to run the management command \"send_unanswered_question_reminders\" (for example, via a cron job - with an appropriate frequency) "
#: conf/email.py:158
msgid "Days before starting to send reminders about unanswered questions"
@@ -827,28 +828,28 @@ msgstr "العدد الأقصى من الرسائل التذكيرية للأسØ
#: conf/email.py:192
msgid "Send periodic reminders to accept the best answer"
-msgstr "ارسل تنبيه دوري للمواÙقة على Ø£Ùضل إجابة"
+msgstr "Send periodic reminders to accept the best answer"
#: conf/email.py:194
msgid ""
"NOTE: in order to use this feature, it is necessary to run the management "
"command \"send_accept_answer_reminders\" (for example, via a cron job - with"
" an appropriate frequency) "
-msgstr ""
+msgstr "NOTE: in order to use this feature, it is necessary to run the management command \"send_accept_answer_reminders\" (for example, via a cron job - with an appropriate frequency) "
#: conf/email.py:207
msgid "Days before starting to send reminders to accept an answer"
-msgstr ""
+msgstr "الأيام قبل البدء بإرسال تنبيهات لقبول Ø£Ùضل إجابة للسؤال"
#: conf/email.py:218
msgid ""
"How often to send accept answer reminders (in days between the reminders "
"sent)."
-msgstr ""
+msgstr "How often to send accept answer reminders (in days between the reminders sent)."
#: conf/email.py:230
msgid "Max. number of reminders to send to accept the best answer"
-msgstr ""
+msgstr "الحد الأقصى للتنبيهات على قبول Ø£Ùضل إجابة للسؤال"
#: conf/email.py:242
msgid "Require email verification before allowing to post"
@@ -857,29 +858,29 @@ msgstr "اشتراط التحقق من البريد الإلكتروني قبل
#: conf/email.py:243
msgid ""
"Active email verification is done by sending a verification key in email"
-msgstr ""
+msgstr "Active email verification is done by sending a verification key in email"
#: conf/email.py:252
msgid "Fake email for anonymous user"
-msgstr ""
+msgstr "البريد المزي٠للأعضاء المجهولون"
#: conf/email.py:253
msgid "Use this setting to control gravatar for email-less user"
-msgstr ""
+msgstr "Use this setting to control gravatar for email-less user"
#: conf/email.py:262
msgid "Allow posting questions by email"
-msgstr ""
+msgstr "السماح بنشر الأسئلة عبر البريد"
#: conf/email.py:264
msgid ""
"Before enabling this setting - please fill out IMAP settings in the "
"settings.py file"
-msgstr ""
+msgstr "Before enabling this setting - please fill out IMAP settings in the settings.py file"
#: conf/email.py:275
msgid "Replace space in emailed tags with dash"
-msgstr ""
+msgstr "تبديل المساÙØ© بالبريد للمواضيع بعلامة ( _ ) "
#: conf/email.py:277
msgid ""
@@ -889,29 +890,29 @@ msgstr "يطبق هذا الإعداد على الوسوم المذكورة ÙÙŠ
#: conf/email.py:288
msgid "Enable posting answers and comments by email"
-msgstr ""
+msgstr "تÙعيل نشر الأسئلة والتعليقات عبر البريد"
#: conf/email.py:291
msgid "To enable this feature make sure lamson is running"
-msgstr ""
+msgstr "لتÙعيل هذه الخاصية تأكد من أن lamson Ùعال ويعمل."
#: conf/email.py:302
msgid "Emailed post: when to notify author about publishing"
-msgstr ""
+msgstr "Emailed post: when to notify author about publishing"
#: conf/email.py:327
msgid "Reply by email hostname"
-msgstr ""
+msgstr "Reply by email hostname"
#: conf/email.py:338
msgid ""
"Email replies having fewer words than this number will be posted as comments"
" instead of answers"
-msgstr ""
+msgstr "Email replies having fewer words than this number will be posted as comments instead of answers"
#: conf/external_keys.py:11
msgid "Keys for external services"
-msgstr ""
+msgstr "Ù…Ùاتيح الخدمات الخارجية"
#: conf/external_keys.py:19
msgid "Google site verification key"
@@ -922,22 +923,22 @@ msgstr "Ù…Ùتاح Google للتحقق من الموقع"
msgid ""
"This key helps google index your site please obtain is at <a "
"href=\"%(url)s?hl=%(lang)s\">google webmasters tools site</a>"
-msgstr ""
+msgstr "This key helps google index your site please obtain is at <a href=\"%(url)s?hl=%(lang)s\">google webmasters tools site</a>"
#: conf/external_keys.py:36
msgid "Google Analytics key"
-msgstr "Ù…Ùتاح جوجل Analytics"
+msgstr "Google Analytics key"
#: conf/external_keys.py:38
#, python-format
msgid ""
"Obtain is at <a href=\"%(url)s\">Google Analytics</a> site, if you wish to "
"use Google Analytics to monitor your site"
-msgstr ""
+msgstr "Obtain is at <a href=\"%(url)s\">Google Analytics</a> site, if you wish to use Google Analytics to monitor your site"
#: conf/external_keys.py:51
msgid "Enable recaptcha (keys below are required)"
-msgstr ""
+msgstr "تÙعيل recaptcha (المÙاتيح ÙÙŠ الأسÙÙ„ مطلوبة)"
#: conf/external_keys.py:62
msgid "Recaptcha public key"
@@ -953,11 +954,11 @@ msgid ""
"Recaptcha is a tool that helps distinguish real people from annoying spam "
"robots. Please get this and a public key at the <a "
"href=\"%(url)s\">%(url)s</a>"
-msgstr ""
+msgstr "Recaptcha is a tool that helps distinguish real people from annoying spam robots. Please get this and a public key at the <a href=\"%(url)s\">%(url)s</a>"
#: conf/external_keys.py:84
msgid "Facebook public API key"
-msgstr "Ù…Ùتاح Facebook العام"
+msgstr "Facebook public API key"
#: conf/external_keys.py:86
#, python-format
@@ -965,135 +966,135 @@ msgid ""
"Facebook API key and Facebook secret allow to use Facebook Connect login "
"method at your site. Please obtain these keys at <a "
"href=\"%(url)s\">facebook create app</a> site"
-msgstr ""
+msgstr "Facebook API key and Facebook secret allow to use Facebook Connect login method at your site. Please obtain these keys at <a href=\"%(url)s\">facebook create app</a> site"
#: conf/external_keys.py:99
msgid "Facebook secret key"
-msgstr ""
+msgstr "Facebook secret key"
#: conf/external_keys.py:107
msgid "Twitter consumer key"
-msgstr ""
+msgstr "Twitter consumer key"
#: conf/external_keys.py:109
#, python-format
msgid ""
"Please register your forum at <a href=\"%(url)s\">twitter applications "
"site</a>"
-msgstr ""
+msgstr "Please register your forum at <a href=\"%(url)s\">twitter applications site</a>"
#: conf/external_keys.py:120
msgid "Twitter consumer secret"
-msgstr ""
+msgstr "Twitter consumer secret"
#: conf/external_keys.py:128
msgid "LinkedIn consumer key"
-msgstr ""
+msgstr "LinkedIn consumer key"
#: conf/external_keys.py:130
#, python-format
msgid ""
"Please register your forum at <a href=\"%(url)s\">LinkedIn developer "
"site</a>"
-msgstr ""
+msgstr "Please register your forum at <a href=\"%(url)s\">LinkedIn developer site</a>"
#: conf/external_keys.py:141
msgid "LinkedIn consumer secret"
-msgstr ""
+msgstr "LinkedIn consumer secret"
#: conf/external_keys.py:149
msgid "ident.ca consumer key"
-msgstr ""
+msgstr "ident.ca consumer key"
#: conf/external_keys.py:151
#, python-format
msgid ""
"Please register your forum at <a href=\"%(url)s\">Identi.ca applications "
"site</a>"
-msgstr ""
+msgstr "Please register your forum at <a href=\"%(url)s\">Identi.ca applications site</a>"
#: conf/external_keys.py:162
msgid "ident.ca consumer secret"
-msgstr ""
+msgstr "ident.ca consumer secret"
#: conf/flatpages.py:11
msgid "Messages and pages - about, privacy policy, etc."
-msgstr ""
+msgstr "الرسائل والصÙحات - عن الموقع، الخصوصية...الخ."
#: conf/flatpages.py:19
msgid "Text of the Q&A forum About page (html format)"
-msgstr ""
+msgstr "Text of the Q&A forum About page (html format)"
#: conf/flatpages.py:22
msgid ""
"Save, then <a href=\"http://validator.w3.org/\">use HTML validator</a> on "
"the \"about\" page to check your input."
-msgstr ""
+msgstr "Save, then <a href=\"http://validator.w3.org/\">use HTML validator</a> on the \"about\" page to check your input."
#: conf/flatpages.py:32
msgid "Text of the Q&A forum FAQ page (html format)"
-msgstr ""
+msgstr "Text of the Q&A forum FAQ page (html format)"
#: conf/flatpages.py:35
msgid ""
"Save, then <a href=\"http://validator.w3.org/\">use HTML validator</a> on "
"the \"faq\" page to check your input."
-msgstr ""
+msgstr "Save, then <a href=\"http://validator.w3.org/\">use HTML validator</a> on the \"faq\" page to check your input."
#: conf/flatpages.py:45
msgid "Instructions on how to ask questions"
-msgstr ""
+msgstr "Instructions on how to ask questions"
#: conf/flatpages.py:48
msgid ""
"HTML is allowed. Save, then <a href=\"http://validator.w3.org/\">use HTML "
"validator</a> on the \"ask\" page to check your input."
-msgstr ""
+msgstr "HTML is allowed. Save, then <a href=\"http://validator.w3.org/\">use HTML validator</a> on the \"ask\" page to check your input."
#: conf/flatpages.py:59
msgid "Text of the Q&A forum Privacy Policy (html format)"
-msgstr ""
+msgstr "Text of the Q&A forum Privacy Policy (html format)"
#: conf/flatpages.py:62
msgid ""
"Save, then <a href=\"http://validator.w3.org/\">use HTML validator</a> on "
"the \"privacy\" page to check your input."
-msgstr ""
+msgstr "Save, then <a href=\"http://validator.w3.org/\">use HTML validator</a> on the \"privacy\" page to check your input."
#: conf/flatpages.py:75
msgid "Do not edit this field manually!!!"
-msgstr ""
+msgstr "Do not edit this field manually!!!"
#: conf/forum_data_rules.py:12
msgid "Data entry and display rules"
-msgstr ""
+msgstr "Data entry and display rules"
#: conf/forum_data_rules.py:27
msgid "Editor for the posts"
-msgstr ""
+msgstr "Editor for the posts"
#: conf/forum_data_rules.py:42
msgid "Editor for the comments"
-msgstr ""
+msgstr "Editor for the comments"
#: conf/forum_data_rules.py:51
msgid "Enable big Ask button"
-msgstr ""
+msgstr "Enable big Ask button"
#: conf/forum_data_rules.py:53
msgid ""
"Disabling this button will reduce number of new questions. If this button is"
" disabled, the ask button in the search menu will still be available."
-msgstr ""
+msgstr "Disabling this button will reduce number of new questions. If this button is disabled, the ask button in the search menu will still be available."
#: conf/forum_data_rules.py:66
msgid "Enable embedding videos. "
-msgstr ""
+msgstr "Enable embedding videos. "
#: conf/forum_data_rules.py:68
#, python-format
msgid "<em>Note: please read <a href=\"%(url)s\">read this</a> first.</em>"
-msgstr ""
+msgstr "<em>Note: please read <a href=\"%(url)s\">read this</a> first.</em>"
#: conf/forum_data_rules.py:78
msgid "Check to enable community wiki feature"
@@ -1107,11 +1108,11 @@ msgstr "السماح بالسؤال دون تحديد الهوية"
msgid ""
"Users do not accrue reputation for anonymous questions and their identity is"
" not revealed until they change their mind"
-msgstr ""
+msgstr "Users do not accrue reputation for anonymous questions and their identity is not revealed until they change their mind"
#: conf/forum_data_rules.py:101
msgid "Allow posting before logging in"
-msgstr ""
+msgstr "Allow posting before logging in"
#: conf/forum_data_rules.py:103
msgid ""
@@ -1119,39 +1120,39 @@ msgid ""
"logging in. Enabling this may require adjustments in the user login system "
"to check for pending posts every time the user logs in. The builtin Askbot "
"login system supports this feature."
-msgstr ""
+msgstr "Check if you want to allow users start posting questions or answers before logging in. Enabling this may require adjustments in the user login system to check for pending posts every time the user logs in. The builtin Askbot login system supports this feature."
#: conf/forum_data_rules.py:118
msgid "Auto-follow questions by the Author"
-msgstr ""
+msgstr "Auto-follow questions by the Author"
#: conf/forum_data_rules.py:123
msgid "Fully open by default"
-msgstr ""
+msgstr "Fully open by default"
#: conf/forum_data_rules.py:124
msgid "Folded by default"
-msgstr ""
+msgstr "Folded by default"
#: conf/forum_data_rules.py:133
msgid "Question details/body editor should be"
-msgstr ""
+msgstr "Question details/body editor should be"
#: conf/forum_data_rules.py:135
msgid ""
"To use folded mode, please first set minimum question body length to 0. Also"
" - please make tags optional."
-msgstr ""
+msgstr "To use folded mode, please first set minimum question body length to 0. Also - please make tags optional."
#: conf/forum_data_rules.py:147
msgid "Allow swapping answer with question"
-msgstr "انشر إجابتك"
+msgstr "Allow swapping answer with question"
#: conf/forum_data_rules.py:149
msgid ""
"This setting will help import data from other forums such as zendesk, when "
"automatic data import fails to detect the original question correctly."
-msgstr ""
+msgstr "This setting will help import data from other forums such as zendesk, when automatic data import fails to detect the original question correctly."
#: conf/forum_data_rules.py:161
msgid "Maximum length of tag (number of characters)"
@@ -1159,35 +1160,35 @@ msgstr "الحد الأقصى لطول الوسم (عدد الحروÙ)"
#: conf/forum_data_rules.py:170
msgid "Minimum length of title (number of characters)"
-msgstr ""
+msgstr "Minimum length of title (number of characters)"
#: conf/forum_data_rules.py:180
msgid "Minimum length of question body (number of characters)"
-msgstr ""
+msgstr "Minimum length of question body (number of characters)"
#: conf/forum_data_rules.py:191
msgid "Minimum length of answer body (number of characters)"
-msgstr ""
+msgstr "Minimum length of answer body (number of characters)"
#: conf/forum_data_rules.py:202
msgid "Minimum length of comment (number of characters)"
-msgstr ""
+msgstr "Minimum length of comment (number of characters)"
#: conf/forum_data_rules.py:213
msgid "Limit one answer per question per user"
-msgstr ""
+msgstr "Limit one answer per question per user"
#: conf/forum_data_rules.py:223
msgid "Enable accepting best answer"
-msgstr ""
+msgstr "Enable accepting best answer"
#: conf/forum_data_rules.py:231
msgid "Are tags required?"
-msgstr ""
+msgstr "Are tags required?"
#: conf/forum_data_rules.py:237
msgid "category tree"
-msgstr ""
+msgstr "category tree"
#: conf/forum_data_rules.py:238
msgid "user input"
@@ -1195,7 +1196,7 @@ msgstr ""
#: conf/forum_data_rules.py:245
msgid "Source of tags"
-msgstr ""
+msgstr "Source of tags"
#: conf/forum_data_rules.py:256
msgid "Mandatory tags"
@@ -1205,7 +1206,7 @@ msgstr "وسوم إلزامية"
msgid ""
"At least one of these tags will be required for any new or newly edited "
"question. A mandatory tag may be wildcard, if the wildcard tags are active."
-msgstr ""
+msgstr "At least one of these tags will be required for any new or newly edited question. A mandatory tag may be wildcard, if the wildcard tags are active."
#: conf/forum_data_rules.py:271
msgid "Force lowercase the tags"
@@ -1216,7 +1217,7 @@ msgid ""
"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"
-msgstr ""
+msgstr "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"
#: conf/forum_data_rules.py:287
msgid "Format of tag list"
@@ -1230,43 +1231,43 @@ msgstr "اختر طريقة عرض الوسوم، إما كقائمة بسيطة
#: conf/forum_data_rules.py:301
msgid "Use wildcard tags"
-msgstr "البطاقات"
+msgstr "Use wildcard tags"
#: conf/forum_data_rules.py:303
msgid ""
"Wildcard tags can be used to follow or ignore many tags at once, a valid "
"wildcard tag has a single wildcard at the very end"
-msgstr ""
+msgstr "Wildcard tags can be used to follow or ignore many tags at once, a valid wildcard tag has a single wildcard at the very end"
#: conf/forum_data_rules.py:315
msgid "Use separate set for subscribed tags"
-msgstr ""
+msgstr "Use separate set for subscribed tags"
#: conf/forum_data_rules.py:317
msgid ""
"If enabled, users will have a third set of tag selections - \"subscribed\" "
"(by email) in additon to \"interesting\" and \"ignored\""
-msgstr ""
+msgstr "If enabled, users will have a third set of tag selections - \"subscribed\" (by email) in additon to \"interesting\" and \"ignored\""
#: conf/forum_data_rules.py:325
msgid "Always, for all users"
-msgstr ""
+msgstr "Always, for all users"
#: conf/forum_data_rules.py:326
msgid "Never, for all users"
-msgstr ""
+msgstr "Never, for all users"
#: conf/forum_data_rules.py:327
msgid "Let users decide"
-msgstr ""
+msgstr "Let users decide"
#: conf/forum_data_rules.py:335
msgid "Publicly show user tag selections"
-msgstr ""
+msgstr "Publicly show user tag selections"
#: conf/forum_data_rules.py:344
msgid "Enable separate tag search box on main page"
-msgstr ""
+msgstr "Enable separate tag search box on main page"
#: conf/forum_data_rules.py:354
msgid "Default max number of comments to display under posts"
@@ -1301,26 +1302,26 @@ msgstr "لحÙظ التعليق، اضغظ على زر <Enter>"
msgid ""
"This may be useful when only one-line comments are desired. Will not work "
"with TinyMCE editor."
-msgstr ""
+msgstr "This may be useful when only one-line comments are desired. Will not work with TinyMCE editor."
#: conf/forum_data_rules.py:411
msgid "Minimum length of search term for Ajax search"
-msgstr ""
+msgstr "Minimum length of search term for Ajax search"
#: conf/forum_data_rules.py:412
msgid "Must match the corresponding database backend setting"
-msgstr ""
+msgstr "Must match the corresponding database backend setting"
#: conf/forum_data_rules.py:421
msgid "Do not make text query sticky in search"
-msgstr ""
+msgstr "Do not make text query sticky in search"
#: conf/forum_data_rules.py:423
msgid ""
"Check to disable the \"sticky\" behavior of the search query. This may be "
"useful if you want to move the search bar away from the default position or "
"do not like the default sticky behavior of the text search query."
-msgstr ""
+msgstr "Check to disable the \"sticky\" behavior of the search query. This may be useful if you want to move the search bar away from the default position or do not like the default sticky behavior of the text search query."
#: conf/forum_data_rules.py:436
msgid "Maximum number of tags per question"
@@ -1332,121 +1333,121 @@ msgstr "العدد الاÙتراضي للأسئلة المعروضة"
#: conf/forum_data_rules.py:458
msgid "What should \"unanswered question\" mean?"
-msgstr ""
+msgstr "What should \"unanswered question\" mean?"
#: conf/group_settings.py:9
msgid "Group settings"
-msgstr ""
+msgstr "Group settings"
#: conf/group_settings.py:18
msgid "Enable user groups"
-msgstr ""
+msgstr "Enable user groups"
#: conf/group_settings.py:41
msgid "everyone"
-msgstr ""
+msgstr "عامة"
#: conf/group_settings.py:42
msgid "Global user group name"
-msgstr ""
+msgstr "Global user group name"
#: conf/group_settings.py:43
msgid "All users belong to this group automatically"
-msgstr ""
+msgstr "All users belong to this group automatically"
#: conf/group_settings.py:53
msgid "Enable group email adddresses"
-msgstr ""
+msgstr "Enable group email adddresses"
#: conf/group_settings.py:55
msgid "If selected, users can post to groups by email \"group-name@domain.com\""
-msgstr ""
+msgstr "If selected, users can post to groups by email \"group-name@domain.com\""
#: conf/karma_and_badges_visibility.py:12
msgid "Karma & Badge visibility"
-msgstr ""
+msgstr "Karma & Badge visibility"
#: conf/karma_and_badges_visibility.py:27
msgid "Visibility of karma"
-msgstr ""
+msgstr "Visibility of karma"
#: conf/karma_and_badges_visibility.py:30
msgid "User's karma may be shown publicly or only to the owners"
-msgstr ""
+msgstr "User's karma may be shown publicly or only to the owners"
#: conf/karma_and_badges_visibility.py:44
msgid "Visibility of badges"
-msgstr ""
+msgstr "Visibility of badges"
#: conf/karma_and_badges_visibility.py:47
msgid "Badges can be either publicly shown or completely hidden"
-msgstr ""
+msgstr "Badges can be either publicly shown or completely hidden"
#: conf/ldap.py:9
msgid "LDAP login configuration"
-msgstr ""
+msgstr "LDAP login configuration"
#: conf/ldap.py:17
msgid "Use LDAP authentication for the password login"
-msgstr ""
+msgstr "Use LDAP authentication for the password login"
#: conf/ldap.py:26
msgid "Automatically create user accounts when possible"
-msgstr ""
+msgstr "Automatically create user accounts when possible"
#: conf/ldap.py:29
msgid ""
"Potentially reduces number of steps in the registration process but can "
"expose personal information, e.g. when LDAP login name is the same as email "
"address or real name."
-msgstr ""
+msgstr "Potentially reduces number of steps in the registration process but can expose personal information, e.g. when LDAP login name is the same as email address or real name."
#: conf/ldap.py:37
msgid "Version 3"
-msgstr ""
+msgstr "Version 3"
#: conf/ldap.py:38
msgid "Version 2 (insecure and deprecated)!!!"
-msgstr ""
+msgstr "Version 2 (insecure and deprecated)!!!"
#: conf/ldap.py:47
msgid "LDAP protocol version"
-msgstr ""
+msgstr "LDAP protocol version"
#: conf/ldap.py:49
msgid ""
"Note that Version 2 protocol is not secure!!! Do not use it on unprotected "
"network."
-msgstr ""
+msgstr "Note that Version 2 protocol is not secure!!! Do not use it on unprotected network."
#: conf/ldap.py:59
msgid "LDAP URL"
-msgstr ""
+msgstr "LDAP URL"
#: conf/ldap.py:68
msgid "LDAP encoding"
-msgstr ""
+msgstr "LDAP encoding"
#: conf/ldap.py:71
msgid ""
"This value in almost all cases is \"utf-8\". Change it if yours is "
"different. This field is required"
-msgstr ""
+msgstr "This value in almost all cases is \"utf-8\". Change it if yours is different. This field is required"
#: conf/ldap.py:82
msgid "Base DN (distinguished name)"
-msgstr ""
+msgstr "Base DN (distinguished name)"
#: conf/ldap.py:85
msgid ""
"Usually base DN mirrors domain name of your organization, e.g. "
"\"dn=example,dn=com\" when your site url is \"example.com\".This value is "
"the \"root\" address of your LDAP directory."
-msgstr ""
+msgstr "Usually base DN mirrors domain name of your organization, e.g. \"dn=example,dn=com\" when your site url is \"example.com\".This value is the \"root\" address of your LDAP directory."
#: conf/ldap.py:96
msgid "User search filter template"
-msgstr ""
+msgstr "User search filter template"
#: conf/ldap.py:99
msgid ""
@@ -1454,7 +1455,7 @@ msgid ""
"should be left in the intact format. First placeholder will be used for the "
"user id field name, and the second - for the user id value. The template can"
" be extended to match schema of your LDAP directory."
-msgstr ""
+msgstr "Python string format template, must have two string placeholders, which should be left in the intact format. First placeholder will be used for the user id field name, and the second - for the user id value. The template can be extended to match schema of your LDAP directory."
#: conf/ldap.py:113
msgid "UserID/login field"
@@ -1464,76 +1465,76 @@ msgstr ""
msgid ""
"This field is required. For Microsoft Active Directory this value usually is"
" \"sAMAccountName\"."
-msgstr ""
+msgstr "This field is required. For Microsoft Active Directory this value usually is \"sAMAccountName\"."
#: conf/ldap.py:127
msgid "\"Common Name\" field"
-msgstr ""
+msgstr "\"Common Name\" field"
#: conf/ldap.py:129
msgid ""
"Common name is a formal or informal name of a person, can be blank. Use it "
"only if surname and given names are not available."
-msgstr ""
+msgstr "Common name is a formal or informal name of a person, can be blank. Use it only if surname and given names are not available."
#: conf/ldap.py:139
msgid "First name, Last name"
-msgstr ""
+msgstr "First name, Last name"
#: conf/ldap.py:140
msgid "Last name, First name"
-msgstr ""
+msgstr "Last name, First name"
#: conf/ldap.py:147
msgid "\"Common Name\" field format"
-msgstr ""
+msgstr "\"Common Name\" field format"
#: conf/ldap.py:150
msgid "Use this only if \"Common Name\" field is used."
-msgstr ""
+msgstr "Use this only if \"Common Name\" field is used."
#: conf/ldap.py:158
msgid "Given (First) name"
-msgstr ""
+msgstr "Given (First) name"
#: conf/ldap.py:160 conf/ldap.py:170
msgid "This field can be blank"
-msgstr ""
+msgstr "This field can be blank"
#: conf/ldap.py:168
msgid "Surname (last) name"
-msgstr ""
+msgstr "Surname (last) name"
#: conf/ldap.py:178
msgid "LDAP Server EMAIL field name"
-msgstr ""
+msgstr "LDAP Server EMAIL field name"
#: conf/ldap.py:180
msgid "This field is required"
-msgstr ""
+msgstr "This field is required"
#: conf/leading_sidebar.py:12
msgid "Common left sidebar"
-msgstr ""
+msgstr "Common left sidebar"
#: conf/leading_sidebar.py:20
msgid "Enable left sidebar"
-msgstr ""
+msgstr "Enable left sidebar"
#: conf/leading_sidebar.py:29
msgid "HTML for the left sidebar"
-msgstr ""
+msgstr "HTML for the left sidebar"
#: conf/leading_sidebar.py:32
msgid ""
"Use this area to enter content at the LEFT sidebarin HTML format. When "
"using this option, please use the HTML validation service to make sure that "
"your input is valid and works well in all browsers."
-msgstr ""
+msgstr "Use this area to enter content at the LEFT sidebarin HTML format. When using this option, please use the HTML validation service to make sure that your input is valid and works well in all browsers."
#: conf/license.py:13
msgid "Content License"
-msgstr "رخصة المحتوي"
+msgstr "Content License"
#: conf/license.py:21
msgid "Show license clause in the site footer"
@@ -1549,7 +1550,7 @@ msgstr "الاسم الكامل للرخصة"
#: conf/license.py:40
msgid "Creative Commons Attribution Share Alike 3.0"
-msgstr ""
+msgstr "Creative Commons Attribution Share Alike 3.0"
#: conf/license.py:48
msgid "Add link to the license page"
@@ -1591,19 +1592,19 @@ msgstr "تنشيط السماح بتسجيل الدخول باستخدام موÙ
msgid ""
"to activate this feature you must fill out the wordpress xml-rpc setting "
"bellow"
-msgstr ""
+msgstr "to activate this feature you must fill out the wordpress xml-rpc setting bellow"
#: conf/login_providers.py:50
msgid ""
"Fill it with the wordpress url to the xml-rpc, normally "
"http://mysite.com/xmlrpc.php"
-msgstr ""
+msgstr "Fill it with the wordpress url to the xml-rpc, normally http://mysite.com/xmlrpc.php"
#: conf/login_providers.py:51
msgid ""
"To enable, go to Settings->Writing->Remote Publishing and check the box for "
"XML-RPC"
-msgstr ""
+msgstr "To enable, go to Settings->Writing->Remote Publishing and check the box for XML-RPC"
#: conf/login_providers.py:60
msgid "Upload your icon"
@@ -1611,7 +1612,7 @@ msgstr "رÙع الأيقونة"
#: conf/login_providers.py:93
msgid "local password"
-msgstr ""
+msgstr "local password"
#: conf/login_providers.py:98
#, python-format
@@ -1627,11 +1628,11 @@ msgstr "ملاحظة: لإتمام تنشيط تسجيل الدخول باستخ
#: conf/markup.py:15
msgid "Markup in posts"
-msgstr ""
+msgstr "Markup in posts"
#: conf/markup.py:41
msgid "Enable code-friendly Markdown"
-msgstr ""
+msgstr "Enable code-friendly Markdown"
#: conf/markup.py:43
msgid ""
@@ -1639,43 +1640,43 @@ msgid ""
" - bold and italic text can still be marked up with asterisks. Note that "
"\"MathJax support\" implicitly turns this feature on, because underscores "
"are heavily used in LaTeX input."
-msgstr ""
+msgstr "If checked, underscore characters will not trigger italic or bold formatting - bold and italic text can still be marked up with asterisks. Note that \"MathJax support\" implicitly turns this feature on, because underscores are heavily used in LaTeX input."
#: conf/markup.py:58
msgid "Mathjax support (rendering of LaTeX)"
-msgstr ""
+msgstr "Mathjax support (rendering of LaTeX)"
#: conf/markup.py:60
#, python-format
msgid ""
"If you enable this feature, <a href=\"%(url)s\">mathjax</a> must be "
"installed on your server in its own directory."
-msgstr ""
+msgstr "If you enable this feature, <a href=\"%(url)s\">mathjax</a> must be installed on your server in its own directory."
#: conf/markup.py:74
msgid "Base url of MathJax deployment"
-msgstr ""
+msgstr "Base url of MathJax deployment"
#: conf/markup.py:76
msgid ""
"Note - <strong>MathJax is not included with askbot</strong> - you should "
"deploy it yourself, preferably at a separate domain and enter url pointing "
"to the \"mathjax\" directory (for example: http://mysite.com/mathjax)"
-msgstr ""
+msgstr "Note - <strong>MathJax is not included with askbot</strong> - you should deploy it yourself, preferably at a separate domain and enter url pointing to the \"mathjax\" directory (for example: http://mysite.com/mathjax)"
#: conf/markup.py:91
msgid "Enable autolinking with specific patterns"
-msgstr ""
+msgstr "Enable autolinking with specific patterns"
#: conf/markup.py:93
msgid ""
"If you enable this feature, the application will be able to detect patterns"
" and auto link to URLs"
-msgstr ""
+msgstr "If you enable this feature, the application will be able to detect patterns and auto link to URLs"
#: conf/markup.py:106
msgid "Regexes to detect the link patterns"
-msgstr ""
+msgstr "Regexes to detect the link patterns"
#: conf/markup.py:108
msgid ""
@@ -1684,11 +1685,11 @@ msgid ""
"The numbers captured by the pattern in the parentheses will be transferred "
"to the link url template. Please look up more information about regular "
"expressions elsewhere."
-msgstr ""
+msgstr "Enter valid regular expressions for the patters, one per line. For example to detect a bug pattern like #bug123, use the following regex: #bug(\\d+). The numbers captured by the pattern in the parentheses will be transferred to the link url template. Please look up more information about regular expressions elsewhere."
#: conf/markup.py:127
msgid "URLs for autolinking"
-msgstr ""
+msgstr "URLs for autolinking"
#: conf/markup.py:129
msgid ""
@@ -1698,11 +1699,11 @@ msgid ""
" https://bugzilla.redhat.com/show_bug.cgi?id=\\1 together with the pattern "
"shown above and the entry in the post #123 will produce link to the bug 123 "
"in the redhat bug tracker."
-msgstr ""
+msgstr "Here, please enter url templates for the patterns entered in the previous setting, also one entry per line. <strong>Make sure that number of lines in this setting and the previous one are the same</strong> For example template https://bugzilla.redhat.com/show_bug.cgi?id=\\1 together with the pattern shown above and the entry in the post #123 will produce link to the bug 123 in the redhat bug tracker."
#: conf/minimum_reputation.py:12
msgid "Karma thresholds"
-msgstr ""
+msgstr "Karma thresholds"
#: conf/minimum_reputation.py:22
msgid "Upvote"
@@ -1714,7 +1715,7 @@ msgstr "تصويت للأسÙÙ„"
#: conf/minimum_reputation.py:40
msgid "Answer own question immediately"
-msgstr "تسليم إجابتك"
+msgstr "الإجابة على سؤالك Ùوراً"
#: conf/minimum_reputation.py:49
msgid "Accept own answer"
@@ -1722,7 +1723,7 @@ msgstr "قبول إجابتي"
#: conf/minimum_reputation.py:58
msgid "Accept any answer"
-msgstr ""
+msgstr "قبول أي إجابة"
#: conf/minimum_reputation.py:67
msgid "Flag offensive"
@@ -1742,17 +1743,17 @@ msgstr "رÙع الملÙات"
#: conf/minimum_reputation.py:115
msgid "Insert clickable links"
-msgstr ""
+msgstr "نشر رابط قابل للضغط"
#: conf/minimum_reputation.py:124
msgid "Insert link suggestions as plain text"
-msgstr ""
+msgstr "نشر رابط نصي (غير قابل للضغط)"
#: conf/minimum_reputation.py:126
msgid ""
"This value should be smaller than that for \"insert clickable links\". This "
"setting should stop link-spamming by newly registered users."
-msgstr ""
+msgstr "This value should be smaller than that for \"insert clickable links\". This setting should stop link-spamming by newly registered users."
#: conf/minimum_reputation.py:137
msgid "Close own questions"
@@ -1768,7 +1769,7 @@ msgstr "إعادة Ùتح أسئلتي"
#: conf/minimum_reputation.py:164
msgid "Edit community wiki posts"
-msgstr ""
+msgstr "تعديل مشاركات الويكي"
#: conf/minimum_reputation.py:173
msgid "Edit posts authored by other people"
@@ -1776,7 +1777,7 @@ msgstr "تحرير مشاركات الآخرين"
#: conf/minimum_reputation.py:182
msgid "View offensive flags"
-msgstr ""
+msgstr "الإطلاع على تبليغات الإساءة"
#: conf/minimum_reputation.py:191
msgid "Close questions asked by others"
@@ -1784,156 +1785,156 @@ msgstr "إغلاق أسئلة الآخرين"
#: conf/minimum_reputation.py:200
msgid "Remove rel=nofollow from own homepage"
-msgstr ""
+msgstr "إزالة وسم rel=nofollow عن صÙحتك الشخصية"
#: conf/minimum_reputation.py:202
msgid ""
"When a search engine crawler will see a rel=nofollow attribute on a link - "
"the link will not count towards the rank of the users personal site."
-msgstr ""
+msgstr "عندما تقوم محركات البحث بارشÙØ© الصÙحات وتجد وسم rel=nofollow على الرابط Ùانها بهذه الحالة تتجاهل الرابط تماماً. "
#: conf/minimum_reputation.py:214
msgid "Make posts by email"
-msgstr ""
+msgstr "نشر مشاركات عبر البريد"
#: conf/minimum_reputation.py:223
msgid "Trigger email notifications"
-msgstr ""
+msgstr "Trigger email notifications"
#: conf/minimum_reputation.py:224 conf/minimum_reputation.py:234
msgid "Reduces spam"
-msgstr ""
+msgstr "Reduces spam"
#: conf/minimum_reputation.py:233
msgid "Trigger tweets on others accounts"
-msgstr ""
+msgstr "Trigger tweets on others accounts"
#: conf/moderation.py:19
msgid "Content moderation"
-msgstr ""
+msgstr "Content moderation"
#: conf/moderation.py:28
msgid "Enable content moderation"
-msgstr ""
+msgstr "Enable content moderation"
#: conf/moderation.py:38
msgid "Enable tag moderation"
-msgstr ""
+msgstr "Enable tag moderation"
#: conf/moderation.py:40
msgid ""
"If enabled, any new tags will not be applied to the questions, but emailed "
"to the moderators. To use this feature, tags must be optional."
-msgstr ""
+msgstr "If enabled, any new tags will not be applied to the questions, but emailed to the moderators. To use this feature, tags must be optional."
#: conf/question_lists.py:11
msgid "Listings of questions"
-msgstr ""
+msgstr "Listings of questions"
#: conf/question_lists.py:20
msgid "Enable \"All Questions\" selector"
-msgstr ""
+msgstr "Enable \"All Questions\" selector"
#: conf/question_lists.py:21 conf/question_lists.py:31
#: conf/question_lists.py:41
msgid "At least one of these selectors must be enabled"
-msgstr ""
+msgstr "At least one of these selectors must be enabled"
#: conf/question_lists.py:30
msgid "Enable \"Unanswered Questions\" selector"
-msgstr ""
+msgstr "Enable \"Unanswered Questions\" selector"
#: conf/question_lists.py:40
msgid "Enable \"Followed Questions\" selector"
-msgstr ""
+msgstr "Enable \"Followed Questions\" selector"
#: conf/question_lists.py:53 conf/question_lists.py:70
msgid "All Questions"
-msgstr ""
+msgstr "All Questions"
#: conf/question_lists.py:54 conf/question_lists.py:71
msgid "Unanswered Questions"
-msgstr ""
+msgstr "Unanswered Questions"
#: conf/question_lists.py:55
msgid "Followed Questions"
-msgstr ""
+msgstr "Followed Questions"
#: conf/question_lists.py:64
msgid "Default questions selector for the authenticated users"
-msgstr ""
+msgstr "Default questions selector for the authenticated users"
#: conf/question_lists.py:80
msgid "Default questions selector for the anonymous users"
-msgstr ""
+msgstr "Default questions selector for the anonymous users"
#: conf/reputation_changes.py:13
msgid "Karma loss and gain rules"
-msgstr ""
+msgstr "Karma loss and gain rules"
#: conf/reputation_changes.py:23
msgid "Maximum daily reputation gain per user"
-msgstr ""
+msgstr "Maximum daily reputation gain per user"
#: conf/reputation_changes.py:32
msgid "Gain for receiving an upvote"
-msgstr ""
+msgstr "Gain for receiving an upvote"
#: conf/reputation_changes.py:41
msgid "Gain for the author of accepted answer"
-msgstr ""
+msgstr "Gain for the author of accepted answer"
#: conf/reputation_changes.py:50
msgid "Gain for accepting best answer"
-msgstr ""
+msgstr "Gain for accepting best answer"
#: conf/reputation_changes.py:59
msgid "Gain for post owner on canceled downvote"
-msgstr ""
+msgstr "Gain for post owner on canceled downvote"
#: conf/reputation_changes.py:68
msgid "Gain for voter on canceling downvote"
-msgstr ""
+msgstr "Gain for voter on canceling downvote"
#: conf/reputation_changes.py:78
msgid "Loss for voter for canceling of answer acceptance"
-msgstr ""
+msgstr "Loss for voter for canceling of answer acceptance"
#: conf/reputation_changes.py:88
msgid "Loss for author whose answer was \"un-accepted\""
-msgstr ""
+msgstr "Loss for author whose answer was \"un-accepted\""
#: conf/reputation_changes.py:98
msgid "Loss for giving a downvote"
-msgstr ""
+msgstr "Loss for giving a downvote"
#: conf/reputation_changes.py:108
msgid "Loss for owner of post that was flagged offensive"
-msgstr ""
+msgstr "Loss for owner of post that was flagged offensive"
#: conf/reputation_changes.py:118
msgid "Loss for owner of post that was downvoted"
-msgstr ""
+msgstr "Loss for owner of post that was downvoted"
#: conf/reputation_changes.py:128
msgid "Loss for owner of post that was flagged 3 times per same revision"
-msgstr ""
+msgstr "Loss for owner of post that was flagged 3 times per same revision"
#: conf/reputation_changes.py:138
msgid "Loss for owner of post that was flagged 5 times per same revision"
-msgstr ""
+msgstr "Loss for owner of post that was flagged 5 times per same revision"
#: conf/reputation_changes.py:148
msgid "Loss for post owner when upvote is canceled"
-msgstr ""
+msgstr "Loss for post owner when upvote is canceled"
#: conf/sidebar_main.py:12
msgid "Main page sidebar"
-msgstr ""
+msgstr "Main page sidebar"
#: conf/sidebar_main.py:20 conf/sidebar_question.py:67
msgid "Custom sidebar header"
-msgstr ""
+msgstr "Custom sidebar header"
#: conf/sidebar_main.py:23 conf/sidebar_profile.py:23
msgid ""
@@ -1941,25 +1942,25 @@ msgid ""
"When using this option (as well as the sidebar footer), please use the HTML "
"validation service to make sure that your input is valid and works well in "
"all browsers."
-msgstr ""
+msgstr "Use this area to enter content at the TOP of the sidebarin HTML format. When using this option (as well as the sidebar footer), please use the HTML validation service to make sure that your input is valid and works well in all browsers."
#: conf/sidebar_main.py:36 conf/sidebar_main.py:111 conf/sidebar_profile.py:37
#: conf/sidebar_question.py:34 conf/sidebar_question.py:58
#: conf/sidebar_question.py:84 conf/sidebar_question.py:149
msgid "Show above only to anonymous users"
-msgstr ""
+msgstr "Show above only to anonymous users"
#: conf/sidebar_main.py:45
msgid "Show avatar block in sidebar"
-msgstr ""
+msgstr "Show avatar block in sidebar"
#: conf/sidebar_main.py:47
msgid "Uncheck this if you want to hide the avatar block from the sidebar "
-msgstr ""
+msgstr "Uncheck this if you want to hide the avatar block from the sidebar "
#: conf/sidebar_main.py:58
msgid "Limit how many avatars will be displayed on the sidebar"
-msgstr ""
+msgstr "Limit how many avatars will be displayed on the sidebar"
#: conf/sidebar_main.py:68
msgid "Show tag selector in sidebar"
@@ -1969,16 +1970,16 @@ msgstr "عرض منتقي الوسوم ÙÙŠ الشريط الجانبي"
msgid ""
"Uncheck this if you want to hide the options for choosing interesting and "
"ignored tags "
-msgstr ""
+msgstr "Uncheck this if you want to hide the options for choosing interesting and ignored tags "
#: conf/sidebar_main.py:81
msgid "Show tag list/cloud in sidebar"
-msgstr ""
+msgstr "Show tag list/cloud in sidebar"
#: conf/sidebar_main.py:83
msgid ""
"Uncheck this if you want to hide the tag cloud or tag list from the sidebar "
-msgstr ""
+msgstr "Uncheck this if you want to hide the tag cloud or tag list from the sidebar "
#: conf/sidebar_main.py:94 conf/sidebar_question.py:132
msgid "Custom sidebar footer"
@@ -1990,40 +1991,40 @@ msgid ""
" When using this option (as well as the sidebar header), please use the "
"HTML validation service to make sure that your input is valid and works well"
" in all browsers."
-msgstr ""
+msgstr "Use this area to enter content at the BOTTOM of the sidebarin HTML format. When using this option (as well as the sidebar header), please use the HTML validation service to make sure that your input is valid and works well in all browsers."
#: conf/sidebar_profile.py:12
msgid "User profile sidebar"
-msgstr ""
+msgstr "User profile sidebar"
#: conf/sidebar_profile.py:20
msgid "Custom sidebar"
-msgstr ""
+msgstr "Custom sidebar"
#: conf/sidebar_question.py:11
msgid "Question page banners and sidebar"
-msgstr ""
+msgstr "Question page banners and sidebar"
#: conf/sidebar_question.py:19
msgid "Top banner"
-msgstr ""
+msgstr "Top banner"
#: conf/sidebar_question.py:22
msgid ""
"When using this option, please use the HTML validation service to make sure "
"that your input is valid and works well in all browsers."
-msgstr ""
+msgstr "When using this option, please use the HTML validation service to make sure that your input is valid and works well in all browsers."
#: conf/sidebar_question.py:42
msgid "Answers banner"
-msgstr ""
+msgstr "Answers banner"
#: conf/sidebar_question.py:45
msgid ""
"This banner will show above the second answer. When using this option, "
"please use the HTML validation service to make sure that your input is valid"
" and works well in all browsers."
-msgstr ""
+msgstr "This banner will show above the second answer. When using this option, please use the HTML validation service to make sure that your input is valid and works well in all browsers."
#: conf/sidebar_question.py:70
msgid ""
@@ -2031,7 +2032,7 @@ msgid ""
" using this option (as well as the sidebar footer), please use the HTML "
"validation service to make sure that your input is valid and works well in "
"all browsers."
-msgstr ""
+msgstr "Use this area to enter content at the TOP of the sidebarin HTML format. When using this option (as well as the sidebar footer), please use the HTML validation service to make sure that your input is valid and works well in all browsers."
#: conf/sidebar_question.py:92
msgid "Show tag list in sidebar"
@@ -2039,7 +2040,7 @@ msgstr "عرض قائمة الأوسمة ÙÙŠ الشريط الجانبي"
#: conf/sidebar_question.py:94
msgid "Uncheck this if you want to hide the tag list from the sidebar "
-msgstr ""
+msgstr "Uncheck this if you want to hide the tag list from the sidebar "
#: conf/sidebar_question.py:105
msgid "Show meta information in sidebar"
@@ -2049,7 +2050,7 @@ msgstr "عرض المعلومات الوصÙية ÙÙŠ الشريط الجانبÙ
msgid ""
"Uncheck this if you want to hide the meta information about the question "
"(post date, views, last updated). "
-msgstr ""
+msgstr "Uncheck this if you want to hide the meta information about the question (post date, views, last updated). "
#: conf/sidebar_question.py:119
msgid "Show related questions in sidebar"
@@ -2057,15 +2058,15 @@ msgstr "عرض الأسئلة ذات الصلة ÙÙŠ الشريط الجانبي
#: conf/sidebar_question.py:121
msgid "Uncheck this if you want to hide the list of related questions. "
-msgstr ""
+msgstr "Uncheck this if you want to hide the list of related questions. "
#: conf/site_modes.py:63
msgid "Bootstrap mode"
-msgstr ""
+msgstr "Bootstrap mode"
#: conf/site_modes.py:73
msgid "Activate a \"Large site\" mode"
-msgstr ""
+msgstr "Activate a \"Large site\" mode"
#: conf/site_modes.py:75
msgid ""
@@ -2073,19 +2074,19 @@ msgid ""
"values, more suitable for the larger communities, <strong>WARNING:</strong> "
"your current values for Minimum reputation, Badge Settings and Vote Rules "
"will be changed after you modify this setting."
-msgstr ""
+msgstr "\"Large site\" mode increases reputation and certain badge thresholds, to values, more suitable for the larger communities, <strong>WARNING:</strong> your current values for Minimum reputation, Badge Settings and Vote Rules will be changed after you modify this setting."
#: conf/site_settings.py:14
msgid "URLS, keywords & greetings"
-msgstr ""
+msgstr "URLS, keywords & greetings"
#: conf/site_settings.py:23
msgid "Site title for the Q&A forum"
-msgstr ""
+msgstr "Site title for the Q&A forum"
#: conf/site_settings.py:32
msgid "Comma separated list of Q&A site keywords"
-msgstr ""
+msgstr "Comma separated list of Q&A site keywords"
#: conf/site_settings.py:41
msgid "Copyright message to show in the footer"
@@ -2101,131 +2102,131 @@ msgstr "الاسم المختصر لمنتدى الأسئلة والأجوبة"
#: conf/site_settings.py:70
msgid "Please enter url of your site"
-msgstr ""
+msgstr "Please enter url of your site"
#: conf/site_settings.py:73
msgid "Url must start either from http or https"
-msgstr ""
+msgstr "Url must start either from http or https"
#: conf/site_settings.py:92
msgid "Base URL for your Q&A forum, must start with http or https"
-msgstr ""
+msgstr "Base URL for your Q&A forum, must start with http or https"
#: conf/site_settings.py:104
msgid "Check to enable greeting for anonymous user"
-msgstr ""
+msgstr "Check to enable greeting for anonymous user"
#: conf/site_settings.py:115
msgid "Text shown in the greeting message shown to the anonymous user"
-msgstr ""
+msgstr "Text shown in the greeting message shown to the anonymous user"
#: conf/site_settings.py:119
msgid "Use HTML to format the message "
-msgstr ""
+msgstr "Use HTML to format the message "
#: conf/site_settings.py:128
msgid "Feedback site URL"
-msgstr ""
+msgstr "Feedback site URL"
#: conf/site_settings.py:130
msgid "If left empty, a simple internal feedback form will be used instead"
-msgstr ""
+msgstr "If left empty, a simple internal feedback form will be used instead"
#: conf/skin_general_settings.py:15
msgid "Skin, logos and HTML <head> parts"
-msgstr ""
+msgstr "Skin, logos and HTML <head> parts"
#: conf/skin_general_settings.py:23
msgid "Q&A site logo"
-msgstr ""
+msgstr "Q&A site logo"
#: conf/skin_general_settings.py:25
msgid "To change the logo, select new file, then submit this whole form."
-msgstr ""
+msgstr "To change the logo, select new file, then submit this whole form."
#: conf/skin_general_settings.py:34
msgid "English"
-msgstr ""
+msgstr "إنجليزي"
#: conf/skin_general_settings.py:35
msgid "Spanish"
-msgstr ""
+msgstr "إسباني"
#: conf/skin_general_settings.py:36
msgid "Catalan"
-msgstr ""
+msgstr "Catalan"
#: conf/skin_general_settings.py:37
msgid "German"
-msgstr ""
+msgstr "ألماني"
#: conf/skin_general_settings.py:38
msgid "Greek"
-msgstr ""
+msgstr "يوناني"
#: conf/skin_general_settings.py:39
msgid "Finnish"
-msgstr ""
+msgstr "Finnish"
#: conf/skin_general_settings.py:40
msgid "French"
-msgstr ""
+msgstr "Ùرنسي"
#: conf/skin_general_settings.py:41
msgid "Hindi"
-msgstr ""
+msgstr "هندي"
#: conf/skin_general_settings.py:42
msgid "Hungarian"
-msgstr ""
+msgstr "هنجاري"
#: conf/skin_general_settings.py:43
msgid "Italian"
-msgstr ""
+msgstr "إيطالي"
#: conf/skin_general_settings.py:44
msgid "Japanese"
-msgstr ""
+msgstr "ياباني"
#: conf/skin_general_settings.py:45
msgid "Korean"
-msgstr ""
+msgstr "كوري"
#: conf/skin_general_settings.py:46
msgid "Portuguese"
-msgstr ""
+msgstr "برتغالي"
#: conf/skin_general_settings.py:47
msgid "Brazilian Portuguese"
-msgstr ""
+msgstr "برازيلي برتغالي"
#: conf/skin_general_settings.py:48
msgid "Romanian"
-msgstr ""
+msgstr "روماني"
#: conf/skin_general_settings.py:49
msgid "Russian"
-msgstr ""
+msgstr "روسي"
#: conf/skin_general_settings.py:50
msgid "Serbian"
-msgstr ""
+msgstr "صربي"
#: conf/skin_general_settings.py:51
msgid "Turkish"
-msgstr ""
+msgstr "تركي"
#: conf/skin_general_settings.py:52
msgid "Vietnamese"
-msgstr ""
+msgstr "Ùيتنامي"
#: conf/skin_general_settings.py:53
msgid "Chinese"
-msgstr ""
+msgstr "صيني"
#: conf/skin_general_settings.py:54
msgid "Chinese (Taiwan)"
-msgstr ""
+msgstr "صيني (تايوان)"
#: conf/skin_general_settings.py:73
msgid "Show logo"
@@ -2235,7 +2236,7 @@ msgstr "عرض الشعار"
msgid ""
"Check if you want to show logo in the forum header or uncheck in the case "
"you do not want the logo to appear in the default location"
-msgstr ""
+msgstr "Check if you want to show logo in the forum header or uncheck in the case you do not want the logo to appear in the default location"
#: conf/skin_general_settings.py:87
msgid "Site favicon"
@@ -2247,28 +2248,28 @@ msgid ""
"A small 16x16 or 32x32 pixel icon image used to distinguish your site in the"
" browser user interface. Please find more information about favicon at <a "
"href=\"%(favicon_info_url)s\">this page</a>."
-msgstr ""
+msgstr "A small 16x16 or 32x32 pixel icon image used to distinguish your site in the browser user interface. Please find more information about favicon at <a href=\"%(favicon_info_url)s\">this page</a>."
#: conf/skin_general_settings.py:105
msgid "Password login button"
-msgstr ""
+msgstr "Password login button"
#: conf/skin_general_settings.py:107
msgid ""
"An 88x38 pixel image that is used on the login screen for the password login"
" button."
-msgstr ""
+msgstr "An 88x38 pixel image that is used on the login screen for the password login button."
#: conf/skin_general_settings.py:120
msgid "Show all UI functions to all users"
-msgstr ""
+msgstr "Show all UI functions to all users"
#: conf/skin_general_settings.py:122
msgid ""
"If checked, all forum functions will be shown to users, regardless of their "
"reputation. However to use those functions, moderation rules, reputation and"
" other limits will still apply."
-msgstr ""
+msgstr "If checked, all forum functions will be shown to users, regardless of their reputation. However to use those functions, moderation rules, reputation and other limits will still apply."
#: conf/skin_general_settings.py:137
msgid "Select skin"
@@ -2276,11 +2277,11 @@ msgstr "اختيار السمة"
#: conf/skin_general_settings.py:148
msgid "Customize HTML <HEAD>"
-msgstr ""
+msgstr "Customize HTML <HEAD>"
#: conf/skin_general_settings.py:157
msgid "Custom portion of the HTML <HEAD>"
-msgstr ""
+msgstr "Custom portion of the HTML <HEAD>"
#: conf/skin_general_settings.py:159
msgid ""
@@ -2292,11 +2293,11 @@ msgid ""
"of the pages. Instead, it will be more efficient to place links to the "
"javascript files into the footer. <strong>Note:</strong> if you do use this "
"setting, please test the site with the W3C HTML validator service."
-msgstr ""
+msgstr "<strong>To use this option</strong>, check \"Customize HTML &lt;HEAD&gt;\" above. Contents of this box will be inserted into the &lt;HEAD&gt; portion of the HTML output, where elements such as &lt;script&gt;, &lt;link&gt;, &lt;meta&gt; may be added. Please, keep in mind that adding external javascript to the &lt;HEAD&gt; is not recommended because it slows loading of the pages. Instead, it will be more efficient to place links to the javascript files into the footer. <strong>Note:</strong> if you do use this setting, please test the site with the W3C HTML validator service."
#: conf/skin_general_settings.py:181
msgid "Custom header additions"
-msgstr ""
+msgstr "Custom header additions"
#: conf/skin_general_settings.py:183
msgid ""
@@ -2305,21 +2306,21 @@ msgid ""
"headerin the HTML format. When customizing the site header (as well as "
"footer and the HTML &lt;HEAD&gt;), use the HTML validation service to make "
"sure that your input is valid and works well in all browsers."
-msgstr ""
+msgstr "Header is the bar at the top of the content that contains user info and site links, and is common to all pages. Use this area to enter contents of the headerin the HTML format. When customizing the site header (as well as footer and the HTML &lt;HEAD&gt;), use the HTML validation service to make sure that your input is valid and works well in all browsers."
#: conf/skin_general_settings.py:198
msgid "Site footer mode"
-msgstr ""
+msgstr "Site footer mode"
#: conf/skin_general_settings.py:200
msgid ""
"Footer is the bottom portion of the content, which is common to all pages. "
"You can disable, customize, or use the default footer."
-msgstr ""
+msgstr "Footer is the bottom portion of the content, which is common to all pages. You can disable, customize, or use the default footer."
#: conf/skin_general_settings.py:217
msgid "Custom footer (HTML format)"
-msgstr ""
+msgstr "Custom footer (HTML format)"
#: conf/skin_general_settings.py:219
msgid ""
@@ -2328,21 +2329,21 @@ msgid ""
"footer in the HTML format. When customizing the site footer (as well as the "
"header and HTML &lt;HEAD&gt;), use the HTML validation service to make sure "
"that your input is valid and works well in all browsers."
-msgstr ""
+msgstr "<strong>To enable this function</strong>, please select option 'customize' in the \"Site footer mode\" above. Use this area to enter contents of the footer in the HTML format. When customizing the site footer (as well as the header and HTML &lt;HEAD&gt;), use the HTML validation service to make sure that your input is valid and works well in all browsers."
#: conf/skin_general_settings.py:234
msgid "Apply custom style sheet (CSS)"
-msgstr ""
+msgstr "Apply custom style sheet (CSS)"
#: conf/skin_general_settings.py:236
msgid ""
"Check if you want to change appearance of your form by adding custom style "
"sheet rules (please see the next item)"
-msgstr ""
+msgstr "Check if you want to change appearance of your form by adding custom style sheet rules (please see the next item)"
#: conf/skin_general_settings.py:248
msgid "Custom style sheet (CSS)"
-msgstr ""
+msgstr "Custom style sheet (CSS)"
#: conf/skin_general_settings.py:250
msgid ""
@@ -2351,7 +2352,7 @@ msgid ""
"default style sheet rules. The custom style sheet will be served dynamically"
" at url \"&lt;forum url&gt;/custom.css\", where the \"&lt;forum url&gt; part"
" depends (default is empty string) on the url configuration in your urls.py."
-msgstr ""
+msgstr "<strong>To use this function</strong>, check \"Apply custom style sheet\" option above. The CSS rules added in this window will be applied after the default style sheet rules. The custom style sheet will be served dynamically at url \"&lt;forum url&gt;/custom.css\", where the \"&lt;forum url&gt; part depends (default is empty string) on the url configuration in your urls.py."
#: conf/skin_general_settings.py:266
msgid "Add custom javascript"
@@ -2359,11 +2360,11 @@ msgstr "إضاÙØ© javascript مخصص"
#: conf/skin_general_settings.py:269
msgid "Check to enable javascript that you can enter in the next field"
-msgstr ""
+msgstr "Check to enable javascript that you can enter in the next field"
#: conf/skin_general_settings.py:279
msgid "Custom javascript"
-msgstr ""
+msgstr "Custom javascript"
#: conf/skin_general_settings.py:281
msgid ""
@@ -2374,156 +2375,156 @@ msgid ""
"that the behavior may not be consistent across different browsers "
"(<strong>to enable your custom code</strong>, check \"Add custom "
"javascript\" option above)."
-msgstr ""
+msgstr "Type or paste plain javascript that you would like to run on your site. Link to the script will be inserted at the bottom of the HTML output and will be served at the url \"&lt;forum url&gt;/custom.js\". Please, bear in mind that your javascript code may break other functionalities of the site and that the behavior may not be consistent across different browsers (<strong>to enable your custom code</strong>, check \"Add custom javascript\" option above)."
#: conf/skin_general_settings.py:299
msgid "Skin media revision number"
-msgstr ""
+msgstr "Skin media revision number"
#: conf/skin_general_settings.py:301
msgid "Will be set automatically but you can modify it if necessary."
-msgstr ""
+msgstr "Will be set automatically but you can modify it if necessary."
#: conf/skin_general_settings.py:312
msgid "Hash to update the media revision number automatically."
-msgstr ""
+msgstr "Hash to update the media revision number automatically."
#: conf/skin_general_settings.py:316
msgid "Will be set automatically, it is not necesary to modify manually."
-msgstr ""
+msgstr "Will be set automatically, it is not necesary to modify manually."
#: conf/social_sharing.py:11
msgid "Content sharing"
-msgstr ""
+msgstr "Content sharing"
#: conf/social_sharing.py:20
msgid "Check to enable RSS feeds"
-msgstr ""
+msgstr "Check to enable RSS feeds"
#: conf/social_sharing.py:29
msgid "Hashtag or suffix to sharing messages"
-msgstr ""
+msgstr "Hashtag or suffix to sharing messages"
#: conf/social_sharing.py:38
msgid "Check to enable sharing of questions on Twitter"
-msgstr ""
+msgstr "Check to enable sharing of questions on Twitter"
#: conf/social_sharing.py:40
msgid ""
"Important - to actually start sharing on twitter, it is required to set up "
"Twitter consumer key and secret in the \"keys to external services\" "
"section."
-msgstr ""
+msgstr "Important - to actually start sharing on twitter, it is required to set up Twitter consumer key and secret in the \"keys to external services\" section."
#: conf/social_sharing.py:52
msgid "Check to enable sharing of questions on Facebook"
-msgstr ""
+msgstr "Check to enable sharing of questions on Facebook"
#: conf/social_sharing.py:61
msgid "Check to enable sharing of questions on LinkedIn"
-msgstr ""
+msgstr "Check to enable sharing of questions on LinkedIn"
#: conf/social_sharing.py:70
msgid "Check to enable sharing of questions on Identi.ca"
-msgstr ""
+msgstr "Check to enable sharing of questions on Identi.ca"
#: conf/social_sharing.py:79
msgid "Check to enable sharing of questions on Google+"
-msgstr ""
+msgstr "Check to enable sharing of questions on Google+"
#: conf/spam_and_moderation.py:10
msgid "Akismet spam protection"
-msgstr ""
+msgstr "Akismet spam protection"
#: conf/spam_and_moderation.py:18
msgid "Enable Akismet spam detection(keys below are required)"
-msgstr ""
+msgstr "Enable Akismet spam detection(keys below are required)"
#: conf/spam_and_moderation.py:21
#, python-format
msgid "To get an Akismet key please visit <a href=\"%(url)s\">Akismet site</a>"
-msgstr ""
+msgstr "To get an Akismet key please visit <a href=\"%(url)s\">Akismet site</a>"
#: conf/spam_and_moderation.py:31
msgid "Akismet key for spam detection"
-msgstr ""
+msgstr "Akismet key for spam detection"
#: conf/super_groups.py:5
msgid "Reputation, Badges, Votes & Flags"
-msgstr ""
+msgstr "Reputation, Badges, Votes & Flags"
#: conf/super_groups.py:6
msgid "Static Content, URLS & UI"
-msgstr ""
+msgstr "Static Content, URLS & UI"
#: conf/super_groups.py:7
msgid "Data rules & Formatting"
-msgstr ""
+msgstr "Data rules & Formatting"
#: conf/super_groups.py:8
msgid "External Services"
-msgstr ""
+msgstr "External Services"
#: conf/super_groups.py:9
msgid "Login, Users & Communication"
-msgstr ""
+msgstr "Login, Users & Communication"
#: conf/user_settings.py:14
msgid "User settings"
-msgstr "إعدادات المستخدم"
+msgstr "User settings"
#: conf/user_settings.py:23
msgid "On-screen greeting shown to the new users"
-msgstr ""
+msgstr "On-screen greeting shown to the new users"
#: conf/user_settings.py:32
msgid "Allow anonymous users send feedback"
-msgstr ""
+msgstr "Allow anonymous users send feedback"
#: conf/user_settings.py:41
msgid "Allow editing user screen name"
-msgstr ""
+msgstr "Allow editing user screen name"
#: conf/user_settings.py:50
msgid "Auto-fill user name, email, etc on registration"
-msgstr ""
+msgstr "Auto-fill user name, email, etc on registration"
#: conf/user_settings.py:51
msgid "Implemented only for LDAP logins at this point"
-msgstr ""
+msgstr "Implemented only for LDAP logins at this point"
#: conf/user_settings.py:60
msgid "Allow users change own email addresses"
-msgstr ""
+msgstr "Allow users change own email addresses"
#: conf/user_settings.py:69
msgid "Allow email address in user name"
-msgstr ""
+msgstr "Allow email address in user name"
#: conf/user_settings.py:78
msgid "Allow account recovery by email"
-msgstr ""
+msgstr "Allow account recovery by email"
#: conf/user_settings.py:87
msgid "Allow adding and removing login methods"
-msgstr ""
+msgstr "Allow adding and removing login methods"
#: conf/user_settings.py:97
msgid "Minimum allowed length for screen name"
-msgstr ""
+msgstr "Minimum allowed length for screen name"
#: conf/user_settings.py:105
msgid "Default avatar for users"
-msgstr ""
+msgstr "Default avatar for users"
#: conf/user_settings.py:107
msgid ""
"To change the avatar image, select new file, then submit this whole form."
-msgstr ""
+msgstr "To change the avatar image, select new file, then submit this whole form."
#: conf/user_settings.py:120
msgid "Use automatic avatars from gravatar.com"
-msgstr ""
+msgstr "Use automatic avatars from gravatar.com"
#: conf/user_settings.py:122
msgid ""
@@ -2532,72 +2533,72 @@ msgid ""
"effective. You will have to enable uploaded avatars as well. For more "
"information, please visit <a href=\"http://askbot.org/doc/optional-"
"modules.html#uploaded-avatars\">this page</a>."
-msgstr ""
+msgstr "Check this option if you want to allow the use of gravatar.com for avatars. Please, note that this feature might take about 10 minutes to become fully effective. You will have to enable uploaded avatars as well. For more information, please visit <a href=\"http://askbot.org/doc/optional-modules.html#uploaded-avatars\">this page</a>."
#: conf/user_settings.py:134
msgid "Default Gravatar icon type"
-msgstr ""
+msgstr "Default Gravatar icon type"
#: conf/user_settings.py:136
msgid ""
"This option allows you to set the default avatar type for email addresses "
"without associated gravatar images. For more information, please visit <a "
"href=\"http://en.gravatar.com/site/implement/images/\">this page</a>."
-msgstr ""
+msgstr "This option allows you to set the default avatar type for email addresses without associated gravatar images. For more information, please visit <a href=\"http://en.gravatar.com/site/implement/images/\">this page</a>."
#: conf/user_settings.py:146
msgid "Name for the Anonymous user"
-msgstr ""
+msgstr "Name for the Anonymous user"
#: conf/vote_rules.py:14
msgid "Vote and flag limits"
-msgstr ""
+msgstr "Vote and flag limits"
#: conf/vote_rules.py:24
msgid "Number of votes a user can cast per day"
-msgstr ""
+msgstr "Number of votes a user can cast per day"
#: conf/vote_rules.py:33
msgid "Maximum number of flags per user per day"
-msgstr ""
+msgstr "Maximum number of flags per user per day"
#: conf/vote_rules.py:42
msgid "Threshold for warning about remaining daily votes"
-msgstr ""
+msgstr "Threshold for warning about remaining daily votes"
#: conf/vote_rules.py:51
msgid "Number of days to allow canceling votes"
-msgstr ""
+msgstr "Number of days to allow canceling votes"
#: conf/vote_rules.py:60
msgid "Number of days required before answering own question"
-msgstr ""
+msgstr "Number of days required before answering own question"
#: conf/vote_rules.py:69
msgid "Number of flags required to automatically hide posts"
-msgstr ""
+msgstr "Number of flags required to automatically hide posts"
#: conf/vote_rules.py:78
msgid "Number of flags required to automatically delete posts"
-msgstr ""
+msgstr "Number of flags required to automatically delete posts"
#: conf/vote_rules.py:87
msgid ""
"Minimum days to accept an answer, if it has not been accepted by the "
"question poster"
-msgstr ""
+msgstr "Minimum days to accept an answer, if it has not been accepted by the question poster"
#: const/__init__.py:11
msgid "duplicate question"
-msgstr ""
+msgstr "سؤال مكرر"
#: const/__init__.py:12
msgid "question is off-topic or not relevant"
-msgstr ""
+msgstr "السؤال خارج موضوع الموقع او ليس ذو صلة"
#: const/__init__.py:13
msgid "too subjective and argumentative"
-msgstr ""
+msgstr "شخصي جداً وجدلي"
#: const/__init__.py:14
msgid "not a real question"
@@ -2621,23 +2622,23 @@ msgstr "دعاية أو مادة غير مرغوب Ùيها"
#: const/__init__.py:19
msgid "too localized"
-msgstr ""
+msgstr "لهجة محلية غير Ù…Ùهومة"
#: const/__init__.py:29
msgid "disable sharing"
-msgstr ""
+msgstr "تعطيل المشاركة"
#: const/__init__.py:30
#: templates/user_profile/twitter_sharing_controls.html:13
#: templates/user_profile/twitter_sharing_controls.html:17
msgid "my posts"
-msgstr ""
+msgstr "مشاركاتي"
#: const/__init__.py:31
#: templates/user_profile/twitter_sharing_controls.html:14
#: templates/user_profile/twitter_sharing_controls.html:16
msgid "all posts"
-msgstr ""
+msgstr "كل المشاركات"
#: const/__init__.py:54 templates/question/answer_tab_bar.html:18
msgid "newest"
@@ -2658,11 +2659,11 @@ msgstr "غير نشط"
#: const/__init__.py:58
msgid "hottest"
-msgstr "أكثر إثارة"
+msgstr "الأكثر Ùعالية"
#: const/__init__.py:59
msgid "coldest"
-msgstr "أكثر برودة"
+msgstr "الأقل Ùعالية"
#: const/__init__.py:60 templates/question/answer_tab_bar.html:21
msgid "most voted"
@@ -2678,7 +2679,7 @@ msgstr "الملاءمة"
#: const/__init__.py:74
msgid "Never"
-msgstr ""
+msgstr "أبداً"
#: const/__init__.py:75
msgid "When new post is published"
@@ -2705,7 +2706,7 @@ msgstr "غير مجاب"
#: const/__init__.py:124
msgid "followed"
-msgstr ""
+msgstr "أسئلة Ù…Ùتابعة"
#: const/__init__.py:129
msgid "list"
@@ -2749,7 +2750,7 @@ msgstr "حرر إجابة"
#: const/__init__.py:201
msgid "received badge"
-msgstr "تلقي شارة"
+msgstr "حصل على وسام"
#: const/__init__.py:202
msgid "marked best answer"
@@ -2805,7 +2806,7 @@ msgstr ""
#: const/__init__.py:220
msgid "reminder about accepting the best answer sent"
-msgstr ""
+msgstr "تم إرسال تذكير لقبول Ø£Ùضل إجابة للسؤال"
#: const/__init__.py:222
msgid "mentioned in the post"
@@ -2813,19 +2814,19 @@ msgstr "ذكر ÙÙŠ المشاركة"
#: const/__init__.py:225
msgid "created tag description"
-msgstr ""
+msgstr "كتب وص٠الموضوع"
#: const/__init__.py:229
msgid "updated tag description"
-msgstr ""
+msgstr "حدث وص٠الموضوع"
#: const/__init__.py:231
msgid "made a new post"
-msgstr ""
+msgstr "نشر مشاركة جديدة"
#: const/__init__.py:234
msgid "made an edit"
-msgstr ""
+msgstr "عدل"
#: const/__init__.py:238
msgid "created post reject reason"
@@ -2857,28 +2858,28 @@ msgstr "النسخة الأولى"
#: const/__init__.py:310
msgid "retagged"
-msgstr ""
+msgstr "تم إعادة تعيين المواضيع"
#: const/__init__.py:311
msgid "[private]"
-msgstr ""
+msgstr "[خاص]"
#: const/__init__.py:320
msgid "show all tags"
-msgstr ""
+msgstr "جميع المواضيع"
#: const/__init__.py:321 const/__init__.py:330 const/__init__.py:336
#: const/__init__.py:342
msgid "exclude ignored tags"
-msgstr ""
+msgstr "إخÙاء المواضيع المستبعدة"
#: const/__init__.py:322 const/__init__.py:331 const/__init__.py:343
msgid "only interesting tags"
-msgstr ""
+msgstr "Ùقط المواضيع المهتم بها"
#: const/__init__.py:326 const/__init__.py:337 const/__init__.py:344
msgid "only subscribed tags"
-msgstr ""
+msgstr "Ùقط المواضيع المشترك بها"
#: const/__init__.py:329 const/__init__.py:335 const/__init__.py:341
msgid "email for all tags"
@@ -2902,23 +2903,23 @@ msgstr "لا بريد"
#: const/__init__.py:358
msgid "identicon"
-msgstr ""
+msgstr "identicon"
#: const/__init__.py:359
msgid "mystery-man"
-msgstr ""
+msgstr "mystery-man"
#: const/__init__.py:360
msgid "monsterid"
-msgstr ""
+msgstr "monsterid"
#: const/__init__.py:361
msgid "wavatar"
-msgstr ""
+msgstr "wavatar"
#: const/__init__.py:362
msgid "retro"
-msgstr ""
+msgstr "retro"
#: const/__init__.py:409 templates/badges.html:33
msgid "gold"
@@ -2938,43 +2939,43 @@ msgstr "لا شئ"
#: const/__init__.py:424
msgid "Gravatar"
-msgstr ""
+msgstr "Gravatar"
#: const/__init__.py:425
msgid "Uploaded Avatar"
-msgstr ""
+msgstr "رÙع صورة رمزية"
#: const/__init__.py:429
msgid "date descendant"
-msgstr ""
+msgstr "التاريخ المنحدر"
#: const/__init__.py:430
msgid "date ascendant"
-msgstr ""
+msgstr "التاريخ الصاعد"
#: const/__init__.py:431
msgid "activity descendant"
-msgstr ""
+msgstr "الأنشطة المنحدرة"
#: const/__init__.py:432
msgid "activity ascendant"
-msgstr ""
+msgstr "الأنشطة الصاعدة"
#: const/__init__.py:433
msgid "answers descendant"
-msgstr ""
+msgstr "الأجوبة المنحدرة"
#: const/__init__.py:434
msgid "answers ascendant"
-msgstr ""
+msgstr "الأجوبة الصاعدة"
#: const/__init__.py:435
msgid "votes descendant"
-msgstr ""
+msgstr "الأصوات المنحدرة"
#: const/__init__.py:436
msgid "votes ascendant"
-msgstr ""
+msgstr "الأصوات الصاعدة"
#: const/message_keys.py:21
msgid "most relevant questions"
@@ -2986,7 +2987,7 @@ msgstr "انقر لرؤية الأسئلة الأكثر ارتباطاً"
#: const/message_keys.py:23
msgid "by relevance"
-msgstr "بالإنتماء"
+msgstr "ذات الصلة"
#: const/message_keys.py:24
msgid "click to see the oldest questions"
@@ -2994,7 +2995,7 @@ msgstr "انقر لرؤية أقدم الأسئلة"
#: const/message_keys.py:25
msgid "by date"
-msgstr "بالتاريخ"
+msgstr "التاريخ"
#: const/message_keys.py:26
msgid "click to see the newest questions"
@@ -3002,15 +3003,15 @@ msgstr "انقر لرؤية أحدث الأسئلة"
#: const/message_keys.py:27
msgid "click to see the least recently updated questions"
-msgstr ""
+msgstr "أضغط لمشاهدة أقل الأسئلة تحديثاً"
#: const/message_keys.py:28
msgid "by activity"
-msgstr "بالنشاط"
+msgstr "النشاط"
#: const/message_keys.py:29
msgid "click to see the most recently updated questions"
-msgstr ""
+msgstr "أضغط لمشاهدة أحدث الأسئلة تحديثاً"
#: const/message_keys.py:30
msgid "click to see the least answered questions"
@@ -3018,7 +3019,7 @@ msgstr "انقر لرؤية الأسئلة الأقل إجابات"
#: const/message_keys.py:31
msgid "by answers"
-msgstr "بالإجابات"
+msgstr "الأجوبة"
#: const/message_keys.py:32
msgid "click to see the most answered questions"
@@ -3026,15 +3027,15 @@ msgstr "انقر لرؤية الأسئلة الأكثر إجابات"
#: const/message_keys.py:33
msgid "click to see least voted questions"
-msgstr ""
+msgstr "أضغط لمشاهدة أقل أسئلة حاصلة على أصوات"
#: const/message_keys.py:34
msgid "by votes"
-msgstr "بالأصوات"
+msgstr "الأصوات"
#: const/message_keys.py:35
msgid "click to see most voted questions"
-msgstr ""
+msgstr "أضغط لمشاهدة أكثر الأسئلة حاصلة على أصوات"
#: const/message_keys.py:36 models/tag.py:311
msgid "interesting"
@@ -3078,12 +3079,12 @@ msgstr ""
#: deps/django_authopenid/forms.py:112 deps/django_authopenid/views.py:206
msgid "i-names are not supported"
-msgstr ""
+msgstr "خدمة i-names غير مدعمة"
#: deps/django_authopenid/forms.py:236
#, python-format
msgid "Please enter your %(username_token)s"
-msgstr ""
+msgstr "يرجى إدخال %(username_token)s"
#: deps/django_authopenid/forms.py:262
msgid "Please, enter your user name"
@@ -3104,7 +3105,7 @@ msgstr "كلمات السر لم تتطابق"
#: deps/django_authopenid/forms.py:300
#, python-format
msgid "Please choose password > %(len)s characters"
-msgstr ""
+msgstr "يرجى إختيار كلمة مرور مكونة من %(len)s حر٠ورقم"
#: deps/django_authopenid/forms.py:338
msgid "Current password"
@@ -3114,7 +3115,7 @@ msgstr "كلمة السر الحالية"
msgid ""
"Old password is incorrect. Please enter the correct "
"password."
-msgstr ""
+msgstr "كلمة المرور القديمة غير صحيحة. يرجى إدخال كلمة المرور الصحيحة."
#: deps/django_authopenid/forms.py:399
msgid "Sorry, we don't have this email address in the database"
@@ -3126,7 +3127,7 @@ msgstr "اسم المستخدم (<i>مطلوب</i>)"
#: deps/django_authopenid/forms.py:455
msgid "sorry, there is no such user name"
-msgstr "عÙواً، لا يوجد اسم الدخول هذا"
+msgstr "لا يوجد أسم مستخدم!"
#: deps/django_authopenid/urls.py:14 deps/django_authopenid/urls.py:20
#: deps/django_authopenid/urls.py:23 setup_templates/settings.py:229
@@ -3135,7 +3136,7 @@ msgstr "signin/"
#: deps/django_authopenid/urls.py:15
msgid "widget/signin/"
-msgstr ""
+msgstr "widget/signin/"
#: deps/django_authopenid/urls.py:18
msgid "signout/"
@@ -3143,37 +3144,37 @@ msgstr "signout/"
#: deps/django_authopenid/urls.py:23
msgid "complete-oauth/"
-msgstr ""
+msgstr "complete-oauth/"
#: deps/django_authopenid/urls.py:32
msgid "register/"
-msgstr ""
+msgstr "register/"
#: deps/django_authopenid/urls.py:34
msgid "signup/"
-msgstr ""
+msgstr "signup/"
#: deps/django_authopenid/urls.py:38
msgid "logout/"
-msgstr ""
+msgstr "logout/"
#: deps/django_authopenid/urls.py:43
msgid "recover/"
-msgstr ""
+msgstr "recover/"
#: deps/django_authopenid/urls.py:45
msgid "verify-email/"
-msgstr ""
+msgstr "verify-email/"
#: deps/django_authopenid/util.py:379
#, python-format
msgid "%(site)s user name and password"
-msgstr ""
+msgstr "تسجيل دخول بعضوية %(site)s"
#: deps/django_authopenid/util.py:385 templates/authopenid/signin.html:117
#: templates/authopenid/widget_signin.html:120
msgid "Create a password-protected account"
-msgstr ""
+msgstr "تسجيل عضوية جديدة"
#: deps/django_authopenid/util.py:386
msgid "Change your password"
@@ -3185,77 +3186,77 @@ msgstr "الدخول بحساب Yahoo"
#: deps/django_authopenid/util.py:493
msgid "AOL screen name"
-msgstr ""
+msgstr "AOL screen name"
#: deps/django_authopenid/util.py:502
msgid "Sign in with LaunchPad"
-msgstr ""
+msgstr "Sign in with LaunchPad"
#: deps/django_authopenid/util.py:509
msgid "OpenID url"
-msgstr ""
+msgstr "OpenID url"
#: deps/django_authopenid/util.py:538
msgid "Flickr user name"
-msgstr ""
+msgstr "Flickr user name"
#: deps/django_authopenid/util.py:546
msgid "Technorati user name"
-msgstr ""
+msgstr "Technorati user name"
#: deps/django_authopenid/util.py:554
msgid "WordPress blog name"
-msgstr ""
+msgstr "WordPress blog name"
#: deps/django_authopenid/util.py:562
msgid "Blogger blog name"
-msgstr ""
+msgstr "Blogger blog name"
#: deps/django_authopenid/util.py:570
msgid "LiveJournal blog name"
-msgstr ""
+msgstr "LiveJournal blog name"
#: deps/django_authopenid/util.py:578
msgid "ClaimID user name"
-msgstr ""
+msgstr "ClaimID user name"
#: deps/django_authopenid/util.py:586
msgid "Vidoop user name"
-msgstr ""
+msgstr "Vidoop user name"
#: deps/django_authopenid/util.py:594
msgid "Verisign user name"
-msgstr ""
+msgstr "Verisign user name"
#: deps/django_authopenid/util.py:629
#, python-format
msgid "Change your %(provider)s password"
-msgstr ""
+msgstr "تغيير كلمة مرور %(provider)s "
#: deps/django_authopenid/util.py:633
#, python-format
msgid "Click to see if your %(provider)s signin still works for %(site_name)s"
-msgstr ""
+msgstr "أضغط لمعرÙØ© أن مازال %(provider)s يعمل ويمكنك تسجيل الدخول من خلاله ÙÙŠ %(site_name)s"
#: deps/django_authopenid/util.py:642
#, python-format
msgid "Create password for %(provider)s"
-msgstr ""
+msgstr "إنشاء كلمة مرور لـ %(provider)s"
#: deps/django_authopenid/util.py:646
#, python-format
msgid "Connect your %(provider)s account to %(site_name)s"
-msgstr ""
+msgstr "ربط %(provider)s بحسابك ÙÙŠ %(site_name)s"
#: deps/django_authopenid/util.py:655
#, python-format
msgid "Signin with %(provider)s user name and password"
-msgstr ""
+msgstr "تسجيل الدخول بأسم المستخدم وكلمة المرور بواسطة %(provider)s"
#: deps/django_authopenid/util.py:662
#, python-format
msgid "Sign in with your %(provider)s account"
-msgstr ""
+msgstr "سجيل دخول بحسابك ÙÙŠ %(provider)s"
#: deps/django_authopenid/views.py:213
#, python-format
@@ -3270,7 +3271,7 @@ msgstr ""
#: deps/django_authopenid/views.py:520
msgid "Your new password saved"
-msgstr ""
+msgstr "تم Ø­Ùظ كلمة المرور الجديدة"
#: deps/django_authopenid/views.py:568 deps/django_authopenid/views.py:583
#, python-format
@@ -3285,11 +3286,11 @@ msgstr ""
#: deps/django_authopenid/views.py:717
msgid "Please click any of the icons below to sign in"
-msgstr ""
+msgstr "يمكنك تسجيل الدخول بحسابك ÙÙŠ المواقع الإجتماعية"
#: deps/django_authopenid/views.py:719
msgid "Account recovery email sent"
-msgstr ""
+msgstr "تم إرسال بريد إستعادة الحساب"
#: deps/django_authopenid/views.py:722
msgid "Please add one or more login methods."
@@ -3297,7 +3298,7 @@ msgstr ""
#: deps/django_authopenid/views.py:724
msgid "If you wish, please add, remove or re-validate your login methods"
-msgstr ""
+msgstr "إدارة وسائل الدخول للحساب"
#: deps/django_authopenid/views.py:726
msgid "Please wait a second! Your account is recovered, but ..."
@@ -3305,12 +3306,12 @@ msgstr ""
#: deps/django_authopenid/views.py:728
msgid "Sorry, this account recovery key has expired or is invalid"
-msgstr ""
+msgstr "عذراً، Ù…Ùتاح إستعادة الحساب هذا قد أنتهى واصبح غير صالح"
#: deps/django_authopenid/views.py:801
#, python-format
msgid "Login method %(provider_name)s does not exist"
-msgstr ""
+msgstr "إمكانية الدخول عبر %(provider_name)s غير متاحة"
#: deps/django_authopenid/views.py:807
msgid "Oops, sorry - there was some error - please try again"
@@ -3336,15 +3337,15 @@ msgstr ""
#: deps/django_authopenid/views.py:1257
#, python-format
msgid "Recover your %(site)s account"
-msgstr ""
+msgstr "إستعادة حساب ÙÙŠ %(site)s"
#: deps/django_authopenid/views.py:1292
msgid "Please check your email and visit the enclosed link."
-msgstr ""
+msgstr "راجع بريدك، وأضغط على الرابط المرسل بالبريد."
#: deps/group_messaging/models.py:356
msgid "Re: "
-msgstr ""
+msgstr "رد:"
#: deps/livesettings/models.py:107 deps/livesettings/models.py:153
msgid "Site"
@@ -3352,37 +3353,37 @@ msgstr "الموقع"
#: deps/livesettings/values.py:72
msgid "Main"
-msgstr "الرئيسي"
+msgstr "Main"
#: deps/livesettings/values.py:133
msgid "Base Settings"
-msgstr ""
+msgstr "Base Settings"
#: deps/livesettings/values.py:244
msgid "Default value: \"\""
-msgstr ""
+msgstr "Default value: \"\""
#: deps/livesettings/values.py:251
msgid "Default value: "
-msgstr ""
+msgstr "Default value: "
#: deps/livesettings/values.py:254
#, python-format
msgid "Default value: %s"
-msgstr ""
+msgstr "Default value: %s"
#: deps/livesettings/values.py:641
#, python-format
msgid "Allowed image file types are %(types)s"
-msgstr ""
+msgstr "صيغ الصور المسموح بها: %(types)s"
#: importers/stackexchange/management/commands/load_stackexchange.py:150
msgid "Congratulations, you are now an Administrator"
-msgstr ""
+msgstr "تهانياً، أنت الأن مشر٠عام"
#: mail/__init__.py:183
msgid "<p>To ask by email, please:</p>"
-msgstr ""
+msgstr "<p>لطرح السؤال عبر البريد:</p>"
#: mail/__init__.py:185
msgid "<li>Type title in the subject line</li>"
@@ -3440,7 +3441,7 @@ msgstr ""
#: mail/lamson_handlers.py:251
#, python-format
msgid "Re: Welcome to %(site_name)s"
-msgstr ""
+msgstr "رد: مرحباً ÙÙŠ %(site_name)s"
#: mail/lamson_handlers.py:258
msgid "Please reply to the welcome email without editing it"
@@ -3458,11 +3459,11 @@ msgstr ""
#: management/commands/send_accept_answer_reminders.py:66
msgid "Please accept the best answer for this question:"
-msgstr ""
+msgstr "Ùضلاً أقبل Ø£Ùضل إجابة للسؤال:"
#: management/commands/send_accept_answer_reminders.py:68
msgid "Please accept the best answer for these questions:"
-msgstr ""
+msgstr "Ùضلاً إختار Ø£Ùضل إجابة لهذه الأسئلة:"
#: management/commands/send_email_alerts.py:434
#, python-format
@@ -3477,7 +3478,7 @@ msgstr[5] ""
#: management/commands/send_email_alerts.py:455
msgid "new question"
-msgstr ""
+msgstr "سؤال جديد"
#: management/commands/send_unanswered_question_reminders.py:67
#, python-format
@@ -3493,11 +3494,11 @@ msgstr[5] ""
#: middleware/forum_mode.py:63
#, python-format
msgid "Please log in to use %s"
-msgstr ""
+msgstr "سجل دخول لإستخدام %s"
#: models/__init__.py:569 models/__init__.py:1388 views/writers.py:226
msgid "Sorry, but you have only read access"
-msgstr ""
+msgstr "عذراً، لديك صلاحية القراءة Ùقط"
#: models/__init__.py:573
msgid "Sorry, this operation is not allowed"
@@ -3507,76 +3508,76 @@ msgstr ""
msgid ""
"Sorry, you cannot accept or unaccept best answers because your account is "
"blocked"
-msgstr ""
+msgstr "عذراً، لا يمكنك قبول او رÙض الإجابات لأن حسابك محجوب"
#: models/__init__.py:627
msgid ""
"Sorry, you cannot accept or unaccept best answers because your account is "
"suspended"
-msgstr ""
+msgstr "عذراً، لا يمكنك قبول او رÙض الإجابات لأن حسابك Ù…Ùصول"
#: models/__init__.py:641
#, python-format
msgid ""
">%(points)s points required to accept or unaccept your own answer to your "
"own question"
-msgstr ""
+msgstr ">%(points)s نقطة مطلوبة لقبول او رÙض إجابتك على سؤالك"
#: models/__init__.py:665
#, python-format
msgid ""
"Sorry, you will be able to accept this answer only after %(will_be_able_at)s"
-msgstr ""
+msgstr "سو٠تستطيع قبول هذه الإجابة بعد %(will_be_able_at)s"
#: models/__init__.py:674
#, python-format
msgid ""
"Sorry, only moderators or original author of the question - %(username)s - "
"can accept or unaccept the best answer"
-msgstr ""
+msgstr "Ùقط المشرÙين والكاتب الأصلي للسؤال - %(username)s - يستطيعون قبول او رÙض Ø£Ùضل إجابة"
#: models/__init__.py:697
msgid "Sorry, you cannot vote for your own posts"
-msgstr ""
+msgstr "لا يمكنك التصويت على مشاركتك!"
#: models/__init__.py:701
msgid "Sorry your account appears to be blocked "
-msgstr ""
+msgstr "عذراً، يبدو أن حسابك محجوب"
#: models/__init__.py:706
msgid "Sorry your account appears to be suspended "
-msgstr ""
+msgstr "عذراً، يبدو أن حسابك Ù…Ùصول"
#: models/__init__.py:716
#, python-format
msgid ">%(points)s points required to upvote"
-msgstr ""
+msgstr ">%(points)s نقطة مطلوبة لإعطاء أصوات إيجابية"
#: models/__init__.py:722
#, python-format
msgid ">%(points)s points required to downvote"
-msgstr ""
+msgstr ">%(points)s نقطة مطلوبة لإعطاء أصوات سلبية"
#: models/__init__.py:737
msgid "Sorry, blocked users cannot upload files"
-msgstr ""
+msgstr "عذراً، الأعضاء المحجوبين لا يمكنهم رÙع الملÙات"
#: models/__init__.py:738
msgid "Sorry, suspended users cannot upload files"
-msgstr ""
+msgstr "عذراً، الأعضاء المÙصولين لا يمكنهم رÙع الملÙات"
#: models/__init__.py:740
#, python-format
msgid "sorry, file uploading requires karma >%(min_rep)s"
-msgstr ""
+msgstr "لرÙع الملÙات يجب أن يكون لديك %(min_rep)s نقطة على الأقل"
#: models/__init__.py:759
msgid "Could not post, because your karma is insufficient to publish links"
-msgstr ""
+msgstr "لا يمكن نشر المشاركة، عدد نقاطك المكتسبة لا تسمح بعد بإضاÙØ© الروابط"
#: models/__init__.py:785
msgid "Sorry, you already gave an answer, please edit it instead."
-msgstr ""
+msgstr "لقد قمت أصلاً بإعطاء إجابة، Ùضلاً عدل إجابتك السابقة بدل نشر إجابة جديدة"
#: models/__init__.py:809
#, python-format
@@ -3595,12 +3596,12 @@ msgstr[5] ""
#: models/__init__.py:821
msgid "Sorry, but only post owners or moderators can edit comments"
-msgstr ""
+msgstr "Ùقط كتاب التعليقات والمشرÙين لهم صلاحية التعديل"
#: models/__init__.py:850
msgid ""
"Sorry, since your account is suspended you can comment only your own posts"
-msgstr ""
+msgstr "بسبب أن حسابك Ù…Ùصول يمكنك كتابة التعليقات على مشاركاتك Ùقط"
#: models/__init__.py:854
#, python-format
@@ -3613,35 +3614,35 @@ msgstr ""
msgid ""
"This post has been deleted and can be seen only by post owners, site "
"administrators and moderators"
-msgstr ""
+msgstr "هذه المشاركة محذوÙØ©ØŒ يمكن مشاهدة من قبل الكاتب الأصلي والمشرÙين Ùقط"
#: models/__init__.py:901
msgid ""
"Sorry, only moderators, site administrators and post owners can edit deleted"
" posts"
-msgstr ""
+msgstr "Ùقط الكاتب الأًصلي والمشرÙين يمكنهم تعديل المشاركات الحذوÙØ©"
#: models/__init__.py:917
msgid "Sorry, since your account is blocked you cannot edit posts"
-msgstr ""
+msgstr "بسبب أن حسابك محجوب لا يمكنك تعديل المشاركات"
#: models/__init__.py:921
msgid ""
"Sorry, since your account is suspended you can edit only your own posts"
-msgstr ""
+msgstr "بسبب أن حسابك Ù…Ùصول يمكنك Ùقط تعديل مشاركاتك"
#: models/__init__.py:926
#, python-format
msgid ""
"Sorry, to edit wiki posts, a minimum reputation of %(min_rep)s is required"
-msgstr ""
+msgstr "لتعديل مشاركات الويكي يجب ان يكون لديك على الأقل %(min_rep)s نقطة"
#: models/__init__.py:933
#, python-format
msgid ""
"Sorry, to edit other people's posts, a minimum reputation of %(min_rep)s is "
"required"
-msgstr ""
+msgstr "لتعديل مشاركات الغير يجب أن يكون لديك على الأقل %(min_rep)s نقطة"
#: models/__init__.py:996
msgid ""
@@ -3659,78 +3660,78 @@ msgstr[5] ""
#: models/__init__.py:1011
msgid "Sorry, since your account is blocked you cannot delete posts"
-msgstr ""
+msgstr "بسبب أن حسابك محجوب لا يمكنك حذ٠المشاركات"
#: models/__init__.py:1015
msgid ""
"Sorry, since your account is suspended you can delete only your own posts"
-msgstr ""
+msgstr "بسبب أن حسابك Ù…Ùصول يمكنك Ùقط تعديل مشاركاتك"
#: models/__init__.py:1019
#, python-format
msgid ""
"Sorry, to delete other people's posts, a minimum reputation of %(min_rep)s "
"is required"
-msgstr ""
+msgstr "لحذ٠مشاركات الغير يجب أن يكون لديك على الأقل %(min_rep)s نقطة"
#: models/__init__.py:1040
msgid "Sorry, since your account is blocked you cannot close questions"
-msgstr ""
+msgstr "بسبب أن حسابك محجوب لا يمكنك إغلاق الأسئلة"
#: models/__init__.py:1044
msgid "Sorry, since your account is suspended you cannot close questions"
-msgstr ""
+msgstr "بسبب أن حسابك Ù…Ùصول يمكنك إغلاق اسألتك Ùقط"
#: models/__init__.py:1048
#, python-format
msgid ""
"Sorry, to close other people' posts, a minimum reputation of %(min_rep)s is "
"required"
-msgstr ""
+msgstr "لإغلاق مشاركات الغير يجب أن يكون لديك على الاقل %(min_rep)s نقطة"
#: models/__init__.py:1057
#, python-format
msgid ""
"Sorry, to close own question a minimum reputation of %(min_rep)s is required"
-msgstr ""
+msgstr "لإغلاق أسالتك يجب أن يكون لديك على الأقل %(min_rep)s نقطة"
#: models/__init__.py:1084
#, python-format
msgid ""
"Sorry, only administrators, moderators or post owners with reputation > "
"%(min_rep)s can reopen questions."
-msgstr ""
+msgstr "Ùقط المشرÙين او الكاتب الأًصلي ÙÙŠ حالة كان لديه على الأقل %(min_rep)s نقطة يمكنهم إعادة Ùتح السؤال."
#: models/__init__.py:1090
#, python-format
msgid ""
"Sorry, to reopen own question a minimum reputation of %(min_rep)s is "
"required"
-msgstr ""
+msgstr "لإعادة Ùتح سؤالك يجب أن يكون لديك على الأقل %(min_rep)s نقطة"
#: models/__init__.py:1095
msgid "Sorry, you cannot reopen questions because your account is blocked"
-msgstr ""
+msgstr "بسبب أن حسابك محجوب لا يمكنك إعادة Ùتح السؤال"
#: models/__init__.py:1100
msgid "Sorry, you cannot reopen questions because your account is suspended"
-msgstr ""
+msgstr "بسبب أن حسابك Ù…Ùصول لا يمكنك إعادة Ùتح السؤال"
#: models/__init__.py:1123
msgid "You have flagged this question before and cannot do it more than once"
-msgstr ""
+msgstr "لقد قمت من قبل بالتبليغ على هذا السؤال، لا يمكنك التبليغ أكثر من مرة"
#: models/__init__.py:1131
msgid ""
"Sorry, since your account is blocked you cannot flag posts as offensive"
-msgstr ""
+msgstr "بسبب أن حسابك محجوب لا يمكنك التبليغ على المشاركات"
#: models/__init__.py:1142
#, python-format
msgid ""
"Sorry, to flag posts as offensive a minimum reputation of %(min_rep)s is "
"required"
-msgstr ""
+msgstr "للتبليغ على المشاركات يجب أن يكون لديك على الأقل %(min_rep)s نقطة"
#: models/__init__.py:1163
#, python-format
@@ -3745,13 +3746,13 @@ msgstr ""
#: models/__init__.py:1181
msgid "Sorry, since your account is blocked you cannot remove flags"
-msgstr ""
+msgstr "بسبب أن حسابك محجوب لا يمكنك إزالة التبليغات"
#: models/__init__.py:1185
msgid ""
"Sorry, your account appears to be suspended and you cannot remove flags. "
"Please contact the forum administrator to reach a resolution."
-msgstr ""
+msgstr "حسابك Ù…Ùصول لا يمكنك إزالة التبليغات، Ùضلاً راسل إدارة المجتمع"
#: models/__init__.py:1191
#, python-format
@@ -3767,50 +3768,50 @@ msgstr[5] ""
#: models/__init__.py:1210
msgid "you don't have the permission to remove all flags"
-msgstr ""
+msgstr "ليس لديك الصلاحية لإزالة كل التبليغات"
#: models/__init__.py:1211
msgid "no flags for this entry"
-msgstr ""
+msgstr "لا يوجد تبليغات على هذا المحتوى"
#: models/__init__.py:1235
msgid ""
"Sorry, only question owners, site administrators and moderators can retag "
"deleted questions"
-msgstr ""
+msgstr "Ùقط الكاتب الأصلي والمشرÙين لديهم صلاحية إعادة تعيين مواضيع السؤال المحذوÙ"
#: models/__init__.py:1243
msgid "Sorry, since your account is blocked you cannot retag questions"
-msgstr ""
+msgstr "بسبب أن حسابك محجوب لا يمكنك إعادة تعيين مواضيع السؤال"
#: models/__init__.py:1247
msgid ""
"Sorry, since your account is suspended you can retag only your own questions"
-msgstr ""
+msgstr "بسبب أن حسابك Ù…Ùصول يمكنك Ùقط إعادة تعيين مواضيع أسالتك"
#: models/__init__.py:1251
#, python-format
msgid ""
"Sorry, to retag questions a minimum reputation of %(min_rep)s is required"
-msgstr ""
+msgstr "لإعادة تعيين مواضيع السؤال يجب أن يكون لديك على الأقل %(min_rep)s نقطة"
#: models/__init__.py:1270
msgid "Sorry, since your account is blocked you cannot delete comment"
-msgstr ""
+msgstr "بسبب أن حسابك محجوب لا يمكنك حذ٠التعليق"
#: models/__init__.py:1274
msgid ""
"Sorry, since your account is suspended you can delete only your own comments"
-msgstr ""
+msgstr "بسب أن حسابك Ù…Ùصول يمكنك Ùقط حذ٠تعليقاتك"
#: models/__init__.py:1278
#, python-format
msgid "Sorry, to delete comments reputation of %(min_rep)s is required"
-msgstr ""
+msgstr "لحذ٠تعليق يجب أن يكون لديك على الأقل %(min_rep)s نقطة"
#: models/__init__.py:1303
msgid "sorry, but older votes cannot be revoked"
-msgstr ""
+msgstr "الأصوات القديمة لا يمكن التراجع عنها"
#: models/__init__.py:1995 utils/functions.py:98
#, python-format
@@ -3891,7 +3892,7 @@ msgstr "مستخدم مسجل"
#: models/__init__.py:2308
msgid "Watched User"
-msgstr ""
+msgstr "Watched"
#: models/__init__.py:2310
msgid "Approved User"
@@ -3900,7 +3901,7 @@ msgstr "مستخدم مقبول"
#: models/__init__.py:2495
#, python-format
msgid "%(username)s karma is %(reputation)s"
-msgstr "نقاط العضو %(username)s هي %(reputation)s"
+msgstr "سمعة %(username)s: %(reputation)s"
#: models/__init__.py:2508
#, python-format
@@ -3938,12 +3939,12 @@ msgstr[5] ""
#: models/__init__.py:2533
#, python-format
msgid "%(item1)s and %(item2)s"
-msgstr ""
+msgstr "%(item1)s Ùˆ %(item2)s"
#: models/__init__.py:2535
#, python-format
msgid "%(user)s has %(badges)s"
-msgstr ""
+msgstr "%(user)s لديه %(badges)s"
#: models/__init__.py:2682
#, python-format
@@ -3959,32 +3960,32 @@ msgstr[5] ""
#: models/__init__.py:3159
#, python-format
msgid "%(user)s shared a %(post_link)s."
-msgstr ""
+msgstr "%(user)s شارك %(post_link)s."
#: models/__init__.py:3162 models/__init__.py:3172
#, python-format
msgid "%(user)s edited a %(post_link)s."
-msgstr ""
+msgstr "%(user)s عدل %(post_link)s."
#: models/__init__.py:3164
#, python-format
msgid "%(user)s posted a %(post_link)s"
-msgstr ""
+msgstr "%(user)s نشر %(post_link)s"
#: models/__init__.py:3167
#, python-format
msgid "%(user)s edited an %(post_link)s."
-msgstr ""
+msgstr "%(user)s عدل %(post_link)s."
#: models/__init__.py:3169
#, python-format
msgid "%(user)s posted an %(post_link)s."
-msgstr ""
+msgstr "%(user)s نشر %(post_link)s."
#: models/__init__.py:3174
#, python-format
msgid "%(user)s posted a %(post_link)s."
-msgstr ""
+msgstr "%(user)s نشر %(post_link)s."
#: models/__init__.py:3190
msgid "To reply, PLEASE WRITE ABOVE THIS LINE."
@@ -3993,7 +3994,7 @@ msgstr ""
#: models/__init__.py:3232
#, python-format
msgid "\"%(title)s\""
-msgstr ""
+msgstr "\"%(title)s\""
#: models/__init__.py:3384
#, python-format
@@ -4005,7 +4006,7 @@ msgstr ""
#: models/__init__.py:3657
#, python-format
msgid "Welcome to %(site_name)s"
-msgstr ""
+msgstr "مرحباً ÙÙŠ %(site_name)s"
#: models/__init__.py:3678 views/commands.py:697
msgid "Your tag subscription was saved, thanks!"
@@ -4014,72 +4015,72 @@ msgstr ""
#: models/badges.py:129
#, python-format
msgid "Deleted own post with %(votes)s or more upvotes"
-msgstr ""
+msgstr "حذ٠مشاركتك مع وجود %(votes)s صوت إيجابي أو أكثر"
#: models/badges.py:133
msgid "Disciplined"
-msgstr ""
+msgstr "منضبط"
#: models/badges.py:151
#, python-format
msgid "Deleted own post with %(votes)s or more downvotes"
-msgstr ""
+msgstr "حذ٠مشاركتك مع وجود %(votes)s صوت سلبي أو أكثر"
#: models/badges.py:155
msgid "Peer Pressure"
-msgstr ""
+msgstr "مضغوط"
#: models/badges.py:174
#, python-format
msgid "Received at least %(votes)s upvote for an answer for the first time"
-msgstr ""
+msgstr "الحصول على أول %(votes)s صوت إيجابي لأحد الأجوبة"
#: models/badges.py:178
msgid "Teacher"
-msgstr ""
+msgstr "أستاذ"
#: models/badges.py:218
msgid "Supporter"
-msgstr ""
+msgstr "داعم"
#: models/badges.py:219
msgid "First upvote"
-msgstr ""
+msgstr "أول تصويت إيجابي"
#: models/badges.py:227
msgid "Critic"
-msgstr ""
+msgstr "ناقد"
#: models/badges.py:228
msgid "First downvote"
-msgstr ""
+msgstr "أول تصويت سلبي"
#: models/badges.py:237
msgid "Civic Duty"
-msgstr ""
+msgstr "مؤدي الواجب"
#: models/badges.py:238
#, python-format
msgid "Voted %(num)s times"
-msgstr ""
+msgstr "صوت %(num)s مرة"
#: models/badges.py:252
#, python-format
msgid "Answered own question with at least %(num)s up votes"
-msgstr ""
+msgstr "الإجابة على سؤالك مع على الأقل %(num)s صوت إيجابي"
#: models/badges.py:256
msgid "Self-Learner"
-msgstr ""
+msgstr "متعلم ذاتياً"
#: models/badges.py:304
msgid "Nice Answer"
-msgstr "إجابة رائعة"
+msgstr "إجابة جميلة"
#: models/badges.py:309 models/badges.py:321 models/badges.py:333
#, python-format
msgid "Answer voted up %(num)s times"
-msgstr ""
+msgstr "التصويت الإيجابي على الإجابة %(num)s مرة"
#: models/badges.py:316
msgid "Good Answer"
@@ -4087,7 +4088,7 @@ msgstr "إجابة جيدة"
#: models/badges.py:328
msgid "Great Answer"
-msgstr "إجابة عظيمة"
+msgstr "إجابة ممتازة"
#: models/badges.py:340
msgid "Nice Question"
@@ -4096,7 +4097,7 @@ msgstr "سؤال جميل"
#: models/badges.py:345 models/badges.py:357 models/badges.py:369
#, python-format
msgid "Question voted up %(num)s times"
-msgstr ""
+msgstr "التصويت الإيجابي على السؤال %(num)s مرة"
#: models/badges.py:352
msgid "Good Question"
@@ -4112,20 +4113,20 @@ msgstr "طالب"
#: models/badges.py:381
msgid "Asked first question with at least one up vote"
-msgstr ""
+msgstr "طرح أول سؤال مع وجود تصويت إيجابي واحد على الأقل"
#: models/badges.py:414
msgid "Popular Question"
-msgstr ""
+msgstr "سؤال شعبي"
#: models/badges.py:418 models/badges.py:429 models/badges.py:441
#, python-format
msgid "Asked a question with %(views)s views"
-msgstr ""
+msgstr "طرح سؤال مع %(views)s مشاهدة"
#: models/badges.py:425
msgid "Notable Question"
-msgstr ""
+msgstr "سؤال ملحوظ"
#: models/badges.py:436
msgid "Famous Question"
@@ -4133,157 +4134,157 @@ msgstr "سؤال مشهور"
#: models/badges.py:450
msgid "Asked a question and accepted an answer"
-msgstr ""
+msgstr "طرح سؤال وقبول إجابة"
#: models/badges.py:453
msgid "Scholar"
-msgstr ""
+msgstr "مثقÙ"
#: models/badges.py:495
msgid "Enlightened"
-msgstr ""
+msgstr "مستنير"
#: models/badges.py:499
#, python-format
msgid "First answer was accepted with %(num)s or more votes"
-msgstr ""
+msgstr "أول إجابة تم قبولها مع %(num)s صوت أو أكثر"
#: models/badges.py:507
msgid "Guru"
-msgstr ""
+msgstr "Ù…Ùعلم"
#: models/badges.py:510
#, python-format
msgid "Answer accepted with %(num)s or more votes"
-msgstr ""
+msgstr "إجابة تم قبولها مع %(num)s صوت أو أكثر"
#: models/badges.py:518
#, python-format
msgid ""
"Answered a question more than %(days)s days later with at least %(votes)s "
"votes"
-msgstr ""
+msgstr "الإجابة على سؤال بعد %(days)s يوم مع على الأقل وجود %(votes)s صوت"
#: models/badges.py:525
msgid "Necromancer"
-msgstr ""
+msgstr "قسم الأرشيÙ"
#: models/badges.py:548
msgid "Citizen Patrol"
-msgstr ""
+msgstr "قائد لجنة شعبية"
#: models/badges.py:551
msgid "First flagged post"
-msgstr ""
+msgstr "أول تبليغ على مشاركة"
#: models/badges.py:563
msgid "Cleanup"
-msgstr ""
+msgstr "تراجع"
#: models/badges.py:566
msgid "First rollback"
-msgstr ""
+msgstr "تراجع عن تصويت"
#: models/badges.py:577
msgid "Pundit"
-msgstr ""
+msgstr "ناقد إيجابي"
#: models/badges.py:580
msgid "Left 10 comments with score of 10 or more"
-msgstr ""
+msgstr "ترك 10 تعليقات مع 10 أصوات أو أكثر"
#: models/badges.py:612
msgid "Editor"
-msgstr ""
+msgstr "محرر"
#: models/badges.py:615
msgid "First edit"
-msgstr ""
+msgstr "أول تعديل"
#: models/badges.py:623
msgid "Associate Editor"
-msgstr ""
+msgstr "كبير المحررين"
#: models/badges.py:627
#, python-format
msgid "Edited %(num)s entries"
-msgstr ""
+msgstr "تعديل %(num)s مشاركة"
#: models/badges.py:634
msgid "Organizer"
-msgstr ""
+msgstr "شخص منظم"
#: models/badges.py:637
msgid "First retag"
-msgstr ""
+msgstr "أول إعادة تعيين مواضيع"
#: models/badges.py:644
msgid "Autobiographer"
-msgstr ""
+msgstr "شخص معروÙ"
#: models/badges.py:647
msgid "Completed all user profile fields"
-msgstr ""
+msgstr "إكمال جميع حقول المل٠الشخصي"
#: models/badges.py:663
#, python-format
msgid "Question favorited by %(num)s users"
-msgstr ""
+msgstr "تم تÙضيل السؤال من قبل %(num)s عضو"
#: models/badges.py:689
msgid "Stellar Question"
-msgstr ""
+msgstr "سؤال مهم"
#: models/badges.py:698
msgid "Favorite Question"
-msgstr ""
+msgstr "سؤال Ù…Ùضل"
#: models/badges.py:710
msgid "Enthusiast"
-msgstr ""
+msgstr "متحمس"
#: models/badges.py:714
#, python-format
msgid "Visited site every day for %(num)s days in a row"
-msgstr ""
+msgstr "زيارة الموقع كل يوم لمدة %(num)s أيام متتابعة"
#: models/badges.py:732
msgid "Commentator"
-msgstr ""
+msgstr "معلق"
#: models/badges.py:736
#, python-format
msgid "Posted %(num_comments)s comments"
-msgstr ""
+msgstr "نشر %(num_comments)s تعليقات"
#: models/badges.py:752
msgid "Taxonomist"
-msgstr ""
+msgstr "مصن٠المواضيع"
#: models/badges.py:756
#, python-format
msgid "Created a tag used by %(num)s questions"
-msgstr ""
+msgstr "إنشاء موضوع وتم إستخدامة ÙÙŠ %(num)s سؤال"
#: models/badges.py:774
msgid "Expert"
-msgstr ""
+msgstr "خبير متخصص"
#: models/badges.py:777
msgid "Very active in one tag"
-msgstr ""
+msgstr "نشط جداً ÙÙŠ موضوع واحد"
#: models/message.py:16
msgid "message"
-msgstr ""
+msgstr "رسالة"
#: models/post.py:414
msgid "Question: "
-msgstr ""
+msgstr "سؤال:"
#: models/post.py:416
msgid "Answer: "
-msgstr ""
+msgstr "جواب:"
#: models/post.py:1570
msgid "Sorry, this question has been deleted and is no longer accessible"
@@ -4336,7 +4337,7 @@ msgstr ""
#: models/question.py:108
#, python-format
msgid "\" and \"%s\""
-msgstr ""
+msgstr "\" Ùˆ \"%s\""
#: models/question.py:111
msgid "\" and more"
@@ -4370,15 +4371,15 @@ msgstr ""
#: models/reply_by_email.py:38
msgid "Post an answer"
-msgstr ""
+msgstr "نشر إجابة"
#: models/reply_by_email.py:39
msgid "Post a comment"
-msgstr ""
+msgstr "نشر تعليق"
#: models/reply_by_email.py:40
msgid "Edit post"
-msgstr ""
+msgstr "تعديل المشاركة"
#: models/reply_by_email.py:41
msgid "Append to post"
@@ -4403,7 +4404,7 @@ msgstr "التحرير بالبريد"
#: models/repute.py:207
#, python-format
msgid "<em>Changed by moderator. Reason:</em> %(reason)s"
-msgstr ""
+msgstr "<em>تم التعديل بواسطة المشرÙ. السبب:</em> %(reason)s"
#: models/repute.py:218
#, python-format
@@ -4430,11 +4431,11 @@ msgstr ""
#: models/user.py:317
msgid "Questions that I asked"
-msgstr ""
+msgstr "الأسئلة التي سألتها"
#: models/user.py:318
msgid "Questions that I answered"
-msgstr ""
+msgstr "أسئلة جاوبت عليها"
#: models/user.py:319
msgid "Individually selected questions"
@@ -4442,11 +4443,11 @@ msgstr ""
#: models/user.py:320
msgid "Mentions and comment responses"
-msgstr ""
+msgstr "التنبيهات والتعليقات"
#: models/user.py:323
msgid "Instantly"
-msgstr "Ùوري"
+msgstr "Ùوراً"
#: models/user.py:324
msgid "Daily"
@@ -4458,7 +4459,7 @@ msgstr "أسبوعي"
#: models/user.py:326
msgid "No email"
-msgstr "لا بريد"
+msgstr "بدون بريد"
#: models/user.py:566
msgid "Can join when they want"
@@ -4474,98 +4475,98 @@ msgstr ""
#: models/user.py:617
msgid "Please give a list of valid email addresses."
-msgstr ""
+msgstr "Please give a list of valid email addresses."
#: models/user.py:627
msgid "Please give a list of valid email domain names."
-msgstr ""
+msgstr "Please give a list of valid email domain names."
#: models/widgets.py:34
msgid "css for the widget"
-msgstr ""
+msgstr "css for the widget"
#: templates/404.html:3 templates/404.html.py:10
msgid "Page not found"
-msgstr ""
+msgstr "لم يتم العثور على الصÙحة"
#: templates/404.html:13
msgid "Sorry, could not find the page you requested."
-msgstr ""
+msgstr "عذراً، لم نجد الصÙحة المطلوبة."
#: templates/404.html:15
msgid "This might have happened for the following reasons:"
-msgstr ""
+msgstr "قد يكون هذا حصل للأسباب التالية:"
#: templates/404.html:17
msgid "this question or answer has been deleted;"
-msgstr ""
+msgstr "السؤال أو الإجابة تم حذÙها؛"
#: templates/404.html:18
msgid "url has error - please check it;"
-msgstr ""
+msgstr "الرابط يحتوي أخطاء - Ùضلاً تأكد؛"
#: templates/404.html:19
msgid ""
"the page you tried to visit is protected or you don't have sufficient "
"points, see"
-msgstr ""
+msgstr "الصÙحة التي تحاول طلبها تطلب صلاحيات خاصية او نقاط معينة، راجع"
#: templates/404.html:19 templates/widgets/footer.html:39
msgid "faq"
-msgstr "أسئلة شائعة"
+msgstr "أشئلة شائعة"
#: templates/404.html:20
msgid "if you believe this error 404 should not have occured, please"
-msgstr ""
+msgstr "إذا كنت متأكد ان الخطأ 404 يجب أن لا يظهر لك، Ùضلاً"
#: templates/404.html:21
msgid "report this problem"
-msgstr ""
+msgstr "بلغ عن هذه المشكلة"
#: templates/404.html:30 templates/500.html:11
msgid "back to previous page"
-msgstr ""
+msgstr "الرجوع للصÙحة السابقة"
#: templates/404.html:31 templates/widgets/scope_nav.html:17
msgid "see all questions"
-msgstr ""
+msgstr "مشاهدة جميع الأسئلة"
#: templates/404.html:32
msgid "see all tags"
-msgstr ""
+msgstr "مشاهدة جميع المواضيع"
#: templates/500.html:3 templates/500.html.py:5
msgid "Internal server error"
-msgstr ""
+msgstr "خطأ سيرÙر داخلي"
#: templates/500.html:8
msgid "system error log is recorded, error will be fixed as soon as possible"
-msgstr ""
+msgstr "تم تسجيل الخطأ ÙÙŠ السيرÙر، سو٠تتم المراجعة وإصلاح المشكلة ÙÙŠ أسرع وقت ممكن"
#: templates/500.html:9
msgid "please report the error to the site administrators if you wish"
-msgstr ""
+msgstr "Ùضلاً بلغ عن هذا الخطأ للمشر٠العام"
#: templates/500.html:12
msgid "see latest questions"
-msgstr ""
+msgstr "مشاهدة أخر الأسئلة"
#: templates/500.html:13
msgid "see tags"
-msgstr "أنظر العلامات"
+msgstr "مشاهدة المواضيع"
#: templates/answer_edit.html:4 templates/answer_edit.html.py:10
msgid "Edit answer"
-msgstr "تحرير الإجابة"
+msgstr "تعديل الإجابة"
#: templates/answer_edit.html:10 templates/question_edit.html:9
#: templates/question_retag.html:5 templates/revisions.html:7
msgid "back"
-msgstr ""
+msgstr "رجوع"
#: templates/answer_edit.html:41 templates/question_edit.html:61
msgid "Save edit"
-msgstr "Ø­Ùظ التحرير"
+msgstr "Ø­Ùظ التعديلات"
#: templates/answer_edit.html:46 templates/close.html:16
#: templates/feedback.html:64 templates/question_edit.html:62
@@ -4584,23 +4585,23 @@ msgstr "إلغاء"
#: templates/question/javascript.html:72 templates/question/javascript.html:75
#: templates/widgets/edit_post.html:73
msgid "hide preview"
-msgstr ""
+msgstr "إخÙاء العرض المسبق"
#: templates/answer_edit.html:89 templates/ask.html:84
#: templates/question_edit.html:103 templates/question/javascript.html:75
msgid "show preview"
-msgstr "معاينة"
+msgstr "مشاهدة العرض المسبق"
#: templates/ask.html:4 templates/widgets/ask_button.html:9
#: templates/widgets/ask_form.html:67
msgid "Ask Your Question"
-msgstr "أسأل"
+msgstr "أطرح سؤالك"
#: templates/ask.html:21
msgid ""
"since you are not logged in right now, you will be asked to sign in or "
"register after posting your question"
-msgstr ""
+msgstr "كونك غير مسجل دخول حالياً، سو٠يطلب منك تسجيل الدخول أو التسجيل بعد كتابة سؤالك"
#: templates/ask.html:25
#, python-format
@@ -4613,22 +4614,22 @@ msgstr ""
#: templates/ask.html:29
msgid "please, try to make your question interesting to this community"
-msgstr ""
+msgstr "Ùضلاً، أجعل سؤال مهم ومÙيد للمجتمع لتحصل على Ø£Ùضل تÙاعل"
#: templates/ask.html:30 templates/widgets/answer_edit_tips.html:12
#: templates/widgets/question_edit_tips.html:8
msgid "provide enough details"
-msgstr "قم بتوÙير ما يكÙÙŠ من التÙاصيل"
+msgstr "ÙˆÙر تÙاصيل قدر الأمكان، حتى لا نظطر لسؤالك عنها وبالتالي يضيع وقت الطرÙين"
#: templates/ask.html:31 templates/widgets/answer_edit_tips.html:15
#: templates/widgets/question_edit_tips.html:11
msgid "be clear and concise"
-msgstr "كن واضح و موجز"
+msgstr "كن واضح وأستخدم لغة نضيÙØ© خالية من الأخطاء، واهتم جيداً بالتنسيق العام"
#: templates/ask.html:36 templates/widgets/answer_edit_tips.html:20
#: templates/widgets/question_edit_tips.html:16
msgid "see frequently asked questions"
-msgstr "أنظر الأسئلة الشائعة"
+msgstr "شاهد الأسئلة الشائعة"
#: templates/ask.html:36 templates/faq_static.html:3
#: templates/faq_static.html.py:5 templates/widgets/answer_edit_tips.html:20
@@ -4645,12 +4646,12 @@ msgstr "%(name)s"
#: templates/badge.html:5
msgid "Badge"
-msgstr "الشارة"
+msgstr "وسام"
#: templates/badge.html:7
#, python-format
msgid "Badge \"%(name)s\""
-msgstr "شارة \"%(name)s\""
+msgstr "الوسام \"%(name)s\""
#: templates/badge.html:9 templates/user_profile/user_recent.html:16
#: templates/user_profile/user_stats.html:71
@@ -4670,21 +4671,21 @@ msgstr[5] ""
#: templates/badges.html:3 templates/badges.html.py:5
msgid "Badges"
-msgstr "شارات"
+msgstr "الأوسمة"
#: templates/badges.html:7
msgid "Community gives you awards for your questions, answers and votes."
-msgstr ""
+msgstr "يتم تكريم الأعضاء المساهمين ÙÙŠ هذا المجتمع من خلال الأوسمة، ويحصل العضو على الأوسمة بناء على مشاركاتة ÙÙŠ طرح الأسئلة، الأجوبة والتصويت على المحتوى الجيد والسيء."
#: templates/badges.html:8
msgid ""
"Below is the list of available badges and number of times each type of badge"
" has been awarded."
-msgstr ""
+msgstr "ÙÙŠ الأسÙÙ„ تجد قائمة الأوسمة المتاحة حالياً، مع ذكر شرط الحصول على كل وسام، بالإضاÙØ© لعدد مرات حصول الأعضاء لكل وسام."
#: templates/badges.html:31
msgid "Community badges"
-msgstr ""
+msgstr "رتب الأوسمة"
#: templates/badges.html:33
msgid "gold badge: the highest honor and is very rare"
@@ -4694,29 +4695,29 @@ msgstr ""
msgid ""
"Gold badge is the highest award in this community. To obtain it you have to show \n"
"profound knowledge and ability in addition to your active participation."
-msgstr ""
+msgstr "الوسام الذهبي: هو أعلى وأرقى مستويات التكريم ÙÙŠ مجتمع ServerHang. للحصول عليها لا بد من أن يثبت الشخص مستوى خبرتة الكبيرة من خلال المساهمة بمحتوى Ùريد وخاص ومن خلال مساعدة الأعضاء."
#: templates/badges.html:42 templates/badges.html.py:46
msgid ""
"silver badge: occasionally awarded for the very high quality contributions"
-msgstr ""
+msgstr "الوسام الÙضي: هو الدرجة الثانية من مستويات التكريم، ويكرم بها المساهمين الجادين والذين يخصصون وقت من يومهم لمساعدة الآخرين."
#: templates/badges.html:49 templates/badges.html.py:53
msgid "bronze badge: often given as a special honor"
-msgstr ""
+msgstr "الوسام البرونزي: هو أول مستويات التكريم على مساهمتك ÙÙŠ بناء هذا المجتمع، وعلى الÙائدة التي تقدمها للمجتمع."
#: templates/base.html:23
#, python-format
msgid "RSS feed from %(site_title)s"
-msgstr ""
+msgstr "خلاصات RSS لموقع %(site_title)s"
#: templates/close.html:3 templates/close.html.py:5
msgid "Close question"
-msgstr "إغلاق سؤال"
+msgstr "إغلاق السؤال"
#: templates/close.html:6
msgid "Close the question"
-msgstr "إغلاق السؤال"
+msgstr "إغلاق هذا السؤال"
#: templates/close.html:11
msgid "Reasons"
@@ -4724,41 +4725,41 @@ msgstr "الأسباب"
#: templates/close.html:15
msgid "OK to close"
-msgstr "تم، و أغلق"
+msgstr "نعم للإغلاق"
#: templates/faq_static.html:5
msgid "Frequently Asked Questions "
-msgstr ""
+msgstr "الأسئلة الأكثر شيوعاً"
#: templates/faq_static.html:6
msgid "What kinds of questions can I ask here?"
-msgstr ""
+msgstr "ما نوع الأسئلة التي أستطيع طرحها هنا؟"
#: templates/faq_static.html:7
msgid ""
"Most importantly - questions should be <strong>relevant</strong> to this "
"community."
-msgstr ""
+msgstr "أهم أمر - يجب ان تكون الأسئلة <strong>ذات صلة</strong> بموضوع المجتمع."
#: templates/faq_static.html:8
msgid ""
"Before you ask - please make sure to search for a similar question. You can "
"search questions by their title or tags."
-msgstr ""
+msgstr "قبل أن تسأل - أبحث جيداً عن سؤالك، يمكنك البحث عن الأسئلة بواسطة العنوان أو الموضوع. لا داعي للمحتوى المكرر."
#: templates/faq_static.html:10
msgid "What kinds of questions should be avoided?"
-msgstr ""
+msgstr "مانوع الأسئلة التي علي تجنبها؟"
#: templates/faq_static.html:11
msgid ""
"Please avoid asking questions that are not relevant to this community, too "
"subjective and argumentative."
-msgstr ""
+msgstr "تجنب طرح الأسئلة الغير الخارجة عن نطاق تخصص المجتمع، ايضاً تجنب الأسئلة الجدلية التي لا يمكن ان تكون عبارة عن سؤال وجواب بل تطلب النقاش والأخذ والعطاء بالكلام، هذا النوع من المحتوى يحذ٠Ùوراً كونه غير متناسب مع آلية عمل المجتمع هذا."
#: templates/faq_static.html:13
msgid "What should I avoid in my answers?"
-msgstr ""
+msgstr "ماذا علي أن أتجنب ÙÙŠ أجوبتي؟"
#: templates/faq_static.html:14
msgid ""
@@ -4766,29 +4767,29 @@ msgid ""
"discussion group</strong>. Please avoid holding debates in your answers as "
"they tend to dilute the essense of questions and answers. For the brief "
"discussions please use commenting facility."
-msgstr ""
+msgstr "is a <strong>question and answer</strong> site - <strong>it is not a discussion group</strong>. Please avoid holding debates in your answers as they tend to dilute the essense of questions and answers. For the brief discussions please use commenting facility."
#: templates/faq_static.html:15
msgid "Who moderates this community?"
-msgstr ""
+msgstr "من إدارة ومشرÙين هذا المجتمع؟"
#: templates/faq_static.html:16
msgid "The short answer is: <strong>you</strong>."
-msgstr ""
+msgstr "بشكل بسيط <strong>أنــت</strong>."
#: templates/faq_static.html:17
msgid "This website is moderated by the users."
-msgstr ""
+msgstr "هذا الموقع يدار من قبل الأعضاء المسجلين."
#: templates/faq_static.html:18
msgid ""
"Karma system allows users to earn rights to perform a variety of moderation "
"tasks"
-msgstr ""
+msgstr "نظام النقاط والسمعة يسمح للأعضاء بالحصول على صلاحيات أشراÙية تمكنهم من إدارة الموقع"
#: templates/faq_static.html:20
msgid "How does karma system work?"
-msgstr ""
+msgstr "كي٠يعمل نظام النقاط والسمعة؟"
#: templates/faq_static.html:21
msgid ""
@@ -4796,7 +4797,7 @@ msgid ""
"some points, which are called \\\"karma points\\\". These points serve as a "
"rough measure of the community trust to him/her. Various moderation tasks "
"are gradually assigned to the users based on those points."
-msgstr ""
+msgstr "When a question or answer is upvoted, the user who posted them will gain some points, which are called \\\"karma points\\\". These points serve as a rough measure of the community trust to him/her. Various moderation tasks are gradually assigned to the users based on those points."
#: templates/faq_static.html:22
#, python-format
@@ -4810,39 +4811,39 @@ msgid ""
"points that can be accumulated for a question or answer per day. The table "
"below explains reputation point requirements for each type of moderation "
"task."
-msgstr ""
+msgstr "For example, if you ask an interesting question or give a helpful answer, your input will be upvoted. On the other hand if the answer is misleading - it will be downvoted. Each vote in favor will generate <strong>%(REP_GAIN_FOR_RECEIVING_UPVOTE)s</strong> points, each vote against will subtract <strong>%(REP_LOSS_FOR_RECEIVING_DOWNVOTE)s</strong> points. There is a limit of <strong>%(MAX_REP_GAIN_PER_USER_PER_DAY)s</strong> points that can be accumulated for a question or answer per day. The table below explains reputation point requirements for each type of moderation task."
#: templates/faq_static.html:32 templates/user_profile/user_votes.html:14
msgid "upvote"
-msgstr ""
+msgstr "تصويت إيجابي"
#: templates/faq_static.html:37
msgid "add comments"
-msgstr "أض٠تعليقات"
+msgstr "إضاÙØ© تعليقات"
#: templates/faq_static.html:42 templates/user_profile/user_votes.html:16
msgid "downvote"
-msgstr ""
+msgstr "تصويت سلبي"
#: templates/faq_static.html:45
msgid " accept own answer to own questions"
-msgstr ""
+msgstr "قبول إجابتك على سؤالك"
#: templates/faq_static.html:49
msgid "open and close own questions"
-msgstr ""
+msgstr "Ùتح وإغلاق الأسئلة الخاصة"
#: templates/faq_static.html:53
msgid "retag other's questions"
-msgstr ""
+msgstr "إعادة تعيين مواضيع أسئلة الغير"
#: templates/faq_static.html:58
msgid "edit community wiki questions"
-msgstr ""
+msgstr "تعديل أسئلة الويكي"
#: templates/faq_static.html:63
msgid "edit any answer"
-msgstr "تحرير أي إجابة"
+msgstr "تعديل أي إجابة"
#: templates/faq_static.html:67
msgid "delete any comment"
@@ -4850,7 +4851,7 @@ msgstr "حذ٠أي تعليق"
#: templates/faq_static.html:71
msgid "How to change my picture (gravatar) and what is gravatar?"
-msgstr ""
+msgstr "كي٠يمكنني تغيير صورتي الرمزية، وماهي خدمة gravatar ؟"
#: templates/faq_static.html:72
msgid ""
@@ -4868,59 +4869,59 @@ msgid ""
"href='http://gravatar.com'><strong>gravatar.com</strong></a> (just please be"
" sure to use the same email address that you used to register with us). "
"Default image that looks like a kitchen tile is generated automatically.</p>"
-msgstr ""
+msgstr "<p>The picture that appears on the users profiles is called <strong>gravatar</strong> (which means <strong>g</strong>lobally <strong>r</strong>ecognized <strong>avatar</strong>).</p><p>Here is how it works: a <strong>cryptographic key</strong> (unbreakable code) is calculated from your email address. You upload your picture (or your favorite alter ego image) the website <a href='http://gravatar.com'><strong>gravatar.com</strong></a> from where we later retreive your image using the key.</p><p>This way all the websites you trust can show your image next to your posts and your email address remains private.</p><p>Please <strong>personalize your account</strong> with an image - just register at <a href='http://gravatar.com'><strong>gravatar.com</strong></a> (just please be sure to use the same email address that you used to register with us). Default image that looks like a kitchen tile is generated automatically.</p>"
#: templates/faq_static.html:73
msgid "To register, do I need to create new password?"
-msgstr ""
+msgstr "To register, do I need to create new password?"
#: templates/faq_static.html:74
msgid ""
"No, you don't have to. You can login through any service that supports "
"OpenID, e.g. Google, Yahoo, AOL, etc."
-msgstr ""
+msgstr "No, you don't have to. You can login through any service that supports OpenID, e.g. Google, Yahoo, AOL, etc."
#: templates/faq_static.html:75
msgid "\"Login now!\""
-msgstr ""
+msgstr "\"سجل دخول\""
#: templates/faq_static.html:77
msgid "Why other people can edit my questions/answers?"
-msgstr ""
+msgstr "لماذا يستطيع الأخرين تعديل أسألتي وأجوبتي؟"
#: templates/faq_static.html:78
msgid "Goal of this site is..."
-msgstr "الهد٠من هذا الموقع..."
+msgstr "هد٠هذا الموقع هو..."
#: templates/faq_static.html:78
msgid ""
"So questions and answers can be edited like wiki pages by experienced users "
"of this site and this improves the overall quality of the knowledge base "
"content."
-msgstr ""
+msgstr "So questions and answers can be edited like wiki pages by experienced users of this site and this improves the overall quality of the knowledge base content."
#: templates/faq_static.html:79
msgid "If this approach is not for you, we respect your choice."
-msgstr ""
+msgstr "If this approach is not for you, we respect your choice."
#: templates/faq_static.html:81
msgid "Still have questions?"
-msgstr ""
+msgstr "مازال لديك أسئلة؟"
#: templates/faq_static.html:82
#, python-format
msgid ""
"Please <a href='%(ask_question_url)s'>ask</a> your question, help make our "
"community better!"
-msgstr ""
+msgstr "Please <a href='%(ask_question_url)s'>ask</a> your question, help make our community better!"
#: templates/feedback.html:3
msgid "Feedback"
-msgstr "رأيك"
+msgstr "مقترحات"
#: templates/feedback.html:5
msgid "Give us your feedback!"
-msgstr ""
+msgstr "ماذا لديك من مقترحات لتطوير هذا المجتمع؟"
#: templates/feedback.html:14
#, python-format
@@ -4937,59 +4938,59 @@ msgid ""
" <span class='big strong'>Dear visitor</span>, we look forward to hearing your feedback.\n"
" Please type and send us your message below.\n"
" "
-msgstr ""
+msgstr "\n <span class='big strong'>عزيزي الزائر</span>, الموقع هذا يعمل كمجتمع يقوم على اعضاءة والÙائدة التي يقدمونها للغير.\n ان كان لديك أي مقترحات لتطوير المجتمع هذا، أستخدم نموذج المراسلة هذا.\n "
#: templates/feedback.html:30
msgid "(to hear from us please enter a valid email or check the box below)"
-msgstr ""
+msgstr "(لنتمكن من الرد عليك، يرجى إستخدام بريد حقيقي)"
#: templates/feedback.html:37 templates/feedback.html.py:46
msgid "(this field is required)"
-msgstr "(حقل مطلوب)"
+msgstr "(هذا الحقل مطلوب)"
#: templates/feedback.html:55
msgid "(Please solve the captcha)"
-msgstr "(من Ùضلك أكتب الحرو٠بشكل صحيح)"
+msgstr "(يرجى حل الكاباتشا)"
#: templates/feedback.html:63
msgid "Send Feedback"
-msgstr "إبداء رأيك"
+msgstr "إرسال المقترحات"
#: templates/groups.html:3 templates/groups.html.py:6
#: templates/question/sidebar.html:108
#: templates/tags/list_bulk_tag_subscription.html:15
msgid "Groups"
-msgstr ""
+msgstr "المجموعات"
#: templates/groups.html:11
msgid "All groups"
-msgstr ""
+msgstr "كل المجمعات"
#: templates/groups.html:13
msgid "all groups"
-msgstr ""
+msgstr "كل المجموعات"
#: templates/groups.html:15
msgid "My groups"
-msgstr ""
+msgstr "مجموعاتي"
#: templates/groups.html:17
msgid "my groups"
-msgstr ""
+msgstr "مجموعات"
#: templates/groups.html:25
msgid ""
"Tip: to create a new group - please go to some user profile and add the new "
"group there. That user will be the first member of the group"
-msgstr ""
+msgstr "Tip: to create a new group - please go to some user profile and add the new group there. That user will be the first member of the group"
#: templates/groups.html:30
msgid "Group"
-msgstr ""
+msgstr "مجموعة"
#: templates/groups.html:31
msgid "Number of members"
-msgstr ""
+msgstr "عدد الأعضاء"
#: templates/help.html:2 templates/help.html.py:4
msgid "Help"
@@ -5002,120 +5003,120 @@ msgstr "مرحباً %(username)s،"
#: templates/help.html:9
msgid "Welcome,"
-msgstr "مرحبا،"
+msgstr "مرحباً،"
#: templates/help.html:13
#, python-format
msgid "Thank you for using %(app_name)s, here is how it works."
-msgstr ""
+msgstr "شكراً لإستخدامك %(app_name)s، أليك كي٠يعمل المجتمع."
#: templates/help.html:16
msgid "How questions, answers and comments work"
-msgstr ""
+msgstr "كي٠تعمل الأسئلة، الأجوبة والتعليقات"
#: templates/help.html:18
msgid ""
"This site is for asking and answering questions, not for open-ended "
"discussions."
-msgstr ""
+msgstr "هذا المجتمع لطرح الأسئلة والإجابة عليها، وليس Ù„Ùتح النقاشات التي لا نهاية لها."
#: templates/help.html:19
msgid ""
"We encourage everyone to use “question†space for asking and “answer†for "
"answering."
-msgstr ""
+msgstr "نحن ننتظر من الجميع إستخدام مساحة “السؤال†لطرح الأسئلة ومساحة “الإجابة†للإجابة على هذه الأسئلة."
#: templates/help.html:22
msgid ""
"Despite that, each question and answer can be commented – \n"
" the comments are good for the limited discussions."
-msgstr ""
+msgstr "بالإضاÙØ© لهذا، يمكن إستخدام خاصية التعليقات على السؤال او الإجابة Ù„Ùتح نقاش ضيق وقصير حول محتوى السؤال او الإجابة Ù†Ùسها لا غير."
#: templates/help.html:26
msgid "Please search before asking your questions"
-msgstr ""
+msgstr "يرجى البحث والبحث قبل طرح أي سؤال بالمجتمع"
#: templates/help.html:27
msgid ""
"Type your question in the search bar and see whether a similar question has "
"been asked before"
-msgstr ""
+msgstr "أستخدم حقل البحث للبحث عن سؤالك أو المواضيع المتعلقة به، وحاول تغيير الكلمات المستخدمة عدة مرات إذا لم تصل للسؤال من أول مرة، لا داعي لوجود أسئلة متكررة، علماً أن الأسئلة المكررة يتم حذÙها Ùوراً."
#: templates/help.html:29
msgid "Search has advanced capabilities:"
-msgstr ""
+msgstr "نظام البحث يحتوي على خصائص متقدمة:"
#: templates/help.html:31
msgid "to search in title - enter [title: your text]"
-msgstr ""
+msgstr "للبحث ÙÙŠ عناوين الأسئلة Ùقط استخدم: [title: your text]"
#: templates/help.html:32
msgid "to search by tags - enter [tag: sometag] or #sometag"
-msgstr ""
+msgstr "للحبث عن المواضيع مثلا عن linux أستخدم: #linux"
#: templates/help.html:33
msgid "to search by user - enter [user: somename] or @somename or @\"some name\""
-msgstr ""
+msgstr "للبحث عن عضو مثلا mustafa أستخدم: @mustafa"
#: templates/help.html:35
msgid ""
"In addition, it is possible to click on tags to add them to the search "
"query."
-msgstr ""
+msgstr "كما يمكنك الضغط على احدى المواضيع للبحث عن الأسئلة المتعلقة بها."
#: templates/help.html:37
msgid ""
"Finally, a separate tag search box is available in the side bar of the main "
"page, where the search tags can be entered as well"
-msgstr ""
+msgstr "Finally, a separate tag search box is available in the side bar of the main page, where the search tags can be entered as well"
#: templates/help.html:40
msgid ""
"<em>Important!!!</em> All search terms are combined with a logical \"AND\" "
"expression - to narrow the search by adding new terms."
-msgstr ""
+msgstr "<em>هام</em>ØŒ نظام البحث يعتمد على المنطق، لهذا حاول ان تقلل الكلمات المستخدمة بالبحث واستخدم الدقة لتصل لأÙضل نتيجة."
#: templates/help.html:42
msgid "Voting"
-msgstr ""
+msgstr "التصويت"
#: templates/help.html:44
#, python-format
msgid ""
"Voting in %(app_name)s helps to select best answers and thank most helpful "
"users."
-msgstr ""
+msgstr "التصويت ÙÙŠ %(app_name)s يساعد على برز المحتوى الجيد للغير وطمر محتوى السيء عنهم، ويساعد على تحديد Ø£Ùضل إجابة لكل سؤال ليكون الوصول للمعلومة الصحيحة أسرع، "
#: templates/help.html:47
#, python-format
msgid ""
"Please vote when you find helpful information,\n"
" it really helps the %(app_name)s community."
-msgstr ""
+msgstr "Ùضلاً صوت عندما تجد معلومات Ù…Ùيدة، وتجنب التصويت الإيجابي او السلبي بناء على المجاملات والأصدقاء Ùهذا يقلل من سمعتك بالموقع ويقل من قوة محتوى مجتمع %(app_name)s."
#: templates/help.html:51
msgid "Other topics"
-msgstr ""
+msgstr "أمور أخرى"
#: templates/help.html:53
msgid ""
"You can @mention users anywhere in the text to point their attention,\n"
" follow users and conversations and report inappropriate content by flagging it."
-msgstr ""
+msgstr "يمكنك متابعة أعضاء المجتمع عن طريق زيارة مل٠العضو الشخصي والضغط على زر متابعة، نظام المتابعة يمكنك من متابعة أنشطة ومشاركات الأعضاء المهمين بالنسبة لك.\nكما يمكنك أستخدام خاصية Ù„Ùت الإنتباه لعضو معين بداخل الأسئلة، الإجابات والتعليقات عن طريق إستخدام @username (أستبدل username بأسم المستخدم للعضو المطلوب تنبيهه)."
#: templates/help.html:56
msgid "Enjoy."
-msgstr ""
+msgstr "الآن يمكنك الإنطلاق بهذا المجتمع لتبدأ وتعمل ÙˆÙÙ‚ مبدأ Ùيد وأستÙيد، Ùهذا هد٠مجتمع ServerHang. شكراً لك على القراءة. "
#: templates/import_data.html:2 templates/import_data.html.py:4
msgid "Import StackExchange data"
-msgstr ""
+msgstr "Import StackExchange data"
#: templates/import_data.html:13
msgid ""
"<em>Warning:</em> if your database is not empty, please back it up\n"
" before attempting this operation."
-msgstr ""
+msgstr "<em>Warning:</em> if your database is not empty, please back it up\n before attempting this operation."
#: templates/import_data.html:16
msgid ""
@@ -5123,21 +5124,21 @@ msgid ""
" the data import completes. This process may take several minutes.\n"
" Please note that feedback will be printed in plain text.\n"
" "
-msgstr ""
+msgstr "Upload your stackexchange dump .zip file, then wait until\n the data import completes. This process may take several minutes.\n Please note that feedback will be printed in plain text.\n "
#: templates/import_data.html:25
msgid "Import data"
-msgstr "إستيراد بيانات"
+msgstr "Import data"
#: templates/import_data.html:27
msgid ""
"In the case you experience any difficulties in using this import tool,\n"
" please try importing your data via command line: <code>python manage.py load_stackexchange path/to/your-data.zip</code>"
-msgstr ""
+msgstr "In the case you experience any difficulties in using this import tool,\n please try importing your data via command line: <code>python manage.py load_stackexchange path/to/your-data.zip</code>"
#: templates/list_suggested_tags.html:11
msgid "Tag"
-msgstr ""
+msgstr "موضوع"
#: templates/list_suggested_tags.html:12
msgid "Suggested by"
@@ -5153,11 +5154,11 @@ msgstr ""
#: templates/list_suggested_tags.html:34 templates/list_suggested_tags.html:45
msgid "Accept"
-msgstr ""
+msgstr "قبول"
#: templates/list_suggested_tags.html:35 templates/list_suggested_tags.html:46
msgid "Reject"
-msgstr ""
+msgstr "رÙض"
#: templates/list_suggested_tags.html:38
msgid "There are no questions with this tag yet"
@@ -5175,7 +5176,7 @@ msgstr ""
#: templates/list_suggested_tags.html:71 templates/tags/content.html:5
#: templates/tags/content.html.py:31
msgid "Nothing found"
-msgstr "لم يعثر علي شئ"
+msgstr "لم يتم العثور على شيء"
#: templates/macros.html:5
#, python-format
@@ -5184,23 +5185,23 @@ msgstr ""
#: templates/macros.html:44
msgid "current number of votes"
-msgstr "عدد الأصوات الحالي"
+msgstr "عدد الأصوات حالياً"
#: templates/macros.html:57
msgid "anonymous user"
-msgstr "مستخدم مجهول"
+msgstr "عضو مجهول"
#: templates/macros.html:91 templates/macros.html.py:110
msgid "asked"
-msgstr ""
+msgstr "سأل"
#: templates/macros.html:93 templates/macros.html.py:112
msgid "answered"
-msgstr "مجاب"
+msgstr "أجاب"
#: templates/macros.html:95 templates/macros.html.py:114
msgid "posted"
-msgstr ""
+msgstr "نشر"
#: templates/macros.html:101
msgid "this post is marked as community wiki"
@@ -5211,20 +5212,20 @@ msgstr ""
msgid ""
"This post is a wiki.\n"
" Anyone with karma &gt;%(wiki_min_rep)s is welcome to improve it."
-msgstr ""
+msgstr "هذه المشاركة ويكي.\n أي عضو مع قوة سمعة +%(wiki_min_rep)s بإمكانة تحسين المحتوى."
#: templates/macros.html:146
msgid "updated"
-msgstr ""
+msgstr "حدث"
#: templates/macros.html:261 templates/macros.html.py:267
msgid "Leave this group"
-msgstr ""
+msgstr "ترك هذه المجموعة"
#: templates/macros.html:262 templates/macros.html.py:264
#: templates/macros.html:283
msgid "Join this group"
-msgstr ""
+msgstr "الإنضمام لهذه المجموعة"
#: templates/macros.html:263 templates/macros.html.py:268
#: templates/macros.html:278
@@ -5242,40 +5243,40 @@ msgstr ""
#: templates/macros.html:273 templates/macros.html.py:274
#: templates/macros.html:285
msgid "Ask to join"
-msgstr ""
+msgstr "طلب إنضمام"
#: templates/macros.html:314
#, python-format
msgid "see questions tagged '%(tag)s'"
-msgstr ""
+msgstr "مشاهدة الأسئلة المتعلقة بموضوع '%(tag)s'"
#: templates/macros.html:395
msgid "Comments"
-msgstr ""
+msgstr "التعليقات"
#: templates/macros.html:430
msgid "delete this comment"
-msgstr "إزالة هذا التعليق"
+msgstr "حذ٠هذا التعليق"
#: templates/macros.html:443 templates/revisions.html:38
#: templates/revisions.html.py:41 templates/question/answer_controls.html:5
#: templates/question/question_controls.html:1
msgid "edit"
-msgstr "تحرير"
+msgstr "تعديل"
#: templates/macros.html:452
msgid "convert to answer"
-msgstr ""
+msgstr "تحويل لإجابة"
#: templates/macros.html:579
#, python-format
msgid "follow %(alias)s"
-msgstr "متابعة %(alias)s"
+msgstr "تابع %(alias)s"
#: templates/macros.html:582
#, python-format
msgid "unfollow %(alias)s"
-msgstr "إيقا٠المتابعة %(alias)s"
+msgstr "إلغاء متابعة %(alias)s"
#: templates/macros.html:583
#, python-format
@@ -5285,17 +5286,17 @@ msgstr "متابع %(alias)s"
#: templates/macros.html:662 templatetags/extra_tags.py:44
#, python-format
msgid "%(username)s gravatar image"
-msgstr ""
+msgstr "الصورة الرمزية للعضو %(username)s"
#: templates/macros.html:671
#, python-format
msgid "%(username)s's website is %(url)s"
-msgstr ""
+msgstr "موقع %(username)s هو %(url)s"
#: templates/macros.html:686 templates/macros.html.py:687
#: templates/macros.html:725 templates/macros.html.py:726
msgid "previous"
-msgstr "السابق"
+msgstr "السابقة"
#: templates/macros.html:698 templates/macros.html.py:737
msgid "current page"
@@ -5329,7 +5330,7 @@ msgstr[5] ""
#: templates/macros.html:768
msgid "no new responses yet"
-msgstr ""
+msgstr "لايوجد ردود بعد"
#: templates/macros.html:783 templates/macros.html.py:784
#, python-format
@@ -5352,27 +5353,27 @@ msgstr "الأسئلة"
#: templates/question.html:230
msgid "see more comments"
-msgstr ""
+msgstr "المزيد من التعليقات"
#: templates/question.html:232 templates/question.html.py:335
msgid "add a comment"
-msgstr ""
+msgstr "أض٠تعليق"
#: templates/question.html:245 templates/question/content.html:46
msgid "Answer Your Own Question"
-msgstr "قم بالإجابة علي سؤالك"
+msgstr "أجب على سؤالك"
#: templates/question.html:250
msgid "Post Your Answer"
-msgstr "إرسال إجابتك"
+msgstr "نشر إجابتك"
#: templates/question.html:256 templates/widgets/ask_form.html:65
msgid "Login/Signup to Post"
-msgstr ""
+msgstr "سجل دخول للنشر"
#: templates/question_edit.html:4 templates/question_edit.html.py:9
msgid "Edit question"
-msgstr "تحرير السؤال"
+msgstr "تعديل السؤال"
#: templates/question_edit.html:16
msgid "Question - in one sentence"
@@ -5380,19 +5381,19 @@ msgstr ""
#: templates/question_edit.html:23
msgid "Details"
-msgstr ""
+msgstr "التÙاصيل"
#: templates/question_edit.html:56
msgid "Change language"
-msgstr ""
+msgstr "تغيير اللغة"
#: templates/question_retag.html:3 templates/question_retag.html.py:5
msgid "Retag question"
-msgstr ""
+msgstr "إعادة تعيين مواضيع السؤال"
#: templates/question_retag.html:21
msgid "Retag"
-msgstr ""
+msgstr "تعديل المواضيع"
#: templates/question_retag.html:28
msgid "Why use and modify tags?"
@@ -5419,7 +5420,7 @@ msgstr "إعادة Ùتح السؤال"
msgid ""
"This question has been closed by \n"
" <a href=\"%(closed_by_profile_url)s\">%(username)s</a>\n"
-msgstr ""
+msgstr "تم إغلاق هذا السؤال بواسطة \n <a href=\"%(closed_by_profile_url)s\">%(username)s</a>\n"
#: templates/reopen.html:17
msgid "Close reason:"
@@ -5427,11 +5428,11 @@ msgstr "سبب الإغلاق:"
#: templates/reopen.html:20
msgid "When:"
-msgstr "حين:"
+msgstr "متى:"
#: templates/reopen.html:23
msgid "Reopen this question?"
-msgstr "إعادة Ùتح السؤال؟"
+msgstr "إعادة Ùتح هذا السؤال؟"
#: templates/reopen.html:27
msgid "Reopen this question"
@@ -5443,16 +5444,16 @@ msgstr "تاريخ المراجعة"
#: templates/revisions.html:23
msgid "click to hide/show revision"
-msgstr ""
+msgstr "أضغط لمشاهدة/إخÙاء المراجعة"
#: templates/revisions.html:29
#, python-format
msgid "revision %(number)s"
-msgstr "إصدار رقم %(number)s"
+msgstr "مراجعة %(number)s"
#: templates/subscribe_for_tags.html:3 templates/subscribe_for_tags.html:5
msgid "Subscribe for tags"
-msgstr ""
+msgstr "الإشتراك بالمواضيع"
#: templates/subscribe_for_tags.html:6
msgid "Please, subscribe for the following tags:"
@@ -5460,16 +5461,16 @@ msgstr ""
#: templates/subscribe_for_tags.html:15
msgid "Subscribe"
-msgstr "اشترك"
+msgstr "أشترك"
#: templates/tags.html:17
msgid "search for tags"
-msgstr ""
+msgstr "البحث عن مواضيع"
#: templates/users.html:8 templates/users.html.py:18
#: templates/tags/list_bulk_tag_subscription.html:13
msgid "Users"
-msgstr "المستخدمون"
+msgstr "الأعضاء"
#: templates/users.html:16
#, python-format
@@ -5488,37 +5489,37 @@ msgstr ""
#: templates/users.html:33 templates/main_page/tab_bar.html:17
#: templates/tags/header.html:14
msgid "Sort by &raquo;"
-msgstr ""
+msgstr "رتب بواسطة &raquo;"
#: templates/users.html:40
msgid "see people with the highest reputation"
-msgstr ""
+msgstr "مشاهدة الأعضاء حسب قوة عطائهم"
#: templates/users.html:41 templates/user_profile/user_info.html:25
#: templates/user_profile/user_reputation.html:5
#: templates/user_profile/user_tabs.html:24
msgid "karma"
-msgstr "النقاط"
+msgstr "قوة السمعة"
#: templates/users.html:47
msgid "see people who joined most recently"
-msgstr ""
+msgstr "مشاهدة أخر الاعضاء المسجلين بالموقع"
#: templates/users.html:48
msgid "recent"
-msgstr "آخر الأحداث"
+msgstr "الأخير"
#: templates/users.html:53
msgid "see people who joined the site first"
-msgstr ""
+msgstr "مشاهدة أول الأعضاء تسجيلاً بالموقع"
#: templates/users.html:59
msgid "see people sorted by name"
-msgstr ""
+msgstr "مشاهدة الأعضاء بواسطة الأسم"
#: templates/users.html:60
msgid "by username"
-msgstr "باسم المستخدم"
+msgstr "الأسم"
#: templates/users.html:66
#, python-format
@@ -5527,7 +5528,7 @@ msgstr ""
#: templates/users.html:69
msgid "Nothing found."
-msgstr "لم يعثر علي شئ."
+msgstr "لم يتم العثور على شيء."
#: templates/authopenid/authopenid_macros.html:63
msgid "Please enter your <span>user name</span>, then sign in"
@@ -5542,15 +5543,15 @@ msgstr ""
#: templates/authopenid/signin.html:115
#: templates/authopenid/widget_signin.html:118
msgid "Sign in"
-msgstr "تسجيل الدخول"
+msgstr "تسجيل دخول"
#: templates/authopenid/changeemail.html:2
msgid "Change Email"
-msgstr "تغيير البريد"
+msgstr "تعديل البريد"
#: templates/authopenid/changeemail.html:6
msgid "Validate email"
-msgstr ""
+msgstr "التحقق من البريد"
#: templates/authopenid/changeemail.html:9
#, python-format
@@ -5565,7 +5566,7 @@ msgstr ""
#: templates/authopenid/changeemail.html:18
msgid "Email verified"
-msgstr ""
+msgstr "تم تأكيد البريد"
#: templates/authopenid/changeemail.html:21
msgid ""
@@ -5578,40 +5579,40 @@ msgstr ""
#: templates/authopenid/complete.html:21
msgid "Registration"
-msgstr ""
+msgstr "تسجيل"
#: templates/authopenid/complete.html:23
msgid "User registration"
-msgstr ""
+msgstr "تسجيل عضو"
#: templates/authopenid/complete.html:47
msgid "<strong>Screen Name</strong> (<i>will be shown to others</i>)"
-msgstr ""
+msgstr "<strong>أسم المستخدم</strong> (<i>ظاهر للجميع</i>)"
#: templates/authopenid/complete.html:56
msgid ""
"<strong>Email Address</strong> (<i>will <strong>not</strong> be shared with \n"
"anyone, must be valid</i>)\n"
" "
-msgstr ""
+msgstr "<strong>البريد الإلكتروني</strong> (<i>مخÙÙŠØŒ غير ظار للأعضاء والزوار، ويجب ان يكون صحيح</i>)"
#: templates/authopenid/complete.html:71
#: templates/authopenid/signup_with_password.html:5
#: templates/authopenid/signup_with_password.html:45
msgid "Signup"
-msgstr "التسجيل"
+msgstr "تسجيل"
#: templates/authopenid/confirm_email.txt:1
msgid "Thank you for registering at our Q&A forum!"
-msgstr ""
+msgstr "شكراً للتسجيل ÙÙŠ ServerHangØŒ الآن يمكنك المساهمة ÙÙŠ بناء المحتوى العربي على الإنترنت!"
#: templates/authopenid/confirm_email.txt:3
msgid "Your account details are:"
-msgstr "تÙاصيل حسابك هي"
+msgstr "بيانات حسابك:"
#: templates/authopenid/confirm_email.txt:5
msgid "Username:"
-msgstr "اسم المستخدم:"
+msgstr "أسم المستخدم:"
#: templates/authopenid/confirm_email.txt:6
msgid "Password:"
@@ -5619,14 +5620,14 @@ msgstr "كلمة المرور:"
#: templates/authopenid/confirm_email.txt:8
msgid "Please sign in here:"
-msgstr "رجاء تسجيل الدخول هنا:"
+msgstr "يرجى تسجيل الدخول هنا"
#: templates/authopenid/confirm_email.txt:11
#: templates/authopenid/email_validation.txt:13
msgid ""
"Sincerely,\n"
"Q&A Forum Administrator"
-msgstr ""
+msgstr "أطيب تحية،\nÙريق عمل ServerHang"
#: templates/authopenid/email_validation.html:2
#: templates/authopenid/email_validation.html:3
@@ -5658,22 +5659,22 @@ msgstr ""
#: templates/authopenid/logout.html:3
msgid "Logout"
-msgstr "تسجيل الخروج"
+msgstr "تسجيل خروج"
#: templates/authopenid/logout.html:5
msgid "You have successfully logged out"
-msgstr ""
+msgstr "تم تسجيل الخروج بنجاح"
#: templates/authopenid/logout.html:7
msgid ""
"However, you still may be logged in to your OpenID provider. Please logout "
"of your provider if you wish to do so."
-msgstr ""
+msgstr "قد تكون مازلت مسجل دخول ÙÙŠ خدمة OpenID التي تستخدمها (مثل تويتر، Ùيسبوك)ØŒ يمكنك التاكد وتسجيل الخروج ان احببت ذلك."
#: templates/authopenid/signin.html:5
#: templates/authopenid/widget_signin.html:5
msgid "User login"
-msgstr ""
+msgstr "دخول عضو"
#: templates/authopenid/signin.html:15
#: templates/authopenid/widget_signin.html:19
@@ -5682,7 +5683,7 @@ msgid ""
"\n"
" Your answer to %(title)s %(summary)s will be posted once you log in\n"
" "
-msgstr ""
+msgstr "\n<span class=\"strong big\">Your answer to </span> <i>\"<strong>%(title)s</strong> %(summary)s...\"</i> <span class=\"strong big\">is saved and will be posted once you log in.</span>"
#: templates/authopenid/signin.html:22
#: templates/authopenid/widget_signin.html:26
@@ -5691,7 +5692,7 @@ msgid ""
"Your question \n"
" %(title)s %(summary)s will be posted once you log in\n"
" "
-msgstr ""
+msgstr "<span class=\"strong big\">Your question</span> <i>\"<strong>%(title)s</strong> %(summary)s...\"</i> <span class=\"strong big\">is saved and will be posted once you log in.</span>"
#: templates/authopenid/signin.html:31
#: templates/authopenid/widget_signin.html:36
@@ -5713,7 +5714,7 @@ msgstr ""
msgid ""
"Click on one of the icons below to add a new login method or re-validate an "
"existing one."
-msgstr ""
+msgstr "أضغط على ايقونة أي من هذه الخدمات لإضاÙتها او إزالتها، كما يمكنك ايضاً من إعادة تأكيد المزود."
#: templates/authopenid/signin.html:39
#: templates/authopenid/widget_signin.html:44
@@ -5727,7 +5728,7 @@ msgstr ""
msgid ""
"Please check your email and visit the enclosed link to re-connect to your "
"account"
-msgstr ""
+msgstr "يرجى مراجعة بريدك الإلكتروني، والضغط على الرابط الخاص الذي ارسلناه لك لتتمكن من إستعادة حسابك."
#: templates/authopenid/signin.html:90
msgid "or enter your <span>user name and password</span>"
@@ -5736,27 +5737,27 @@ msgstr ""
#: templates/authopenid/signin.html:94
#: templates/authopenid/widget_signin.html:98
msgid "Please, sign in"
-msgstr "Ùضلا، الدخول"
+msgstr "يرجى تسجيل الدخول"
#: templates/authopenid/signin.html:101
#: templates/authopenid/widget_signin.html:105
msgid "Login failed, please try again"
-msgstr ""
+msgstr "Ùشل الدخول، يرجى تكرار المحاولة"
#: templates/authopenid/signin.html:106
#: templates/authopenid/widget_signin.html:109
msgid "Login or email"
-msgstr ""
+msgstr "البريد الإلكتروني"
#: templates/authopenid/signin.html:110
#: templates/authopenid/widget_signin.html:113 utils/forms.py:264
msgid "Password"
-msgstr "كلمة مرور"
+msgstr "كلمة المرور"
#: templates/authopenid/signin.html:122
#: templates/authopenid/widget_signin.html:125
msgid "To change your password - please enter the new one twice, then submit"
-msgstr ""
+msgstr "لتغيير كلمة المرور، يرجى إدخال كلمة مرور جديدة مرتبين ثم أرسل."
#: templates/authopenid/signin.html:126
#: templates/authopenid/widget_signin.html:129
@@ -5766,33 +5767,33 @@ msgstr "كلمة مرور جديدة"
#: templates/authopenid/signin.html:135
#: templates/authopenid/widget_signin.html:138
msgid "Please, retype"
-msgstr ""
+msgstr "يرجى إعادة الكتابة"
#: templates/authopenid/signin.html:145
#: templates/authopenid/widget_signin.html:148
#: templates/livesettings/site_settings.html:24
msgid "Change password"
-msgstr ""
+msgstr "تغيير كلمة المرور"
#: templates/authopenid/signin.html:159
#: templates/authopenid/widget_signin.html:162
msgid "Here are your current login methods"
-msgstr ""
+msgstr "وسائل الدخول المستخدمة حالياً"
#: templates/authopenid/signin.html:163
#: templates/authopenid/widget_signin.html:166
msgid "provider"
-msgstr ""
+msgstr "المزود"
#: templates/authopenid/signin.html:164
#: templates/authopenid/widget_signin.html:167
msgid "last used"
-msgstr ""
+msgstr "آخر إستخدام"
#: templates/authopenid/signin.html:165
#: templates/authopenid/widget_signin.html:168
msgid "delete, if you like"
-msgstr ""
+msgstr "حذ٠الوسيلة"
#: templates/authopenid/signin.html:179
#: templates/authopenid/widget_signin.html:182
@@ -5804,45 +5805,45 @@ msgstr "حذÙ"
#: templates/authopenid/signin.html:181
#: templates/authopenid/widget_signin.html:184
msgid "cannot be deleted"
-msgstr ""
+msgstr "لا يمكن حذÙها"
#: templates/authopenid/signin.html:194
#: templates/authopenid/widget_signin.html:197
msgid "Still have trouble signing in?"
-msgstr ""
+msgstr "مازال لديك مشكلة بتسجيل الدخول؟"
#: templates/authopenid/signin.html:199
#: templates/authopenid/widget_signin.html:202
msgid "Please, enter your email address below and obtain a new key"
-msgstr ""
+msgstr "يرجى إدخال البريد الخاص بك هنا لإرسال كود جديد"
#: templates/authopenid/signin.html:201
#: templates/authopenid/widget_signin.html:204
msgid "Please, enter your email address below to recover your account"
-msgstr ""
+msgstr "يرجى إدخال البريد الخاص بك هنا لإستعادة الحساب"
#: templates/authopenid/signin.html:204
#: templates/authopenid/widget_signin.html:207
msgid "recover your account via email"
-msgstr ""
+msgstr "إستعادة حسابك عبر البريد"
#: templates/authopenid/signin.html:215
#: templates/authopenid/widget_signin.html:217
msgid "Send a new recovery key"
-msgstr ""
+msgstr "إرسال Ù…Ùتاح إستعادة جديد"
#: templates/authopenid/signin.html:217
#: templates/authopenid/widget_signin.html:219
msgid "Recover your account via email"
-msgstr ""
+msgstr "إستعادة حسابك عبر البرد"
#: templates/authopenid/signup_with_password.html:11
msgid "Please register by clicking on any of the icons below"
-msgstr ""
+msgstr "يمكنك التسجيل من خلال أحدى هذه الخدمات الإجتماعية"
#: templates/authopenid/signup_with_password.html:24
msgid "or create a new user name and password here"
-msgstr ""
+msgstr "كما يمكنك تسجيل حساب خاص من خلال النموذج بالأسÙÙ„"
#: templates/authopenid/signup_with_password.html:26
msgid "Create login name and password"
@@ -5861,7 +5862,7 @@ msgstr ""
msgid ""
"Please read and type in the two words below to help us prevent automated "
"account creation."
-msgstr ""
+msgstr "Ùضلاً أدخل كلمة التحقق البشري، تساعدنا هذه الطريقة بمنع التسجيل العشوائي والتلقائي."
#: templates/authopenid/signup_with_password.html:47
msgid "or"
@@ -5874,17 +5875,17 @@ msgstr ""
#: templates/authopenid/verify_email.html:2
#: templates/authopenid/verify_email.html:4
msgid "Confirm email address"
-msgstr ""
+msgstr "تأكيد البريد الإلكتروني"
#: templates/authopenid/verify_email.html:6
msgid ""
"Validation email sent. Please find it and follow the enclosed link.<br/>\n"
" If the link doesn't work - enter the code below:"
-msgstr ""
+msgstr "تم إرسال بريد للتحقق من صحة البريد. يرجى Ùتح الرسالة واضغط على الرابط المرÙÙ‚.<br/>\n واذا لم يعمل، انسخ الكود Ùقط والصق ÙÙŠ الحقل هنا: "
#: templates/authopenid/verify_email.html:11
msgid "Confirm email"
-msgstr ""
+msgstr "تأكيد البريد"
#: templates/authopenid/widget_signin.html:33
msgid ""
@@ -5899,27 +5900,27 @@ msgstr ""
#: templates/avatar/add.html:3
msgid "add avatar"
-msgstr "إضاÙØ© صورة"
+msgstr "أض٠صورة رمزية"
#: templates/avatar/add.html:5
msgid "Change avatar"
-msgstr "تغيير الصورة"
+msgstr "تعديل الصورة الرمزية"
#: templates/avatar/add.html:6 templates/avatar/change.html:7
msgid "Your current avatar: "
-msgstr "صورتك الحالية:"
+msgstr "الصورة الرمزية الحالية"
#: templates/avatar/add.html:9 templates/avatar/change.html:11
msgid "You haven't uploaded an avatar yet. Please upload one now."
-msgstr ""
+msgstr "لم تقم برÙع أي صورة رمزية بعد، يرجى رÙع واحدة الآن."
#: templates/avatar/add.html:13
msgid "Upload New Image"
-msgstr "تحميل صورة جديدة"
+msgstr "رÙع صورة جديدة"
#: templates/avatar/change.html:4
msgid "change avatar"
-msgstr ""
+msgstr "تعديل الصورة الرمزية"
#: templates/avatar/change.html:17
msgid "Choose new Default"
@@ -5927,11 +5928,11 @@ msgstr ""
#: templates/avatar/change.html:22
msgid "Upload"
-msgstr "تحميل"
+msgstr "رÙع"
#: templates/avatar/confirm_delete.html:2
msgid "delete avatar"
-msgstr "حذ٠صورة"
+msgstr "حذ٠الصورة الرمزية"
#: templates/avatar/confirm_delete.html:4
msgid "Please select the avatars that you would like to delete."
@@ -6000,7 +6001,7 @@ msgstr ""
#: templates/email/delayed_email_alert.html:2
#, python-format
msgid "Dear %(name)s,"
-msgstr ""
+msgstr "عزيزي %(name)s،"
#: templates/email/delayed_email_alert.html:3
#, python-format
@@ -6045,7 +6046,7 @@ msgstr ""
#: templates/email/macros.html:19
#, python-format
msgid "Question by %(author)s:"
-msgstr ""
+msgstr "سؤال بواسطة %(author)s:"
#: templates/email/macros.html:21
#, python-format
@@ -6062,11 +6063,11 @@ msgstr ""
#: templates/email/macros.html:33
#, python-format
msgid "Asked by %(author)s:"
-msgstr ""
+msgstr "سÙأل بواسطة %(author)s: "
#: templates/email/macros.html:40
msgid "Tags:"
-msgstr ""
+msgstr "مواضيع:"
#: templates/email/macros.html:48
#, python-format
@@ -6190,7 +6191,7 @@ msgstr ""
#: templates/email/welcome_lamson_on.html:4
#, python-format
msgid "Welcome to %(site_name)s!"
-msgstr ""
+msgstr "مرحباً بك ÙÙŠ %(site_name)s"
#: templates/email/welcome_lamson_on.html:11
msgid ""
@@ -6208,19 +6209,19 @@ msgstr ""
#: templates/embed/list_widgets.html:44
msgid "How to use?"
-msgstr ""
+msgstr "How to use?"
#: templates/embed/list_widgets.html:45
msgid ""
"\n"
" Just copy the &lt;script&gt; tag provided and paste it in the site where you wan to put it.\n"
" "
-msgstr ""
+msgstr "\n Just copy the &lt;script&gt; tag provided and paste it in the site where you wan to put it.\n "
#: templates/embed/widget_form.html:3 templates/embed/widget_form.html.py:5
#, python-format
msgid "%(action)s an %(widget_name)s widget"
-msgstr ""
+msgstr "%(action)s an %(widget_name)s widget"
#: templates/embed/widget_form.html:14
#: templates/user_profile/user_moderate.html:20
@@ -6229,33 +6230,33 @@ msgstr "Ø­Ùظ"
#: templates/embed/widgets.html:3 templates/embed/widgets.html.py:5
msgid "Widgets"
-msgstr ""
+msgstr "Widgets"
#: templates/embed/widgets.html:11
msgid ""
"Create and embed widgets into your sites, here a list of available widgets."
-msgstr ""
+msgstr "Create and embed widgets into your sites, here a list of available widgets."
#: templates/embed/widgets.html:16
msgid "Ask a question"
-msgstr ""
+msgstr "أطرح سؤالك معنا"
#: templates/embed/widgets.html:17 templates/embed/widgets.html.py:26
msgid "create"
-msgstr ""
+msgstr "create"
#: templates/embed/widgets.html:20 templates/embed/widgets.html.py:29
msgid "view list"
-msgstr ""
+msgstr "عرض القائمة"
#: templates/embed/widgets.html:25
msgid "List of questions"
-msgstr ""
+msgstr "قائمة الأسئلة"
#: templates/group_messaging/email_alert.html:7
#, python-format
msgid "%(author)s wrote:"
-msgstr ""
+msgstr "%(author)s كتب:"
#: templates/group_messaging/email_alert.html:11
msgid ""
@@ -6266,12 +6267,12 @@ msgstr ""
#: templates/group_messaging/home.html:7
#: templates/group_messaging/home_thread_details.html:7
msgid "compose"
-msgstr ""
+msgstr "تحرير"
#: templates/group_messaging/macros.html:5
#, python-format
msgid "You wrote on %(date)s:"
-msgstr ""
+msgstr "لقد كتبت ÙÙŠ %(date)s:"
#: templates/group_messaging/senders_list.html:3
msgid "Messages by sender:"
@@ -6280,19 +6281,19 @@ msgstr ""
#: templates/group_messaging/senders_list.html:5
#: templates/user_inbox/base.html:6 templates/user_profile/user_tabs.html:12
msgid "inbox"
-msgstr "الوارد"
+msgstr "الرسائل"
#: templates/group_messaging/senders_list.html:9
msgid "sent"
-msgstr ""
+msgstr "المرسلة"
#: templates/group_messaging/senders_list.html:16
msgid "trash"
-msgstr ""
+msgstr "السلة"
#: templates/group_messaging/threads_list.html:25
msgid "there are no messages yet..."
-msgstr ""
+msgstr "لا يوجد رسائل بعد..."
#: templates/livesettings/_admin_site_views.html:4
msgid "Sites"
@@ -6300,7 +6301,7 @@ msgstr "مواقع"
#: templates/livesettings/group_settings.html:4
msgid "Settings"
-msgstr ""
+msgstr "إعدادات"
#: templates/livesettings/group_settings.html:9
#: templates/livesettings/site_settings.html:51
@@ -6321,15 +6322,15 @@ msgstr ""
#: templates/livesettings/group_settings.html:50
#: templates/livesettings/site_settings.html:98
msgid "You don't have permission to edit values."
-msgstr ""
+msgstr "ليس لديك صلاحيات لتعديل هذه القيم."
#: templates/livesettings/site_settings.html:24
msgid "Documentation"
-msgstr ""
+msgstr "الوثائق"
#: templates/livesettings/site_settings.html:24
msgid "Log out"
-msgstr "سجيل الخروج"
+msgstr "تسجيل خروج"
#: templates/livesettings/site_settings.html:27
msgid "Home"
@@ -6337,20 +6338,20 @@ msgstr "الرئيسية"
#: templates/livesettings/site_settings.html:28
msgid "Edit Site Settings"
-msgstr ""
+msgstr "تعديل إعدادات الموقع"
#: templates/livesettings/site_settings.html:44
msgid "Livesettings are disabled for this site."
-msgstr ""
+msgstr "Livesettings are disabled for this site."
#: templates/livesettings/site_settings.html:45
msgid "All configuration options must be edited in the site settings.py file"
-msgstr ""
+msgstr "All configuration options must be edited in the site settings.py file"
#: templates/livesettings/site_settings.html:67
#, python-format
msgid "Group settings: %(name)s"
-msgstr ""
+msgstr "إعدادات مجموعة: %(name)s"
#: templates/livesettings/site_settings.html:94
msgid "Uncollapse all"
@@ -6374,11 +6375,11 @@ msgstr ""
#: templates/main_page/headline.html:11
msgid "Tagged"
-msgstr "معلّم"
+msgstr "المواضيع"
#: templates/main_page/headline.html:22
msgid "Search tips:"
-msgstr ""
+msgstr "نصائح البحث:"
#: templates/main_page/headline.html:25
msgid "reset author"
@@ -6396,7 +6397,7 @@ msgstr ""
#: templates/main_page/headline.html:31 templates/main_page/headline.html:34
msgid "start over"
-msgstr ""
+msgstr "إبدأ من جديد"
#: templates/main_page/headline.html:36
msgid " - to expand, or dig in by adding more tags and revising the query."
@@ -6404,7 +6405,7 @@ msgstr ""
#: templates/main_page/headline.html:39
msgid "Search tip:"
-msgstr "بحث الإرشادات"
+msgstr "نصائح البحث:"
#: templates/main_page/headline.html:39
msgid "add tags and a query to focus your search"
@@ -6420,7 +6421,7 @@ msgstr "لا يوجد أسئلة هنا."
#: templates/main_page/nothing_found.html:8
msgid "Please follow some questions or follow some users."
-msgstr ""
+msgstr "Ùضلا تابع بعض الأسئلة أو بعض الأعضاء."
#: templates/main_page/nothing_found.html:13
msgid "You can expand your search by "
@@ -6437,35 +6438,35 @@ msgstr ""
#: templates/main_page/nothing_found.html:22
#: templates/main_page/nothing_found.html:25
msgid "starting over"
-msgstr ""
+msgstr "إبدأ من جديد"
#: templates/main_page/nothing_found.html:30
msgid "Please always feel free to ask your question!"
-msgstr ""
+msgstr "أطرح سؤالك بكل حرية أن لم يكن قد كتب من قبل!"
#: templates/main_page/questions_loop.html:9
msgid "Did not find what you were looking for?"
-msgstr "لم تجد ما تبحث عنه؟"
+msgstr "لم تجد إجابة لسؤالك بعد؟"
#: templates/main_page/questions_loop.html:10
msgid "Ask your question!"
-msgstr ""
+msgstr "أنشر سؤالك الآن لتحصل على الإجابة!"
#: templates/main_page/tab_bar.html:11
msgid "subscribe to the questions feed"
-msgstr ""
+msgstr "الإشتراك بخلاصة RSS لمتابعة آخر الأسئلة المطروحة"
#: templates/main_page/tab_bar.html:12
msgid "RSS"
-msgstr ""
+msgstr "خلاصة RSS"
#: templates/main_page/tag_search.html:2
msgid "Tag search"
-msgstr ""
+msgstr "بحث عن موضوع"
#: templates/main_page/tag_search.html:5
msgid "search"
-msgstr ""
+msgstr "بحث"
#: templates/meta/bottom_scripts.html:7
#, python-format
@@ -6501,11 +6502,11 @@ msgstr[5] ""
#, python-format
msgid ""
"please use up to %(tag_count)s tags, less than %(max_chars)s characters each"
-msgstr ""
+msgstr "يمكنك بإستخدام %(tag_count)s مواضيع كحد أقصى، وأن لا يتجاوز كل موضوع عن %(max_chars)s حرÙ."
#: templates/question/answer_card.html:21
msgid "This response is published"
-msgstr ""
+msgstr "تم نشر الرد"
#: templates/question/answer_controls.html:2
msgid "swap with question"
@@ -6513,12 +6514,12 @@ msgstr ""
#: templates/question/answer_controls.html:11
msgid "remove offensive flag"
-msgstr ""
+msgstr "إلغاء تبليغ الإساءة"
#: templates/question/answer_controls.html:13
#: templates/question/question_controls.html:12
msgid "remove flag"
-msgstr "إزالة العلم"
+msgstr "إزالة التبليغ"
#: templates/question/answer_controls.html:18
#: templates/question/answer_controls.html:26
@@ -6527,14 +6528,14 @@ msgstr "إزالة العلم"
#: templates/question/question_controls.html:23
msgid ""
"report as offensive (i.e containing spam, advertising, malicious text, etc.)"
-msgstr ""
+msgstr "التبليغ على المحتوى (مثلا سبام، دعائي، يحتوي روابط ضارة، يحتوي مواد سيئة...الخ.)"
#: templates/question/answer_controls.html:20
#: templates/question/answer_controls.html:28
#: templates/question/question_controls.html:18
#: templates/question/question_controls.html:25
msgid "flag offensive"
-msgstr "ضع علم كعدواني"
+msgstr "تبليغ إساءة"
#: templates/question/answer_controls.html:33
#: templates/question/question_controls.html:36
@@ -6543,15 +6544,15 @@ msgstr "إلغاء الحذÙ"
#: templates/question/answer_controls.html:43
msgid "unpublish"
-msgstr ""
+msgstr "إلغاء النشر"
#: templates/question/answer_controls.html:48
msgid "publish"
-msgstr ""
+msgstr "نشر"
#: templates/question/answer_controls.html:54
msgid "permanent link"
-msgstr ""
+msgstr "الرابط الدائم"
#: templates/question/answer_controls.html:55
#: templates/widgets/markdown_help.html:20
@@ -6560,15 +6561,15 @@ msgstr "رابط"
#: templates/question/answer_controls.html:58
msgid "more"
-msgstr ""
+msgstr "المزيد"
#: templates/question/answer_controls.html:71
msgid "repost as a question comment"
-msgstr ""
+msgstr "إعادة النشر كتعليق على السؤال"
#: templates/question/answer_controls.html:85
msgid "repost as a comment under the older answer"
-msgstr ""
+msgstr "إعادة النشر كتعليق على الإجابة الأقدم"
#: templates/question/answer_tab_bar.html:3
#, python-format
@@ -6589,52 +6590,52 @@ msgstr[5] ""
#: templates/question/answer_tab_bar.html:11
msgid "Sort by »"
-msgstr "ترتيب حسب >> "
+msgstr "رتب »"
#: templates/question/answer_tab_bar.html:14
msgid "oldest answers will be shown first"
-msgstr ""
+msgstr "الإجابات الأقدم أولاً"
#: templates/question/answer_tab_bar.html:17
msgid "newest answers will be shown first"
-msgstr ""
+msgstr "الإجابات الأحدث أولاً"
#: templates/question/answer_tab_bar.html:20
msgid "most voted answers will be shown first"
-msgstr ""
+msgstr "الإجابات الأكثر تصويت أولاً"
#: templates/question/answer_vote_buttons.html:8
#: templates/user_profile/users_answers.html:7
msgid "this answer has been selected as correct"
-msgstr ""
+msgstr "تم إختيار هذه الإجابة كصحيحة"
#: templates/question/answer_vote_buttons.html:10
msgid "mark this answer as correct (click again to undo)"
-msgstr ""
+msgstr "إختيار إجابة صحيحة (أعد أضغط للتراجع)"
#: templates/question/closed_question_info.html:2
#, python-format
msgid ""
"The question has been closed for the following reason "
"<b>\"%(close_reason)s\"</b> <i>by"
-msgstr ""
+msgstr "هذا السؤال تم إغلاقة للأسباب التالية <b>\"%(close_reason)s\"</b> <i> بواسطة"
#: templates/question/closed_question_info.html:4
#, python-format
msgid "close date %(closed_at)s"
-msgstr ""
+msgstr "تاريخ الإغلاق %(closed_at)s"
#: templates/question/content.html:33
msgid "Edit Your Previous Answer"
-msgstr ""
+msgstr "تعديل إجابتك"
#: templates/question/content.html:34
msgid "(only one answer per user is allowed)"
-msgstr ""
+msgstr "(يسمح بإجابة واحدة لكل عضو)"
#: templates/question/new_answer_form.html:12
msgid "Login/Signup to Answer"
-msgstr ""
+msgstr "دخول/تسجيل للإجابة"
#: templates/question/new_answer_form.html:20
msgid "Your answer"
@@ -6642,7 +6643,7 @@ msgstr "إجابتك"
#: templates/question/new_answer_form.html:22
msgid "Be the first one to answer this question!"
-msgstr "لتكن أول من يجيب هذا السؤال!"
+msgstr "ÙƒÙÙ† الأول ليجيب على هذا السؤال وأحصل على قوة سمعة إضاÙية!"
#: templates/question/new_answer_form.html:28
msgid ""
@@ -6651,7 +6652,7 @@ msgid ""
"you log in or create a new account. Please try to give a <strong>substantial"
" answer</strong>, for discussions, <strong>please use comments</strong> and "
"<strong>please do remember to vote</strong> (after you log in)!"
-msgstr ""
+msgstr "يمكنك كتابة إجابتك الآن، وبعد تسجيل الدخول سو٠يتم نشر الإجابة بشكل تلقائي. تأكد أنك سو٠تقوم بطرح إجابة كاملة وصحيحة. كما يمكنك دائماً مراجعة وتعديل إجابتك. Ùضلاً <strong>أستخدم خاصية التعليقات للنقاش</strong>. كما يرجى <strong>التصويت للإجابات الصحيحة</strong> دائماً، ايضاً صوت بالسالب على الإجابات الخاطئة."
#: templates/question/new_answer_form.html:32
msgid ""
@@ -6661,7 +6662,7 @@ msgid ""
"<strong>use comments for discussions</strong> and <strong>please don't "
"forget to vote :)</strong> for the answers that you liked (or perhaps did "
"not like)!"
-msgstr ""
+msgstr "بإمكانك دائماً الإجابة على سؤالك، لكن تأكد أنك سو٠تقوم بطرح إجابة كاملة وصحيحة. علماً انه يمكنك دائماً مراجعة وتعديل صيغة سؤالك الأصلي وضاÙØ© المزيد من المعلومات Ùيه أو كتابتها على شكل تعليق. Ùضلاً <strong>أستخدم التعليقات للنقاش</strong> ويرجى <strong>التصويت للإجابات الصحيحة</strong> دائماً، ايضاً صوت بالسالب على الإجابات الخاطئة، حيث ان التصويت يساعد المحتوى الجيد على الظهور بترتيب اÙضل وهذا يساعد الغير ÙÙŠ الحصول على المعلومة بشكل اسرع."
#: templates/question/new_answer_form.html:34
msgid ""
@@ -6671,15 +6672,15 @@ msgid ""
" your answers</strong> - no need to answer the same question twice. Also, "
"please <strong>don't forget to vote</strong> - it really helps to select the"
" best questions and answers!"
-msgstr ""
+msgstr "حاول قدر الإمكان ان تعطي إجابة كاملة دقيقة حول السؤال، الإجابات الصحيحة والدقيقة دائماً تأخذ تصويت اعلى، واهتم جيداً بالتنسيق. <strong>للنقاش أستخدم خاصية التعليقات على السؤال او الإجابة</strong>. كما يرجى <strong>التصويت للإجابات الصحيحة</strong> دائماً، ايضاً صوت بالسالب على الإجابات الخاطئة، التصويت يساعد المحتوى الجيد على الظهور وبالتالي ايجاد المعلومة الصحيحة من قبل الغير بشكل اسرع. كن مساهم إيجابي!"
#: templates/question/new_answer_form.html:39
msgid "Add answer"
-msgstr ""
+msgstr "أض٠إجابة"
#: templates/question/question_controls.html:5
msgid "retag"
-msgstr ""
+msgstr "إعادة تعيين المواضيع"
#: templates/question/question_controls.html:29
msgid "reopen"
@@ -6687,31 +6688,31 @@ msgstr "إعادة Ùتح"
#: templates/question/question_controls.html:31
msgid "close"
-msgstr "غلق"
+msgstr "إغلاق"
#: templates/question/sidebar.html:8
msgid "Question tools"
-msgstr ""
+msgstr "أدوات السؤال"
#: templates/question/sidebar.html:11
msgid "click to unfollow this question"
-msgstr "انقر لإلغاء المتابعة"
+msgstr "أضغط هنا لإلغاء المتابعة"
#: templates/question/sidebar.html:12
msgid "Following"
-msgstr "متابع"
+msgstr "Ù…Ùتابع"
#: templates/question/sidebar.html:13
msgid "Unfollow"
-msgstr "إيقا٠المتابعة"
+msgstr "إلغاء المتابعة"
#: templates/question/sidebar.html:17
msgid "click to follow this question"
-msgstr "أنقر لمتابعة هذا السؤال"
+msgstr "أضغط هنا لمتابعة هذا السؤال"
#: templates/question/sidebar.html:18
msgid "Follow"
-msgstr "متابعة"
+msgstr "تابع"
#: templates/question/sidebar.html:25
#, python-format
@@ -6726,15 +6727,15 @@ msgstr[5] ""
#: templates/question/sidebar.html:33
msgid "subscribe to this question rss feed"
-msgstr ""
+msgstr "متابعة هذا السؤال عبر خلاصات RSS"
#: templates/question/sidebar.html:34
msgid "subscribe to rss feed"
-msgstr ""
+msgstr "الإشتراك بخلاصة RSS"
#: templates/question/sidebar.html:44
msgid "Invite"
-msgstr ""
+msgstr "دعوة"
#: templates/question/sidebar.html:50 templates/question/sidebar.html.py:56
#: templates/user_profile/user_email_subscriptions.html:59
@@ -6742,11 +6743,11 @@ msgstr ""
#: templates/widgets/tag_selector.html:37
#: templates/widgets/tag_selector.html:56
msgid "add"
-msgstr "إضاÙØ©"
+msgstr "أضÙ"
#: templates/question/sidebar.html:52 templates/question/sidebar.html.py:58
msgid "- or -"
-msgstr ""
+msgstr "- أو -"
#: templates/question/sidebar.html:70
msgid "share with everyone"
@@ -6762,16 +6763,16 @@ msgstr ""
#: templates/question/sidebar.html:88
msgid "You"
-msgstr ""
+msgstr "أنت"
#: templates/question/sidebar.html:95 templates/question/sidebar.html:115
msgid "and"
-msgstr ""
+msgstr "Ùˆ"
#: templates/question/sidebar.html:120
#, python-format
msgid "%(more_count)s more"
-msgstr ""
+msgstr "%(more_count)s المزيد"
#: templates/question/sidebar.html:126
msgid "Public thread"
@@ -6785,35 +6786,35 @@ msgstr ""
#: templates/question/sidebar.html:135
msgid "Stats"
-msgstr "إحصائيات"
+msgstr "إحصاءات"
#: templates/question/sidebar.html:137
msgid "Asked"
-msgstr ""
+msgstr "سأل"
#: templates/question/sidebar.html:140
msgid "Seen"
-msgstr ""
+msgstr "شوهد"
#: templates/question/sidebar.html:140
msgid "times"
-msgstr "مرات"
+msgstr "مرة"
#: templates/question/sidebar.html:143
msgid "Last updated"
-msgstr "آخر تحديث"
+msgstr "آخر تعديل"
#: templates/question/sidebar.html:151
msgid "Related questions"
-msgstr "الأسئلة المرتبطة"
+msgstr "أسئلة ذات صلة"
#: templates/tags/form_bulk_tag_subscription.html:4
msgid "Tag subscriptions"
-msgstr ""
+msgstr "الإشتراك بالمواضيع"
#: templates/tags/form_bulk_tag_subscription.html:6
msgid "Tag Subscriptions"
-msgstr ""
+msgstr "الإشتراك بالمواضيع"
#: templates/tags/header.html:7
#, python-format
@@ -6822,19 +6823,19 @@ msgstr ""
#: templates/tags/header.html:19
msgid "sorted alphabetically"
-msgstr ""
+msgstr "ترتيب أبجدي"
#: templates/tags/header.html:20
msgid "by name"
-msgstr "بالاسم"
+msgstr "الأسم"
#: templates/tags/header.html:25
msgid "sorted by frequency of tag use"
-msgstr ""
+msgstr "الترتيب بمعدل إستخدام الموضوع بالأسئلة"
#: templates/tags/header.html:26
msgid "by popularity"
-msgstr "بالشعبية"
+msgstr "الشعبية"
#: templates/tags/header.html:34 templates/tags/header.html.py:35
msgid "suggested"
@@ -6842,39 +6843,39 @@ msgstr ""
#: templates/tags/header.html:42 templates/tags/header.html.py:43
msgid "manage subscriptions"
-msgstr ""
+msgstr "إدارة الإشتراكات"
#: templates/tags/list_bulk_tag_subscription.html:4
msgid "Manage Tag subscriptions"
-msgstr ""
+msgstr "إدارة إشتراكات المواضيع"
#: templates/tags/list_bulk_tag_subscription.html:6
msgid "Manage Tag subscription</a> "
-msgstr ""
+msgstr "إدارة إشتراكات المواضيع</a> "
#: templates/tags/list_bulk_tag_subscription.html:6
msgid "Create New"
-msgstr ""
+msgstr "إنشاء جديد"
#: templates/tags/list_bulk_tag_subscription.html:11
msgid "Date"
-msgstr ""
+msgstr "التاريخ"
#: templates/tags/list_bulk_tag_subscription.html:17
msgid "Action"
-msgstr ""
+msgstr "الÙعل"
#: templates/tags/list_bulk_tag_subscription.html:48 views/commands.py:759
msgid "Edit"
-msgstr ""
+msgstr "تعديل"
#: templates/user_inbox/base.html:14
msgid "Sections:"
-msgstr "أقسام:"
+msgstr "الأقسام:"
#: templates/user_inbox/base.html:19
msgid "messages"
-msgstr ""
+msgstr "الرسائل"
#: templates/user_inbox/base.html:24
#, python-format
@@ -6896,27 +6897,27 @@ msgstr ""
#: templates/user_inbox/group_join_requests.html:26
msgid "Approve"
-msgstr ""
+msgstr "صرح"
#: templates/user_inbox/group_join_requests.html:41
msgid "Deny"
-msgstr ""
+msgstr "أحجب"
#: templates/user_inbox/messages.html:104
msgid "inbox - messages"
-msgstr ""
+msgstr "صندوق الرسائل"
#: templates/user_inbox/responses_and_flags.html:4
msgid "inbox - responses"
-msgstr ""
+msgstr "صندوق الردود"
#: templates/user_inbox/responses_and_flags.html:8
msgid "select:"
-msgstr "تحديد:"
+msgstr "إختيار:"
#: templates/user_inbox/responses_and_flags.html:10
msgid "seen"
-msgstr ""
+msgstr "شوهد"
#: templates/user_inbox/responses_and_flags.html:11
msgid "new"
@@ -6924,11 +6925,11 @@ msgstr "جديد"
#: templates/user_inbox/responses_and_flags.html:12
msgid "none"
-msgstr "لا شئ"
+msgstr "لاشيء"
#: templates/user_inbox/responses_and_flags.html:15
msgid "mark as seen"
-msgstr "تعليم كمشاهد"
+msgstr "تعليم كشوهد"
#: templates/user_inbox/responses_and_flags.html:16
msgid "mark as new"
@@ -6936,7 +6937,7 @@ msgstr "تعليم كجديد"
#: templates/user_inbox/responses_and_flags.html:17
msgid "dismiss"
-msgstr ""
+msgstr "تم الإطلاع"
#: templates/user_inbox/responses_and_flags.html:19
msgid "remove flags/approve"
@@ -6966,27 +6967,27 @@ msgstr ""
#: templates/user_profile/reject_post_dialog.html:27
#: templates/user_profile/reject_post_dialog.html:95
msgid "Use other reason"
-msgstr ""
+msgstr "إختيار سبب آخر"
#: templates/user_profile/reject_post_dialog.html:33
msgid "Save reason, but do not reject"
-msgstr ""
+msgstr "أحÙظ السبب دون ان ترÙض"
#: templates/user_profile/reject_post_dialog.html:43
msgid "Please, choose a reason for the rejection."
-msgstr ""
+msgstr "يرجى إختيار سبب لهذا الرÙض."
#: templates/user_profile/reject_post_dialog.html:58
msgid "Select this reason"
-msgstr ""
+msgstr "إختيار هذا السبب"
#: templates/user_profile/reject_post_dialog.html:65
msgid "Delete this reason"
-msgstr ""
+msgstr "حذ٠هذا السبب"
#: templates/user_profile/reject_post_dialog.html:71
msgid "Add a new reason"
-msgstr ""
+msgstr "أض٠سبب جديد"
#: templates/user_profile/reject_post_dialog.html:81
msgid ""
@@ -6997,7 +6998,7 @@ msgstr ""
#: templates/user_profile/reject_post_dialog.html:101
msgid "Edit this reason"
-msgstr ""
+msgstr "تعديل هذا السبب"
#: templates/user_profile/twitter_sharing_controls.html:8
#, python-format
@@ -7006,45 +7007,45 @@ msgstr ""
#: templates/user_profile/twitter_sharing_controls.html:19
msgid "stop tweeting"
-msgstr ""
+msgstr "إيقا٠التغريد"
#: templates/user_profile/twitter_sharing_controls.html:23
msgid "Auto-tweeting is inactive"
-msgstr ""
+msgstr "التغريد التلقائي معطل"
#: templates/user_profile/twitter_sharing_controls.html:26
msgid "Select twitter account"
-msgstr ""
+msgstr "إختيار حساب تويتر"
#: templates/user_profile/twitter_sharing_controls.html:28
msgid "use another account"
-msgstr ""
+msgstr "إستخدام حساب آخر"
#: templates/user_profile/twitter_sharing_controls.html:32
msgid "Auto-tweeting is off"
-msgstr ""
+msgstr "التغريد التلقائي موقÙ"
#: templates/user_profile/twitter_sharing_controls.html:33
msgid "Start tweeting"
-msgstr ""
+msgstr "إبدأ بالتغريد"
#: templates/user_profile/user.html:12
#, python-format
msgid "%(username)s's profile"
-msgstr "صÙحة %(username)s"
+msgstr "الصÙحة الشخصية للعضو %(username)s"
#: templates/user_profile/user_edit.html:4
msgid "Edit user profile"
-msgstr "تحرير صÙحتك الخاصة"
+msgstr "تعديل المل٠العضو الشخصي"
#: templates/user_profile/user_edit.html:7
msgid "edit profile"
-msgstr "تحرير المل٠الشخصي:"
+msgstr "تعديل المل٠الشخصي"
#: templates/user_profile/user_edit.html:21
#: templates/user_profile/user_info.html:14
msgid "change picture"
-msgstr "تغيير الصورة"
+msgstr "تعديل الصورة"
#: templates/user_profile/user_edit.html:25
#: templates/user_profile/user_info.html:18
@@ -7057,11 +7058,11 @@ msgstr "عضو مسجل"
#: templates/user_profile/user_edit.html:39
msgid "Screen Name"
-msgstr "الاسم الظاهر"
+msgstr "أسم المستخدم"
#: templates/user_profile/user_edit.html:59
msgid "(cannot be changed)"
-msgstr "(لا يمكن تعديلها)"
+msgstr "(لا يمكن تعديلة)"
#: templates/user_profile/user_edit.html:109
#: templates/user_profile/user_email_subscriptions.html:23
@@ -7071,11 +7072,11 @@ msgstr "تحديث"
#: templates/user_profile/user_email_subscriptions.html:5
#: templates/user_profile/user_tabs.html:44
msgid "subscriptions"
-msgstr "إشتراكات"
+msgstr "النشرات والتنبيهات"
#: templates/user_profile/user_email_subscriptions.html:8
msgid "Email subscription settings"
-msgstr ""
+msgstr "إعدادات النشرات والتنبيهات البريدية"
#: templates/user_profile/user_email_subscriptions.html:10
msgid ""
@@ -7084,7 +7085,7 @@ msgid ""
"community</strong> by answering questions of your colleagues. If you do not "
"wish to receive emails - select 'no email' on all items below.<br/>Updates "
"are only sent when there is any new activity on selected items."
-msgstr ""
+msgstr "ÙÙŠ هذه الصÙحة يمكنك إدارة إشتراكات البريد ومعدل إرسال التنبيهات على بريدك. التنبيهات التي تصلك هي غالباً حول الأسئلة التي أنت مهتم بها حسب نوع مشاركتك معها، وتعتبر وسيلة جيدة لمتابعة هذه الأسئلة والبقاء على تحديث حول مايحدث Ùيها. لن تصلك رسالة مالم يكن هناك جديد، <b>لا يتم إرسال نشرات دعائية ابداً، نحن لا نحب هذا الامر، مثلك تمامأً</b>. "
#: templates/user_profile/user_email_subscriptions.html:24
msgid "Stop Email"
@@ -7096,7 +7097,7 @@ msgstr ""
#: templates/user_profile/user_email_subscriptions.html:43
msgid "Save languages"
-msgstr ""
+msgstr "Ø­Ùظ اللغات"
#: templates/user_profile/user_email_subscriptions.html:48
msgid "Subscribed Tags"
@@ -7105,27 +7106,27 @@ msgstr ""
#: templates/user_profile/user_favorites.html:4
#: templates/user_profile/user_tabs.html:29
msgid "followed questions"
-msgstr ""
+msgstr "الأسئلة المÙتابعة"
#: templates/user_profile/user_info.html:37
msgid "update profile"
-msgstr ""
+msgstr "تعديل المل٠الشخصي"
#: templates/user_profile/user_info.html:41
msgid "manage login methods"
-msgstr ""
+msgstr "إدارة وسائل الدخول"
#: templates/user_profile/user_info.html:54
msgid "real name"
-msgstr "الاسم الحقيقي"
+msgstr "الأسم الحقيقي"
#: templates/user_profile/user_info.html:60
msgid "groups"
-msgstr ""
+msgstr "المجموعات"
#: templates/user_profile/user_info.html:71
msgid "add group"
-msgstr ""
+msgstr "أض٠مجموعة"
#: templates/user_profile/user_info.html:77
msgid "member since"
@@ -7133,7 +7134,7 @@ msgstr "عضو منذ"
#: templates/user_profile/user_info.html:82
msgid "last seen"
-msgstr ""
+msgstr "أخر تواجد"
#: templates/user_profile/user_info.html:88
msgid "website"
@@ -7141,7 +7142,7 @@ msgstr "الموقع"
#: templates/user_profile/user_info.html:101
msgid "location"
-msgstr "المكان"
+msgstr "الموقع الجغراÙÙŠ"
#: templates/user_profile/user_info.html:108
msgid "age"
@@ -7150,56 +7151,56 @@ msgstr "العمر"
#: templates/user_profile/user_info.html:109
#, python-format
msgid "%(age)s years old"
-msgstr ""
+msgstr "%(age)s سنة"
#: templates/user_profile/user_info.html:114
msgid "todays unused votes"
-msgstr ""
+msgstr "أصوات اليوم الغير مستخدمة"
#: templates/user_profile/user_info.html:115
msgid "votes left"
-msgstr "الأصوات المتبقية"
+msgstr "صوت"
#: templates/user_profile/user_moderate.html:4
#: templates/user_profile/user_tabs.html:50
msgid "moderation"
-msgstr ""
+msgstr "الإشراÙ"
#: templates/user_profile/user_moderate.html:8
#, python-format
msgid "%(username)s's current status is \"%(status)s\""
-msgstr ""
+msgstr "%(username)s حالته حالياً هي \"%(status)s\""
#: templates/user_profile/user_moderate.html:11
msgid "User status changed"
-msgstr ""
+msgstr "تم تغيير حالة العضو"
#: templates/user_profile/user_moderate.html:25
#, python-format
msgid "Your current reputation is %(reputation)s points"
-msgstr ""
+msgstr "قوة سمعتك حالياً %(reputation)s نقطة"
#: templates/user_profile/user_moderate.html:27
#, python-format
msgid "User's current reputation is %(reputation)s points"
-msgstr ""
+msgstr "قوة سمعة العضو حالياً %(reputation)s نقطة"
#: templates/user_profile/user_moderate.html:31
msgid "User reputation changed"
-msgstr ""
+msgstr "تم تعديل سمعة العضو"
#: templates/user_profile/user_moderate.html:38
msgid "Subtract"
-msgstr ""
+msgstr "نقص"
#: templates/user_profile/user_moderate.html:39
msgid "Add"
-msgstr "إضاÙØ©"
+msgstr "أضÙ"
#: templates/user_profile/user_moderate.html:43
#, python-format
msgid "Send message to %(username)s"
-msgstr ""
+msgstr "إرسال رسالة للعضو %(username)s"
#: templates/user_profile/user_moderate.html:44
msgid ""
@@ -7209,11 +7210,11 @@ msgstr ""
#: templates/user_profile/user_moderate.html:46
msgid "Message sent"
-msgstr "تم الإرسال"
+msgstr "الرسالة أرسلت"
#: templates/user_profile/user_moderate.html:64
msgid "Send message"
-msgstr "أرسل الرسالة"
+msgstr "إرسال رسالة"
#: templates/user_profile/user_moderate.html:74
msgid ""
@@ -7245,7 +7246,7 @@ msgstr ""
#: templates/user_profile/user_network.html:5
#: templates/user_profile/user_tabs.html:18
msgid "network"
-msgstr "شبكة"
+msgstr "شبكة المتابعة"
#: templates/user_profile/user_network.html:10
#, python-format
@@ -7273,18 +7274,18 @@ msgstr[5] ""
msgid ""
"Your network is empty. Would you like to follow someone? - Just visit their "
"profiles and click \"follow\""
-msgstr ""
+msgstr "شبكتك Ùارغة حالياً. هل تريد متابعة عضو ما؟ تصÙØ­ ملÙÙ‡ الشخصي واضغط على زر (تابع)"
#: templates/user_profile/user_network.html:33
#, python-format
msgid "%(username)s's network is empty"
-msgstr ""
+msgstr "شبكة %(username)s Ùارغة"
#: templates/user_profile/user_recent.html:5
#: templates/user_profile/user_tabs.html:31
#: templates/user_profile/user_tabs.html:33
msgid "activity"
-msgstr "نشاط"
+msgstr "سجل التÙاعل"
#: templates/user_profile/user_recent.html:23
#: templates/user_profile/user_recent.html:27
@@ -7293,12 +7294,12 @@ msgstr "مصدر"
#: templates/user_profile/user_reputation.html:12
msgid "Your karma change log."
-msgstr ""
+msgstr "سجل تغيرات السمعة"
#: templates/user_profile/user_reputation.html:14
#, python-format
msgid "%(user_name)s's karma change log"
-msgstr ""
+msgstr "سجل تغيرات سمعة %(user_name)s"
#: templates/user_profile/user_stats.html:6
#: templates/user_profile/user_tabs.html:7
@@ -7365,45 +7366,45 @@ msgstr "مجاب لـ:"
#: templates/user_profile/user_tabs.html:5
msgid "User profile"
-msgstr "المل٠الشخصي للمستخدم"
+msgstr "مل٠العضو"
#: templates/user_profile/user_tabs.html:10 views/users.py:819
msgid "comments and answers to others questions"
-msgstr ""
+msgstr "التعليق والإجابة على أسئلة الأخرين"
#: templates/user_profile/user_tabs.html:16
msgid "followers and followed users"
-msgstr ""
+msgstr "الأعضاء المتابعين والمÙتابعون"
#: templates/user_profile/user_tabs.html:22
msgid "Graph of user karma"
-msgstr "الرسم البياني لمستخدم النقاط"
+msgstr "رسم بياني لسمعة العضو"
#: templates/user_profile/user_tabs.html:27
msgid "questions that user is following"
-msgstr ""
+msgstr "الأسئلة التي يتابعها العضو"
#: templates/user_profile/user_tabs.html:36 views/users.py:861
msgid "user vote record"
-msgstr ""
+msgstr "سجل أصوات العضو"
#: templates/user_profile/user_tabs.html:38
#: templates/user_profile/user_votes.html:5
msgid "votes"
-msgstr "أصوات"
+msgstr "الأصوات"
#: templates/user_profile/user_tabs.html:42 views/users.py:973
msgid "email subscription settings"
-msgstr ""
+msgstr "إعدادات نشرات وتنبيهات البريد"
#: templates/user_profile/user_tabs.html:48 views/users.py:286
msgid "moderate this user"
-msgstr ""
+msgstr "الإشرا٠على هذا العضو"
#: templates/user_profile/users_answers.html:7
#, python-format
msgid "the answer has been voted for %(answer_score)s times"
-msgstr ""
+msgstr "تم التصويت على الإجابة %(answer_score)s مرة"
#: templates/user_profile/users_answers.html:17
#, python-format
@@ -7419,43 +7420,43 @@ msgstr[5] ""
#: templates/widgets/answer_edit_tips.html:3
#: templates/widgets/question_edit_tips.html:3
msgid "Tips"
-msgstr "إرشادات"
+msgstr "نصائح"
#: templates/widgets/answer_edit_tips.html:6
msgid "give an answer interesting to this community"
-msgstr ""
+msgstr "أعطي جواب يهم هذا المجتمع"
#: templates/widgets/answer_edit_tips.html:9
msgid "try to give an answer, rather than engage into a discussion"
-msgstr "حاول إعطاء جواب، بدلاً من الانخراط ÙÙŠ نقاش"
+msgstr "حاول أن تعطي إجابة شاÙية، بدل من الدخول ÙÙŠ نقاش حول السؤال او موضوعة"
#: templates/widgets/ask_button.html:9
msgid "Ask the Group"
-msgstr ""
+msgstr "أسأل المجموعة"
#: templates/widgets/ask_form.html:22 templates/widgets/ask_form.html.py:24
msgid "Add details (optional)"
-msgstr ""
+msgstr "أضاÙØ© التÙاصيل (إختياري)"
#: templates/widgets/ask_form.html:26
msgid "Add details"
-msgstr ""
+msgstr "إضاÙØ© التÙاصيل"
#: templates/widgets/ask_form.html:59
msgid "Select language"
-msgstr ""
+msgstr "إختيار اللغة"
#: templates/widgets/contributors.html:3
msgid "Contributors"
-msgstr "المساهمين"
+msgstr "المساهمون"
#: templates/widgets/edit_post.html:33
msgid ", one of these is required"
-msgstr ""
+msgstr "، واحدة من هذه مطلوبة"
#: templates/widgets/edit_post.html:42 templates/widgets/edit_post.html:47
msgid "tags:"
-msgstr ""
+msgstr "المواضيع:"
#: templates/widgets/edit_post.html:43
msgid "(required)"
@@ -7469,7 +7470,7 @@ msgstr ""
msgid ""
"To post on behalf of someone else, enter user name <strong>and</strong> "
"email below."
-msgstr ""
+msgstr "للنشر بالنيابة عن عضو أخر، يرجى كتابة أسم المستخدم والبريد بالأسÙÙ„."
#: templates/widgets/footer.html:33
#, python-format
@@ -7478,7 +7479,7 @@ msgstr "هذا الموقع مرخص تحت %(license)s"
#: templates/widgets/footer.html:38
msgid "about"
-msgstr "عن"
+msgstr "عن الموقع"
#: templates/widgets/footer.html:40 templates/widgets/user_navigation.html:26
msgid "help"
@@ -7486,31 +7487,31 @@ msgstr "مساعدة"
#: templates/widgets/footer.html:42
msgid "privacy policy"
-msgstr "av,' hgow,wdm"
+msgstr "بيان الخصوصية"
#: templates/widgets/footer.html:51
msgid "give feedback"
-msgstr "إبداء رأيك"
+msgstr "مقترحات"
#: templates/widgets/group_info.html:3
msgid "Group info"
-msgstr ""
+msgstr "معلومات المجموعة"
#: templates/widgets/group_info.html:26
msgid "edit description"
-msgstr ""
+msgstr "تعديل الوصÙ"
#: templates/widgets/group_info.html:30
msgid "change logo"
-msgstr ""
+msgstr "تعديل اللوجو"
#: templates/widgets/group_info.html:32
msgid "delete logo"
-msgstr ""
+msgstr "حذ٠اللوجو"
#: templates/widgets/group_info.html:36
msgid "add logo"
-msgstr ""
+msgstr "أض٠لوجو"
#: templates/widgets/group_info.html:46
msgid "moderate emailed questions"
@@ -7522,7 +7523,7 @@ msgstr ""
#: templates/widgets/group_info.html:63
msgid "How users join this group?"
-msgstr ""
+msgstr "كي٠ينضم الأعضاء لهذه المجموعة؟"
#: templates/widgets/group_info.html:87
msgid "Can moderate site"
@@ -7530,7 +7531,7 @@ msgstr ""
#: templates/widgets/group_info.html:97
msgid "Allow only read access"
-msgstr ""
+msgstr "السماح Ùقط بالقراءة"
#: templates/widgets/group_info.html:102
msgid "list of email addresses of pre-approved users"
@@ -7574,32 +7575,32 @@ msgstr "العودة للرئيسية"
#: templates/widgets/logo.html:4
#, python-format
msgid "%(site)s logo"
-msgstr "الشعار %(site)s"
+msgstr "لوجو %(site)s"
#: templates/widgets/markdown_help.html:2
msgid "Markdown basics"
-msgstr "أساسيات Markdown"
+msgstr "أساسيات المحرر"
#: templates/widgets/markdown_help.html:6
msgid "*italic*"
-msgstr "*مائل*"
+msgstr "*نص مائل هنا*"
#: templates/widgets/markdown_help.html:9
msgid "**bold**"
-msgstr "**غليظ**"
+msgstr "**نص بارز هنا**"
#: templates/widgets/markdown_help.html:13
msgid "*italic* or _italic_"
-msgstr "*مائل* أو _مائل_"
+msgstr "*italic* أو _italic_"
#: templates/widgets/markdown_help.html:16
msgid "**bold** or __bold__"
-msgstr "**غليظ** أو __غليظ__"
+msgstr "**bold** او __bold__"
#: templates/widgets/markdown_help.html:20
#: templates/widgets/markdown_help.html:24
msgid "text"
-msgstr "نص"
+msgstr "text"
#: templates/widgets/markdown_help.html:24
msgid "image"
@@ -7611,27 +7612,27 @@ msgstr "قائمة مرقمة:"
#: templates/widgets/markdown_help.html:33
msgid "basic HTML tags are also supported"
-msgstr ""
+msgstr "بعض وسوم HTML البسيطة مسموح بها"
#: templates/widgets/markdown_help.html:38
msgid "learn more about Markdown"
-msgstr "معرÙØ© المزيد عن Markdown"
+msgstr "أعر٠المزيد حول محرر Markdown"
#: templates/widgets/meta_nav.html:12
msgid "people & groups"
-msgstr ""
+msgstr "الأعضاء والمجموعات"
#: templates/widgets/meta_nav.html:20
msgid "users"
-msgstr "مستخدمين"
+msgstr "الأعضاء"
#: templates/widgets/meta_nav.html:27
msgid "badges"
-msgstr "شارات"
+msgstr "أوسمة الأعضاء"
#: templates/widgets/question_edit_tips.html:5
msgid "ask a question interesting to this community"
-msgstr "اطرح سؤال مهم ÙÙŠ هذا المجتمع"
+msgstr "أطرح سؤال يخص هذا المجتمع"
#: templates/widgets/question_summary.html:12
msgid "view"
@@ -7669,31 +7670,31 @@ msgstr "الكل"
#: templates/widgets/scope_nav.html:22
msgid "see unanswered questions"
-msgstr "أنظر الأسئلة الغير مجابة"
+msgstr "مشاهدة الأسئلة الغير مجاب عليها بعد. Ùضلاً ساعدنا بالإجابة عليها"
#: templates/widgets/scope_nav.html:22
msgid "UNANSWERED"
-msgstr "غير مجاب"
+msgstr "غير مجابة"
#: templates/widgets/scope_nav.html:27
msgid "see your followed questions"
-msgstr "أنظر للأسئلة التي تتابعها"
+msgstr "مشاهدة الأسئلة التي تهمك وقد قمت بمتابتعها او التÙاعل معها"
#: templates/widgets/scope_nav.html:27
msgid "FOLLOWED"
-msgstr "تتم متابعته"
+msgstr "المتابعة"
#: templates/widgets/scope_nav.html:30
msgid "Please ask your question here"
-msgstr "قم بالسؤال هنا من Ùضلك"
+msgstr "يمكنك كتابة سؤالك هنا"
#: templates/widgets/tag_selector.html:4
msgid "Interesting tags"
-msgstr ""
+msgstr "المواضيع المهمة"
#: templates/widgets/tag_selector.html:22
msgid "Ignored tags"
-msgstr ""
+msgstr "المواضيع الغير مهمة"
#: templates/widgets/tag_selector.html:40
msgid "Subscribed tags"
@@ -7701,11 +7702,11 @@ msgstr ""
#: templates/widgets/tag_selector.html:59
msgid "Show only questions from"
-msgstr ""
+msgstr "أظهر Ùقط الأسئلة من"
#: templates/widgets/tag_selector.html:70
msgid "Send me email alerts for"
-msgstr ""
+msgstr "أرسل لي تنبيهات بالبريد بخصوص"
#: templates/widgets/tag_selector.html:86
msgid "Change frequency of emails"
@@ -7726,27 +7727,27 @@ msgstr ""
#: templates/widgets/three_column_category_selector.html:9
#: templates/widgets/three_column_category_selector.html:11
msgid "(edit categories)"
-msgstr ""
+msgstr "(تعديل التصانيÙ)"
#: templates/widgets/user_long_score_and_badge_summary.html:3
msgid "read only access"
-msgstr ""
+msgstr "صلاحية القراءة Ùقط"
#: templates/widgets/user_long_score_and_badge_summary.html:10
msgid "karma:"
-msgstr "نقاط:"
+msgstr "السمعة:"
#: templates/widgets/user_long_score_and_badge_summary.html:15
msgid "badges:"
-msgstr "الشارات:"
+msgstr "الأوسمة:"
#: templates/widgets/user_navigation.html:17
msgid "sign out"
-msgstr "تسجيل الخروج"
+msgstr "تسجيل خروج"
#: templates/widgets/user_navigation.html:20
msgid "Hi there! Please sign in"
-msgstr ""
+msgstr "تسجيل دخول"
#: templates/widgets/user_navigation.html:23
msgid "settings"
@@ -7759,34 +7760,34 @@ msgstr ""
#: templates/widgets/user_perms.html:1
#, python-format
msgid "Your karma is %(karma)s"
-msgstr ""
+msgstr "قوة سمعتك %(karma)s"
#: templates/widgets/user_perms.html:4
msgid "Karma reflects the value of your contribution to this community."
-msgstr ""
+msgstr "نقاط السمعة هي مقياس لمدى مساهمتك ÙÙŠ بناء هذا المجتمع، ومدى Ùائدتك له."
#: templates/widgets/user_perms.html:13
#, python-format
msgid ""
"Since you are the site %(role)s, you have access to all functions regardless"
" of your karma."
-msgstr ""
+msgstr "بسبب أنك %(role)s ÙÙŠ هذا المجتمع، لك إمكانية إستخدام جميع الصلاحيات، عدى التحكم بمعدل سمعتك."
#: templates/widgets/user_perms.html:15
msgid "The higher is your karma, the more rights you have on this site."
-msgstr ""
+msgstr "كل مازادت نقاط سمعتك كل مازادت صلاحياتك ÙÙŠ هذا المجتمع."
#: templates/widgets/user_perms.html:19
msgid "Currently, you can:"
-msgstr ""
+msgstr "حالياً، لديك الصلاحيات على"
#: templates/widgets/user_perms.html:21
msgid "Post questions, answers and comments"
-msgstr ""
+msgstr "نشر أسئلة، أجوبة وتعليقات"
#: templatetags/extra_filters_jinja.py:332
msgid "no"
-msgstr "كلا"
+msgstr "0"
#: utils/decorators.py:104 views/commands.py:146
msgid "Oops, apologies - there was some error"
@@ -7794,7 +7795,7 @@ msgstr ""
#: utils/decorators.py:123
msgid "Please login to post"
-msgstr "قم بالدخول للإرسال"
+msgstr "يرجى تسجيل الدخول للنشر"
#: utils/decorators.py:219
msgid "Spam was detected on your post, sorry for if this is a mistake"
@@ -7802,7 +7803,7 @@ msgstr ""
#: utils/decorators.py:243
msgid "This function is limited to moderators and administrators"
-msgstr ""
+msgstr "هذه الصلاحية مقتصرة على المراقبين"
#: utils/forms.py:66
msgid "this field is required"
@@ -7810,23 +7811,23 @@ msgstr "هذا الحقل مطلوب"
#: utils/forms.py:93
msgid "Choose a screen name"
-msgstr "اختر اسم للظهور به"
+msgstr "إختيار أسم مستخدم"
#: utils/forms.py:103
msgid "user name is required"
-msgstr "اسم المستخدم مطلوب"
+msgstr "أسم العضو مطلوب"
#: utils/forms.py:104
msgid "sorry, this name is taken, please choose another"
-msgstr "عÙواً، الاسم مستخدم، اختر اسم آخر"
+msgstr "المعذرة، هذا الأسم مستخدم، يرجى إختيار أسم آخر"
#: utils/forms.py:105
msgid "sorry, this name is not allowed, please choose another"
-msgstr "عÙواً، الاسم غير مقبول، اختر اسم آخر"
+msgstr "المعذرة، هذا الأسم غير مسموح به، يرجى إختيار أسم آخر"
#: utils/forms.py:106
msgid "sorry, there is no user with this name"
-msgstr "عÙواً، لا يوجد اسم مستخدم بهذا الاسم"
+msgstr "المعذرة، لا يوجد عضو بهذا الأسم"
#: utils/forms.py:107
msgid "sorry, we have a serious error - user name is taken by several users"
@@ -7834,19 +7835,19 @@ msgstr ""
#: utils/forms.py:108
msgid "user name can only consist of letters, empty space and underscore"
-msgstr ""
+msgstr "أسم المستحدم ممكن أن يتكون من أحر٠ومساÙات Ùارغة Ùˆ علامة \"_\""
#: utils/forms.py:109
msgid "please use at least some alphabetic characters in the user name"
-msgstr ""
+msgstr "Ùضلا إستخدام بعض الأحر٠لأسم المستخدم/العضو"
#: utils/forms.py:110
msgid "symbol \"@\" is not allowed"
-msgstr ""
+msgstr "علامة \"@\" غير مسموح بها"
#: utils/forms.py:222
msgid "Your email <i>(never shared)</i>"
-msgstr "بريدك <i>(لن يتم نشره)</i>"
+msgstr "بريدك <i>(غير ظاهر للغير)</i>"
#: utils/forms.py:224
msgid "email address is required"
@@ -7854,15 +7855,15 @@ msgstr "البريد مطلوب"
#: utils/forms.py:225
msgid "please enter a valid email address"
-msgstr "من Ùضلك قم بإختيار بريد صحيح"
+msgstr "يرجى إدخال بريد صحيح"
#: utils/forms.py:226
msgid "this email is already used by someone else, please choose another"
-msgstr "هذا البريد مستخدم من قبل، اختر بريد آخر"
+msgstr "هذا البريد مستخدم مسبقاً من قبل عضو آخر، يرجى إستخدام بريد آخر."
#: utils/forms.py:227
msgid "this email address is not authorized"
-msgstr ""
+msgstr "هذا البريد غير مصرح له"
#: utils/forms.py:265
msgid "password is required"
@@ -7870,19 +7871,19 @@ msgstr "كلمة المرور مطلوبة"
#: utils/forms.py:268
msgid "Password <i>(please retype)</i>"
-msgstr "كلمة المرور <i>(مرة أخري)</i>"
+msgstr "كلمة المرور <i>(أعد كتابتها)</i>"
#: utils/forms.py:269
msgid "please, retype your password"
-msgstr "من Ùضلك، أعد كلمة المرور"
+msgstr "Ùضلاً قم بإعادة كتابة كلمة المرور"
#: utils/forms.py:270
msgid "sorry, entered passwords did not match, please try again"
-msgstr "عÙواً، كلمة المرور ليست مطابقة التأكيد"
+msgstr "المعذرة، كلمة المرور المدخولة غير متطابقة، يرجى التأكد وإعادة المحاولة"
#: utils/functions.py:102
msgid "2 days ago"
-msgstr "منذ يومان"
+msgstr "منذ يومين"
#: utils/functions.py:104
msgid "yesterday"
@@ -7912,44 +7913,44 @@ msgstr[5] "منذ %(min)d دقائق"
#: views/avatar_views.py:103
msgid "Successfully uploaded a new avatar."
-msgstr "تم تحميل الصورة الجديدة."
+msgstr "تم بنجاح رÙع صورة مصغرة جديدة."
#: views/avatar_views.py:144
msgid "Successfully updated your avatar."
-msgstr "تم بنجاح تجديث صورتك."
+msgstr "تم بنجاح تعديل الصورة المصغرة."
#: views/avatar_views.py:184
msgid "Successfully deleted the requested avatars."
-msgstr "تم حذ٠الصورة المطلوبة."
+msgstr "تم بنجاح حذ٠الصورة الرمزية"
#: views/commands.py:123
msgid "your post was not accepted"
-msgstr ""
+msgstr "مشاركتك لم تقبل"
#: views/commands.py:136
msgid "Sorry, but anonymous users cannot access the inbox"
-msgstr ""
+msgstr "المعذرة، الزوار لا يمكنهم الوصول لصندوق الوارد"
#: views/commands.py:165
msgid "Sorry, anonymous users cannot vote"
-msgstr ""
+msgstr "الزوار لا يمكنهم التصويت"
#: views/commands.py:182
msgid "Sorry you ran out of votes for today"
-msgstr "عذرا،استنÙذت كل Ùرص التصويت لهذا اليوم"
+msgstr "لقد أستنÙذت الحد الأقصى من الأصوات باليوم الواحد"
#: views/commands.py:188
#, python-format
msgid "You have %(votes_left)s votes left for today"
-msgstr ""
+msgstr "تبقى لديك %(votes_left)s صوت لهذا اليوم"
#: views/commands.py:263
msgid "Sorry, something is not right here..."
-msgstr ""
+msgstr "المعذرة، شيء غير صحيح هنا..."
#: views/commands.py:286
msgid "Sorry, but anonymous users cannot accept answers"
-msgstr ""
+msgstr "الزوار لا يمكنهم قبول الأجوبة"
#: views/commands.py:396
#, python-format
@@ -7964,7 +7965,7 @@ msgstr ""
#: views/commands.py:628
msgid "Sorry, could not delete tag"
-msgstr ""
+msgstr "المعذرة، لا يمكن حذ٠الموضوع"
#: views/commands.py:701
#, python-format
@@ -7974,7 +7975,7 @@ msgstr ""
#: views/commands.py:710
#, python-format
msgid "Please sign in to subscribe for: %(tags)s"
-msgstr ""
+msgstr "يرجى تسجيل الدخول للإشتراك بالموضوع %(tags)s"
#: views/commands.py:729
msgid "Create"
@@ -7982,16 +7983,16 @@ msgstr ""
#: views/commands.py:959
msgid "Please sign in to vote"
-msgstr "قم بالدخول للتصويت"
+msgstr "يرجى تسجيل الدخول للتصويت"
#: views/commands.py:980
msgid "Please sign in to delete/restore posts"
-msgstr ""
+msgstr "يرجى تسجيل الدخول لحذÙ/إستعادة هذه المشاركة"
#: views/commands.py:1042
#, python-format
msgid "Group %(name)s does not exist"
-msgstr ""
+msgstr "المجموعة %(name)s غير موجودة"
#: views/commands.py:1408 views/commands.py:1441
msgid "Sorry, looks like sharing request was invalid"
@@ -8000,7 +8001,7 @@ msgstr ""
#: views/commands.py:1464
#, python-format
msgid "%(user)s, welcome to group %(group)s!"
-msgstr ""
+msgstr "%(user)sØŒ مرحباً بك ÙÙŠ مجموعة %(group)s"
#: views/commands.py:1521
msgid "Sorry, only thread moderators can use this function"
@@ -8008,28 +8009,28 @@ msgstr ""
#: views/commands.py:1536
msgid "The answer is now unpublished"
-msgstr ""
+msgstr "هذه الإجابة الآن غير منشورة"
#: views/commands.py:1540
msgid "The answer is now published"
-msgstr ""
+msgstr "هذه الإجابة الآن منشورة"
#: views/meta.py:47
#, python-format
msgid "About %(site)s"
-msgstr "عن الموقع %(site)s"
+msgstr "عن %(site)s"
#: views/meta.py:91
msgid "Please sign in or register to send your feedback"
-msgstr ""
+msgstr "Ùضلاً سجل دخول او سجل عضوية جديدة لإرسال مقترحاتك"
#: views/meta.py:118
msgid "Q&A forum feedback"
-msgstr ""
+msgstr "المقترحات"
#: views/meta.py:122
msgid "Thanks for the feedback!"
-msgstr "شكراً لتعليقك!"
+msgstr "شكراً على مقترحاتك!"
#: views/meta.py:131
msgid "We look forward to hearing your feedback! Please, give it next time :)"
@@ -8037,11 +8038,11 @@ msgstr ""
#: views/meta.py:135
msgid "Privacy policy"
-msgstr "شروط الخصوصية"
+msgstr "بيان الخصوصية"
#: views/meta.py:216
msgid "Suggested tags"
-msgstr ""
+msgstr "المواضيع المقترحة"
#: views/readers.py:256
#, python-format
@@ -8058,23 +8059,23 @@ msgstr "عÙوأ، التعليق تم حذÙÙ‡ Ùˆ لا يمكن الوصول Ø¥
#: views/users.py:287
msgid "moderate user"
-msgstr ""
+msgstr "إدارة المستخدم"
#: views/users.py:529
msgid "user profile"
-msgstr "مل٠المستخدم"
+msgstr "المل٠الشخصي"
#: views/users.py:530
msgid "user profile overview"
-msgstr "مل٠المستخدم عامة"
+msgstr "نظرة عامة للمل٠الشخصي للعضو"
#: views/users.py:650
msgid "recent user activity"
-msgstr "آخر الأنشطة للمستخدم"
+msgstr "أخر أنشطة العضو"
#: views/users.py:651
msgid "profile - recent activity"
-msgstr "مل٠شخصي - آخر التحديثات"
+msgstr "المل٠الشخصي - أخر الأنشطة"
#: views/users.py:682
msgid "group joining requests"
@@ -8082,15 +8083,15 @@ msgstr ""
#: views/users.py:683
msgid "profile - moderation"
-msgstr ""
+msgstr "المل٠الشخصي - الإشراÙ"
#: views/users.py:739
msgid "private messages"
-msgstr ""
+msgstr "الرسائل الخاصة"
#: views/users.py:740
msgid "profile - messages"
-msgstr ""
+msgstr "المل٠الشخصي - الرسائل"
#: views/users.py:820
msgid "profile - responses"
@@ -8098,15 +8099,15 @@ msgstr "مل٠شخصي - الردود"
#: views/users.py:862
msgid "profile - votes"
-msgstr "مل٠شخصي - الأصوات"
+msgstr "المل٠الشخصي - التصويت"
#: views/users.py:883
msgid "user karma"
-msgstr "نقاط المستخدم"
+msgstr "عطاء العضو"
#: views/users.py:884
msgid "Profile - User's Karma"
-msgstr "مل٠شخصي - نقاط المستخدم"
+msgstr "المل٠الشخصي - قوة سمعة العضو"
#: views/users.py:902
msgid "users favorite questions"
@@ -8114,11 +8115,11 @@ msgstr "الأسئلة المÙضلة للمستخدمين"
#: views/users.py:903
msgid "profile - favorite questions"
-msgstr "مل٠شخصي - الأسئلة المÙضلة"
+msgstr "المل٠الشخصي - الأسئلة المÙضلة"
#: views/users.py:944 views/users.py:948
msgid "changes saved"
-msgstr "تم الحÙظ"
+msgstr "تم Ø­Ùظ التعديلات"
#: views/users.py:954
msgid "email updates canceled"
@@ -8126,7 +8127,7 @@ msgstr "تحديثات البريد ألغيت"
#: views/users.py:974
msgid "profile - email subscriptions"
-msgstr "مل٠شخصي - إشتراكات البريد"
+msgstr "المل٠الشخصي - إشتراكات البريد"
#: views/users.py:995
#, python-format
@@ -8135,7 +8136,7 @@ msgstr ""
#: views/writers.py:73
msgid "Sorry, anonymous users cannot upload files"
-msgstr "عÙواً، لا يمكن للمستخدم المجهول تحميل أي ملÙات"
+msgstr "المعذرة، الزوار لا يمكنهم رÙع الملÙات"
#: views/writers.py:91
#, python-format
@@ -8150,7 +8151,7 @@ msgstr "الجد الأقصي لحجم المل٠%(file_size)s كيلو بايØ
#: views/writers.py:112
msgid ""
"Error uploading file. Please contact the site administrator. Thank you."
-msgstr "خطأ أثناء التحميل، قم بالإتصال بالمشر٠العام، شكراً لك."
+msgstr "خطأ ÙÙŠ رÙع الملÙØŒ يرجى مراسلة إدارة المجتمع. شكراً."
#: views/writers.py:209
msgid ""
@@ -8163,7 +8164,7 @@ msgstr "<span class=\"strong big\">مرحباً بك يمكن إرسال السØ
#: views/writers.py:582
msgid "Please log in to answer questions"
-msgstr "من Ùضلك قم بالدخول لإجابة الأسئلة"
+msgstr "Ùضلاً سجل دخول للإجابة على الأسئلة"
#: views/writers.py:708
msgid "This content is forbidden"
@@ -8171,7 +8172,7 @@ msgstr ""
#: views/writers.py:717
msgid "Post not found"
-msgstr ""
+msgstr "لم يتم العثور على المشاركة"
#: views/writers.py:725
#, python-format
diff --git a/askbot/locale/ar/LC_MESSAGES/djangojs.mo b/askbot/locale/ar/LC_MESSAGES/djangojs.mo
index 354fc455..39941002 100644
--- a/askbot/locale/ar/LC_MESSAGES/djangojs.mo
+++ b/askbot/locale/ar/LC_MESSAGES/djangojs.mo
Binary files differ
diff --git a/askbot/locale/ar/LC_MESSAGES/djangojs.po b/askbot/locale/ar/LC_MESSAGES/djangojs.po
index 38a926ec..66d8d8bc 100644
--- a/askbot/locale/ar/LC_MESSAGES/djangojs.po
+++ b/askbot/locale/ar/LC_MESSAGES/djangojs.po
@@ -11,8 +11,8 @@ msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:07-0500\n"
-"PO-Revision-Date: 2013-07-20 23:44+0000\n"
-"Last-Translator: Ahmad Khayyat <akhayyat@gmail.com>\n"
+"PO-Revision-Date: 2013-09-10 07:48+0000\n"
+"Last-Translator: mustafaalbazy <mustafa@albazy.com>\n"
"Language-Team: Arabic (http://www.transifex.com/projects/p/askbot/language/ar/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -155,7 +155,7 @@ msgstr[5] ""
#: media/js/post.js:154 media/js/post.js.c:1269
msgid "tags cannot be empty"
-msgstr ""
+msgstr "Ùضلاً حدد المواضيع (مطلوب)"
#: media/js/post.js:160
msgid "details are required"
@@ -279,7 +279,7 @@ msgstr[5] ""
#: media/js/post.js:845
msgid "<div>Following</div><div class=\"unfollow\">Unfollow</div>"
-msgstr ""
+msgstr "<div>Ù…Ùتابع</div><div class=\"unfollow\">إلغاء المتابعة</div>"
#: media/js/post.js:901
msgid "remove flag"
@@ -299,7 +299,7 @@ msgstr "تم حذ٠المشاركة"
#: media/js/post.js:1218 media/js/post.js.c:1445
msgid "sorry, something is not right here"
-msgstr ""
+msgstr "عذراً، شيء غير صحيح هنا"
#: media/js/post.js:1665
msgid "add comment"
@@ -326,7 +326,7 @@ msgstr ""
#: media/js/post.js:1823
msgid "minor edit (don't send alerts)"
-msgstr ""
+msgstr "تعديل بسيط (لا ترسل تنبيهات بريد)"
#: media/js/post.js:1855
msgid "Are you sure you don't want to post this comment?"
@@ -501,7 +501,7 @@ msgstr "انظر هل يوجد شئ لتصليحه :"
#: media/js/user.js:443
msgid "Please provide description."
-msgstr ""
+msgstr "Ùضل ضع وصÙ."
#: media/js/user.js:446
msgid "Please provide details."
@@ -513,7 +513,7 @@ msgstr "يجب ان تختار سبب لحذ٠الاخر "
#: media/js/user.js:659
msgid "A reason must be selected to reject post."
-msgstr ""
+msgstr "يجب إختيار سبب لرÙض المشاركة."
#: media/js/user.js:708
msgid "Please <a href=\"%(signin_url)s\">signin</a> to follow %(username)s"
@@ -544,7 +544,7 @@ msgstr "إضاÙØ©"
#: media/js/utils.js:99
msgid "and"
-msgstr ""
+msgstr "Ùˆ"
#: media/js/utils.js:117
msgid "click to close"
@@ -556,7 +556,7 @@ msgstr "انقر لتعديل التعليق"
#: media/js/utils.js:905
msgid "convert to answer"
-msgstr ""
+msgstr "تحويل لإجابة"
#: media/js/utils.js:958
msgid "Ok"
@@ -569,7 +569,7 @@ msgstr "إلغاء"
#: media/js/utils.js:1219
#, c-format
msgid "Uploaded file: %s"
-msgstr ""
+msgstr "الملÙات المرÙوعة: %s"
#: media/js/utils.js:1234
msgid "Choose a different image"
@@ -610,7 +610,7 @@ msgstr "Ø­Ùظت"
#: media/js/utils.js:1602
msgid "enabled"
-msgstr ""
+msgstr "Ù…Ùعل"
#: media/js/utils.js:1604
msgid "disabled"
@@ -626,7 +626,7 @@ msgstr "إضاÙØ© مجموعة"
#: media/js/utils.js:2138
msgid "Group %(name)s already exists. Group names are case-insensitive."
-msgstr ""
+msgstr "أسم المجموعة %(name)s محجوز، أسماء المجموعات غير حساسة لحالة الأحرÙ."
#: media/js/utils.js:2311
#, c-format
@@ -635,7 +635,7 @@ msgstr ""
#: media/js/utils.js:3358
msgid "ago"
-msgstr ""
+msgstr "منذ"
#: media/js/utils.js:3359
msgid "from now"
@@ -648,7 +648,7 @@ msgstr "ÙÙŠ حدود دقيقة"
#: media/js/utils.js:3362
#, c-format
msgid "%d minutes"
-msgstr ""
+msgstr "%d دقيقة"
#: media/js/utils.js:3363
msgid "about an hour"
@@ -657,7 +657,7 @@ msgstr "ساعة تÙريباً"
#: media/js/utils.js:3364
#, c-format
msgid "%d hours"
-msgstr ""
+msgstr "%d ساعة"
#: media/js/utils.js:3365 media/js/utils.js.c:3493
msgid "yesterday"
@@ -666,7 +666,7 @@ msgstr "البارحة"
#: media/js/utils.js:3366
#, c-format
msgid "%d days"
-msgstr ""
+msgstr "%d يوم"
#: media/js/utils.js:3367
msgid "about a month"
@@ -675,7 +675,7 @@ msgstr "شهر تÙريباً"
#: media/js/utils.js:3368
#, c-format
msgid "%d months"
-msgstr ""
+msgstr "%d أشهر"
#: media/js/utils.js:3369
msgid "about a year"
@@ -684,55 +684,55 @@ msgstr "سنة تقريباً"
#: media/js/utils.js:3370
#, c-format
msgid "%d years"
-msgstr ""
+msgstr "%d سنة"
#: media/js/utils.js:3468
msgid "Jan"
-msgstr ""
+msgstr "يناير"
#: media/js/utils.js:3469
msgid "Feb"
-msgstr ""
+msgstr "Ùبراير"
#: media/js/utils.js:3470
msgid "Mar"
-msgstr ""
+msgstr "مارس"
#: media/js/utils.js:3471
msgid "Apr"
-msgstr ""
+msgstr "أبريل"
#: media/js/utils.js:3472
msgid "May"
-msgstr ""
+msgstr "مايو"
#: media/js/utils.js:3473
msgid "Jun"
-msgstr ""
+msgstr "يونيو"
#: media/js/utils.js:3474
msgid "Jul"
-msgstr ""
+msgstr "يوليو"
#: media/js/utils.js:3475
msgid "Aug"
-msgstr ""
+msgstr "أغسطس"
#: media/js/utils.js:3476
msgid "Sep"
-msgstr ""
+msgstr "سبتمبر"
#: media/js/utils.js:3477
msgid "Oct"
-msgstr ""
+msgstr "أكتوبر"
#: media/js/utils.js:3478
msgid "Nov"
-msgstr ""
+msgstr "نوÙمبر"
#: media/js/utils.js:3479
msgid "Dec"
-msgstr ""
+msgstr "ديسمبر"
#: media/js/utils.js:3491
msgid "2 days ago"
diff --git a/askbot/locale/de/LC_MESSAGES/django.mo b/askbot/locale/de/LC_MESSAGES/django.mo
index b0fbf9b9..aedd55b1 100644
--- a/askbot/locale/de/LC_MESSAGES/django.mo
+++ b/askbot/locale/de/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/de/LC_MESSAGES/django.po b/askbot/locale/de/LC_MESSAGES/django.po
index 70777dfc..fdd51aa5 100644
--- a/askbot/locale/de/LC_MESSAGES/django.po
+++ b/askbot/locale/de/LC_MESSAGES/django.po
@@ -14,7 +14,7 @@ msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:06-0500\n"
-"PO-Revision-Date: 2013-08-03 14:46+0000\n"
+"PO-Revision-Date: 2013-09-13 16:15+0000\n"
"Last-Translator: Alexander Lieder <enormitas@gmail.com>\n"
"Language-Team: German (http://www.transifex.com/projects/p/askbot/language/de/)\n"
"MIME-Version: 1.0\n"
@@ -111,7 +111,7 @@ msgstr ""
#: forms.py:410 forms.py:1006 models/widgets.py:27
#: templates/widgets/edit_post.html:32 templates/widgets/meta_nav.html:6
msgid "tags"
-msgstr "Schlagwörter"
+msgstr "Tags"
#: forms.py:412
#, python-format
@@ -2026,7 +2026,7 @@ msgstr ""
#: conf/sidebar_question.py:119
msgid "Show related questions in sidebar"
-msgstr "Verwandte / ähnliche Fragen in der Seitenleiste anzeigen"
+msgstr "Verwandte Fragen in der Seitenleiste anzeigen"
#: conf/sidebar_question.py:121
msgid "Uncheck this if you want to hide the list of related questions. "
@@ -6376,8 +6376,8 @@ msgstr "Bitte beachte: %(app_name)s benötigt javascript um korrekt zu funktioni
#, python-format
msgid "each tag must be shorter that %(max_chars)s character"
msgid_plural "each tag must be shorter than %(max_chars)s characters"
-msgstr[0] "Jeder Tag muss länger sein als %(max_chars)s Zeichen"
-msgstr[1] "Jeder Tag muss länger sein als %(max_chars)s Zeichen"
+msgstr[0] "Jedes Schlagwort muss kürzer sein als %(max_chars)s Zeichen"
+msgstr[1] "Jedes Schlagwort muss kürzer sein als %(max_chars)s Zeichen"
#: templates/meta/editor_data.html:7
#, python-format
@@ -6686,7 +6686,7 @@ msgstr "Letztes Update"
#: templates/question/sidebar.html:151
msgid "Related questions"
-msgstr "Verwandte / ähnliche Fragen"
+msgstr "Verwandte Fragen"
#: templates/tags/form_bulk_tag_subscription.html:4
msgid "Tag subscriptions"
diff --git a/askbot/locale/en/LC_MESSAGES/django.mo b/askbot/locale/en/LC_MESSAGES/django.mo
index 9af75244..92662132 100644
--- a/askbot/locale/en/LC_MESSAGES/django.mo
+++ b/askbot/locale/en/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/en/LC_MESSAGES/django.po b/askbot/locale/en/LC_MESSAGES/django.po
index cdff3a26..bbab876b 100644
--- a/askbot/locale/en/LC_MESSAGES/django.po
+++ b/askbot/locale/en/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.7\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-07-13 14:06-0500\n"
+"POT-Creation-Date: 2013-10-16 16:34-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Evgeny Fadeev <evgeny.fadeev@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -25,8 +25,14 @@ msgstr ""
msgid " - "
msgstr ""
-#: feed.py:35 feed.py:109
-msgid "Individual question feed"
+#: feed.py:35
+#, python-format
+msgid "Individual %(question)s feed"
+msgstr ""
+
+#: feed.py:109
+#, python-format
+msgid "Latest %(question)s feed"
msgstr ""
#: forms.py:140
@@ -64,8 +70,9 @@ msgstr ""
msgid "title"
msgstr ""
-#: forms.py:249 templates/embed/ask_by_widget.html:170
-msgid "Please enter your question"
+#: forms.py:249
+#, python-format
+msgid "Please enter your %(question)s"
msgstr ""
#: forms.py:260
@@ -75,39 +82,51 @@ msgid_plural "must have > %d characters"
msgstr[0] ""
msgstr[1] ""
-#: forms.py:270
+#: forms.py:271
#, python-format
-msgid "The question is too long, maximum allowed size is %d characters"
+msgid ""
+"The %(question)s is too long, maximum allowed size is %(length)d characters"
msgstr ""
-#: forms.py:277
+#: forms.py:278
#, python-format
-msgid "The question is too long, maximum allowed size is %d bytes"
+msgid "The %(question)s is too long, maximum allowed size is %(length)d bytes"
msgstr ""
-#: forms.py:309
+#: forms.py:307
msgid "content"
msgstr ""
-#: forms.py:370
+#: forms.py:311
+msgid "post"
+msgstr ""
+
+#: forms.py:318
+#, python-format
+msgid "%(post)s content must be > %(count)d character"
+msgid_plural "%(post)s content must be > %(count)d characters"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forms.py:366
#, python-format
msgid "each tag must be shorter than %(max_chars)d character"
msgid_plural "each tag must be shorter than %(max_chars)d characters"
msgstr[0] ""
msgstr[1] ""
-#: forms.py:407
+#: forms.py:403
msgid ""
"We ran out of space for recording the tags. Please shorten or delete some of "
"them."
msgstr ""
-#: forms.py:410 forms.py:1006 models/widgets.py:27
+#: forms.py:406 forms.py:1006 models/widgets.py:27
#: templates/widgets/edit_post.html:32 templates/widgets/meta_nav.html:6
msgid "tags"
msgstr ""
-#: forms.py:412
+#: forms.py:408
#, python-format
msgid ""
"Tags are short keywords, with no spaces within. Up to %(max_tags)d tag can "
@@ -118,156 +137,163 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: forms.py:439
+#: forms.py:435
#, python-format
msgid "please use %(tag_count)d tag or less"
msgid_plural "please use %(tag_count)d tags or less"
msgstr[0] ""
msgstr[1] ""
-#: forms.py:447
+#: forms.py:443
#, python-format
msgid "At least one of the following tags is required : %(tags)s"
msgstr ""
-#: forms.py:475
+#: forms.py:471
msgid "community wiki (karma is not awarded & many others can edit wiki post)"
msgstr ""
-#: forms.py:479
+#: forms.py:475
+#, python-format
msgid ""
-"if you choose community wiki option, the question and answer do not generate "
-"points and name of author will not be shown"
+"if you choose community wiki option, the %(question)s and answer do not "
+"generate points and name of author will not be shown"
+msgstr ""
+
+#: forms.py:478 conf/words.py:90
+msgid "question"
msgstr ""
-#: forms.py:496
+#: forms.py:492
msgid "update summary:"
msgstr ""
-#: forms.py:498
+#: forms.py:494
msgid ""
"enter a brief summary of your revision (e.g. fixed spelling, grammar, "
"improved style, this field is optional)"
msgstr ""
-#: forms.py:585
+#: forms.py:583
msgid "Enter number of points to add or subtract"
msgstr ""
-#: forms.py:600 const/__init__.py:375
+#: forms.py:598 const/__init__.py:380
msgid "approved"
msgstr ""
-#: forms.py:601 const/__init__.py:376
+#: forms.py:599 const/__init__.py:381
msgid "watched"
msgstr ""
-#: forms.py:602 const/__init__.py:377
+#: forms.py:600 const/__init__.py:382
msgid "suspended"
msgstr ""
-#: forms.py:603 const/__init__.py:378
+#: forms.py:601 const/__init__.py:383
msgid "blocked"
msgstr ""
-#: forms.py:605
+#: forms.py:603
msgid "administrator"
msgstr ""
-#: forms.py:606 const/__init__.py:374
+#: forms.py:604 const/__init__.py:379
msgid "moderator"
msgstr ""
-#: forms.py:625
+#: forms.py:623
msgid "Change status to"
msgstr ""
-#: forms.py:652
+#: forms.py:650
msgid "which one?"
msgstr ""
-#: forms.py:673
+#: forms.py:671
msgid "Cannot change own status"
msgstr ""
-#: forms.py:679
+#: forms.py:677
msgid "Cannot turn other user to moderator"
msgstr ""
-#: forms.py:686
+#: forms.py:684
msgid "Cannot change status of another moderator"
msgstr ""
-#: forms.py:692
+#: forms.py:690
msgid "Cannot change status to admin"
msgstr ""
-#: forms.py:698
+#: forms.py:696
#, python-format
msgid ""
"If you wish to change %(username)s's status, please make a meaningful "
"selection."
msgstr ""
-#: forms.py:708
+#: forms.py:706
msgid "Subject line"
msgstr ""
-#: forms.py:713
+#: forms.py:711
msgid "Message text"
msgstr ""
-#: forms.py:727
+#: forms.py:725
msgid "Your name (optional):"
msgstr ""
-#: forms.py:728
+#: forms.py:726
msgid "Email:"
msgstr ""
-#: forms.py:730
+#: forms.py:728
msgid "Your message:"
msgstr ""
-#: forms.py:735
+#: forms.py:733
msgid "I don't want to give my email or receive a response:"
msgstr ""
-#: forms.py:758
+#: forms.py:756
msgid "Please mark \"I dont want to give my mail\" field."
msgstr ""
-#: forms.py:791
+#: forms.py:789
msgid "keep private within your groups"
msgstr ""
-#: forms.py:830
+#: forms.py:828 templates/ask.html:58 templates/question.html:338
#, fuzzy
msgid "User name:"
msgstr "User login"
-#: forms.py:832
+#: forms.py:830
msgid "Enter name to post on behalf of someone else. Can create new accounts."
msgstr ""
-#: forms.py:839
+#: forms.py:837 templates/question.html:339
msgid "Email address:"
msgstr ""
-#: forms.py:889
+#: forms.py:887
msgid "User name is required with the email"
msgstr ""
-#: forms.py:894
+#: forms.py:892
msgid "Email is required if user name is added"
msgstr ""
-#: forms.py:914 forms.py:957
-msgid "ask anonymously"
+#: forms.py:923
+msgid "post anonymously"
msgstr ""
-#: forms.py:916 forms.py:959
-msgid "Check if you do not want to reveal your name when asking this question"
+#: forms.py:925
+#, python-format
+msgid ""
+"Check if you do not want to reveal your name when posting this %(question)s"
msgstr ""
#: forms.py:947
@@ -275,6 +301,14 @@ msgid ""
"Subject line is expected in the format: [tag1, tag2, tag3,...] question title"
msgstr ""
+#: forms.py:957
+msgid "ask anonymously"
+msgstr ""
+
+#: forms.py:959
+msgid "Check if you do not want to reveal your name when asking this question"
+msgstr ""
+
#: forms.py:1213
msgid ""
"You have asked this question anonymously, if you decide to reveal your "
@@ -403,154 +437,154 @@ msgstr ""
msgid "Your post at %(site_name)s is now published"
msgstr ""
-#: urls.py:44
+#: urls.py:44 conf/words.py:99
msgid "questions"
msgstr ""
-#: urls.py:56
+#: urls.py:57
msgid "question/"
msgstr ""
-#: urls.py:61
+#: urls.py:62
msgid "tags/"
msgstr ""
-#: urls.py:66 urls.py:71 urls.py:78 urls.py:84 urls.py:93 urls.py:100
+#: urls.py:67 urls.py:72 urls.py:79 urls.py:85 urls.py:94 urls.py:101
msgid "users/"
msgstr ""
-#: urls.py:71
+#: urls.py:72
msgid "by-group/"
msgstr ""
-#: urls.py:78 urls.py:159 urls.py:226 urls.py:520
+#: urls.py:79 urls.py:160 urls.py:237 urls.py:531
msgid "edit/"
msgstr ""
-#: urls.py:85
+#: urls.py:86
msgid "subscriptions/"
msgstr ""
-#: urls.py:94
+#: urls.py:95
msgid "select_languages/"
msgstr ""
-#: urls.py:105
+#: urls.py:106
msgid "groups/"
msgstr ""
-#: urls.py:110
+#: urls.py:111
msgid "users/update_has_custom_avatar/"
msgstr ""
-#: urls.py:115 urls.py:120
+#: urls.py:116 urls.py:121
msgid "badges/"
msgstr ""
-#: urls.py:133
+#: urls.py:134
msgid "feedback/"
msgstr ""
-#: urls.py:154
+#: urls.py:155
msgid "about/"
msgstr ""
-#: urls.py:155
+#: urls.py:156
msgid "faq/"
msgstr ""
-#: urls.py:156
+#: urls.py:157
msgid "privacy/"
msgstr ""
-#: urls.py:157
+#: urls.py:158
msgid "help/"
msgstr ""
-#: urls.py:159 urls.py:164
+#: urls.py:160 urls.py:165
msgid "answers/"
msgstr ""
-#: urls.py:164 urls.py:256
+#: urls.py:165 urls.py:267
msgid "revisions/"
msgstr ""
-#: urls.py:221 urls.py:226 urls.py:231 urls.py:236 urls.py:241 urls.py:246
-#: urls.py:256
+#: urls.py:232 urls.py:237 urls.py:242 urls.py:247 urls.py:252 urls.py:257
+#: urls.py:267
msgid "questions/"
msgstr ""
-#: urls.py:221 urls.py:495 urls.py:500 urls.py:505 urls.py:510
+#: urls.py:232 urls.py:506 urls.py:511 urls.py:516 urls.py:521
msgid "ask/"
msgstr ""
-#: urls.py:231
+#: urls.py:242
msgid "retag/"
msgstr ""
-#: urls.py:236
+#: urls.py:247
msgid "close/"
msgstr ""
-#: urls.py:241
+#: urls.py:252
msgid "reopen/"
msgstr ""
-#: urls.py:246
+#: urls.py:257
msgid "answer/"
msgstr ""
-#: urls.py:314
+#: urls.py:325
msgid "tags/subscriptions/"
msgstr ""
-#: urls.py:319
+#: urls.py:330
msgid "tags/subscriptions/delete/"
msgstr ""
-#: urls.py:324
+#: urls.py:335
msgid "tags/subscriptions/create/"
msgstr ""
-#: urls.py:329
+#: urls.py:340
msgid "tags/subscriptions/edit/"
msgstr ""
-#: urls.py:334
+#: urls.py:345
msgid "suggested-tags/"
msgstr ""
-#: urls.py:459
+#: urls.py:470
msgid "messages/"
msgstr ""
-#: urls.py:459
+#: urls.py:470
msgid "markread/"
msgstr ""
-#: urls.py:490 urls.py:495 urls.py:500 urls.py:505 urls.py:510 urls.py:515
-#: urls.py:520 urls.py:525 urls.py:530
+#: urls.py:501 urls.py:506 urls.py:511 urls.py:516 urls.py:521 urls.py:526
+#: urls.py:531 urls.py:536 urls.py:541
msgid "widgets/"
msgstr ""
-#: urls.py:510 deps/django_authopenid/urls.py:20
+#: urls.py:521 deps/django_authopenid/urls.py:20
msgid "complete/"
msgstr ""
-#: urls.py:515
+#: urls.py:526
msgid "create/"
msgstr ""
-#: urls.py:525
+#: urls.py:536
msgid "delete/"
msgstr ""
-#: urls.py:560
+#: urls.py:571
msgid "upload/"
msgstr ""
-#: urls.py:585 setup_templates/settings.py:229
-#: templates/authopenid/providers_javascript.html:7
+#: urls.py:596 setup_templates/settings.py:232
+#: templates/authopenid/providers_javascript.html:8
msgid "account/"
msgstr ""
@@ -713,164 +747,172 @@ msgid "Enable email alerts"
msgstr ""
#: conf/email.py:62
-msgid "Maximum number of news entries in an email alert"
+msgid "Enable HTML-formatted email"
+msgstr ""
+
+#: conf/email.py:63
+msgid "May not be supported by some email clients"
msgstr ""
#: conf/email.py:72
+msgid "Maximum number of news entries in an email alert"
+msgstr ""
+
+#: conf/email.py:82
msgid "Default notification frequency all questions"
msgstr ""
-#: conf/email.py:74
+#: conf/email.py:84
msgid "Option to define frequency of emailed updates for: all questions."
msgstr ""
-#: conf/email.py:86
+#: conf/email.py:96
msgid "Default notification frequency questions asked by the user"
msgstr ""
-#: conf/email.py:88
+#: conf/email.py:98
msgid ""
"Option to define frequency of emailed updates for: Question asked by the "
"user."
msgstr ""
-#: conf/email.py:100
+#: conf/email.py:110
msgid "Default notification frequency questions answered by the user"
msgstr ""
-#: conf/email.py:102
+#: conf/email.py:112
msgid ""
"Option to define frequency of emailed updates for: Question answered by the "
"user."
msgstr ""
-#: conf/email.py:114
+#: conf/email.py:124
msgid ""
"Default notification frequency questions individually "
"selected by the user"
msgstr ""
-#: conf/email.py:117
+#: conf/email.py:127
msgid ""
"Option to define frequency of emailed updates for: Question individually "
"selected by the user."
msgstr ""
-#: conf/email.py:129
+#: conf/email.py:139
msgid ""
"Default notification frequency for mentions and "
"comments"
msgstr ""
-#: conf/email.py:132
+#: conf/email.py:142
msgid ""
"Option to define frequency of emailed updates for: Mentions and comments."
msgstr ""
-#: conf/email.py:143
+#: conf/email.py:153
msgid "Send periodic reminders about unanswered questions"
msgstr ""
-#: conf/email.py:145
+#: conf/email.py:155
msgid ""
"NOTE: in order to use this feature, it is necessary to run the management "
"command \"send_unanswered_question_reminders\" (for example, via a cron job "
"- with an appropriate frequency) "
msgstr ""
-#: conf/email.py:158
+#: conf/email.py:168
msgid "Days before starting to send reminders about unanswered questions"
msgstr ""
-#: conf/email.py:169
+#: conf/email.py:179
msgid ""
"How often to send unanswered question reminders (in days between the "
"reminders sent)."
msgstr ""
-#: conf/email.py:181
+#: conf/email.py:191
msgid "Max. number of reminders to send about unanswered questions"
msgstr ""
-#: conf/email.py:192
+#: conf/email.py:202
msgid "Send periodic reminders to accept the best answer"
msgstr ""
-#: conf/email.py:194
+#: conf/email.py:204
msgid ""
"NOTE: in order to use this feature, it is necessary to run the management "
"command \"send_accept_answer_reminders\" (for example, via a cron job - with "
"an appropriate frequency) "
msgstr ""
-#: conf/email.py:207
+#: conf/email.py:217
msgid "Days before starting to send reminders to accept an answer"
msgstr ""
-#: conf/email.py:218
+#: conf/email.py:228
msgid ""
"How often to send accept answer reminders (in days between the reminders "
"sent)."
msgstr ""
-#: conf/email.py:230
+#: conf/email.py:240
msgid "Max. number of reminders to send to accept the best answer"
msgstr ""
-#: conf/email.py:242
+#: conf/email.py:252
msgid "Require email verification before allowing to post"
msgstr ""
-#: conf/email.py:243
+#: conf/email.py:253
msgid ""
"Active email verification is done by sending a verification key in email"
msgstr ""
-#: conf/email.py:252
+#: conf/email.py:262
msgid "Fake email for anonymous user"
msgstr ""
-#: conf/email.py:253
+#: conf/email.py:263
msgid "Use this setting to control gravatar for email-less user"
msgstr ""
-#: conf/email.py:262
+#: conf/email.py:272
msgid "Allow posting questions by email"
msgstr ""
-#: conf/email.py:264
+#: conf/email.py:274
msgid ""
"Before enabling this setting - please fill out IMAP settings in the settings."
"py file"
msgstr ""
-#: conf/email.py:275
+#: conf/email.py:285
msgid "Replace space in emailed tags with dash"
msgstr ""
-#: conf/email.py:277
+#: conf/email.py:287
msgid ""
"This setting applies to tags written in the subject line of questions asked "
"by email"
msgstr ""
-#: conf/email.py:288
+#: conf/email.py:298
msgid "Enable posting answers and comments by email"
msgstr ""
-#: conf/email.py:291
+#: conf/email.py:301
msgid "To enable this feature make sure lamson is running"
msgstr ""
-#: conf/email.py:302
+#: conf/email.py:312
msgid "Emailed post: when to notify author about publishing"
msgstr ""
-#: conf/email.py:327
+#: conf/email.py:337
msgid "Reply by email hostname"
msgstr ""
-#: conf/email.py:338
+#: conf/email.py:348
msgid ""
"Email replies having fewer words than this number will be posted as comments "
"instead of answers"
@@ -1105,8 +1147,8 @@ msgstr ""
#: conf/forum_data_rules.py:135
msgid ""
-"To use folded mode, please first set minimum question body length to 0. Also "
-"- please make tags optional."
+"<b style=\"color:red;\">To use folded mode, please first set minimum "
+"question body length to 0. Also - please make tags optional.</b>"
msgstr ""
#: conf/forum_data_rules.py:147
@@ -1147,156 +1189,160 @@ msgstr ""
msgid "Enable accepting best answer"
msgstr ""
-#: conf/forum_data_rules.py:231
+#: conf/forum_data_rules.py:233
+msgid "How to sort answers by default"
+msgstr ""
+
+#: conf/forum_data_rules.py:241
msgid "Are tags required?"
msgstr ""
-#: conf/forum_data_rules.py:237
+#: conf/forum_data_rules.py:247
msgid "category tree"
msgstr ""
-#: conf/forum_data_rules.py:238
+#: conf/forum_data_rules.py:248
#, fuzzy
msgid "user input"
msgstr "User login"
-#: conf/forum_data_rules.py:245
+#: conf/forum_data_rules.py:255
msgid "Source of tags"
msgstr ""
-#: conf/forum_data_rules.py:256
+#: conf/forum_data_rules.py:266
msgid "Mandatory tags"
msgstr ""
-#: conf/forum_data_rules.py:259
+#: conf/forum_data_rules.py:269
msgid ""
"At least one of these tags will be required for any new or newly edited "
"question. A mandatory tag may be wildcard, if the wildcard tags are active."
msgstr ""
-#: conf/forum_data_rules.py:271
+#: conf/forum_data_rules.py:281
msgid "Force lowercase the tags"
msgstr ""
-#: conf/forum_data_rules.py:273
+#: conf/forum_data_rules.py:283
msgid ""
"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"
msgstr ""
-#: conf/forum_data_rules.py:287
+#: conf/forum_data_rules.py:297
msgid "Format of tag list"
msgstr ""
-#: conf/forum_data_rules.py:289
+#: conf/forum_data_rules.py:299
msgid ""
"Select the format to show tags in, either as a simple list, or as a tag cloud"
msgstr ""
-#: conf/forum_data_rules.py:301
+#: conf/forum_data_rules.py:311
msgid "Use wildcard tags"
msgstr ""
-#: conf/forum_data_rules.py:303
+#: conf/forum_data_rules.py:313
msgid ""
"Wildcard tags can be used to follow or ignore many tags at once, a valid "
"wildcard tag has a single wildcard at the very end"
msgstr ""
-#: conf/forum_data_rules.py:315
+#: conf/forum_data_rules.py:325
msgid "Use separate set for subscribed tags"
msgstr ""
-#: conf/forum_data_rules.py:317
+#: conf/forum_data_rules.py:327
msgid ""
"If enabled, users will have a third set of tag selections - \"subscribed"
"\" (by email) in additon to \"interesting\" and \"ignored\""
msgstr ""
-#: conf/forum_data_rules.py:325
+#: conf/forum_data_rules.py:335
msgid "Always, for all users"
msgstr ""
-#: conf/forum_data_rules.py:326
+#: conf/forum_data_rules.py:336
msgid "Never, for all users"
msgstr ""
-#: conf/forum_data_rules.py:327
+#: conf/forum_data_rules.py:337
msgid "Let users decide"
msgstr ""
-#: conf/forum_data_rules.py:335
+#: conf/forum_data_rules.py:345
msgid "Publicly show user tag selections"
msgstr ""
-#: conf/forum_data_rules.py:344
+#: conf/forum_data_rules.py:354
msgid "Enable separate tag search box on main page"
msgstr ""
-#: conf/forum_data_rules.py:354
+#: conf/forum_data_rules.py:364
msgid "Default max number of comments to display under posts"
msgstr ""
-#: conf/forum_data_rules.py:365
+#: conf/forum_data_rules.py:375
#, python-format
msgid "Maximum comment length, must be < %(max_len)s"
msgstr ""
-#: conf/forum_data_rules.py:375
+#: conf/forum_data_rules.py:385
msgid "Limit time to edit comments"
msgstr ""
-#: conf/forum_data_rules.py:377
+#: conf/forum_data_rules.py:387
msgid "If unchecked, there will be no time limit to edit the comments"
msgstr ""
-#: conf/forum_data_rules.py:388
+#: conf/forum_data_rules.py:398
msgid "Minutes allowed to edit a comment"
msgstr ""
-#: conf/forum_data_rules.py:389
+#: conf/forum_data_rules.py:399
msgid "To enable this setting, check the previous one"
msgstr ""
-#: conf/forum_data_rules.py:398
+#: conf/forum_data_rules.py:408
msgid "Save comment by pressing <Enter> key"
msgstr ""
-#: conf/forum_data_rules.py:400
+#: conf/forum_data_rules.py:410
msgid ""
"This may be useful when only one-line comments are desired. Will not work "
"with TinyMCE editor."
msgstr ""
-#: conf/forum_data_rules.py:411
+#: conf/forum_data_rules.py:421
msgid "Minimum length of search term for Ajax search"
msgstr ""
-#: conf/forum_data_rules.py:412
+#: conf/forum_data_rules.py:422
msgid "Must match the corresponding database backend setting"
msgstr ""
-#: conf/forum_data_rules.py:421
+#: conf/forum_data_rules.py:431
msgid "Do not make text query sticky in search"
msgstr ""
-#: conf/forum_data_rules.py:423
+#: conf/forum_data_rules.py:433
msgid ""
"Check to disable the \"sticky\" behavior of the search query. This may be "
"useful if you want to move the search bar away from the default position or "
"do not like the default sticky behavior of the text search query."
msgstr ""
-#: conf/forum_data_rules.py:436
+#: conf/forum_data_rules.py:446
msgid "Maximum number of tags per question"
msgstr ""
-#: conf/forum_data_rules.py:448
+#: conf/forum_data_rules.py:458
msgid "Number of questions to list by default"
msgstr ""
-#: conf/forum_data_rules.py:458
+#: conf/forum_data_rules.py:468
msgid "What should \"unanswered question\" mean?"
msgstr ""
@@ -1900,7 +1946,7 @@ msgstr ""
msgid "Main page sidebar"
msgstr ""
-#: conf/sidebar_main.py:20 conf/sidebar_question.py:67
+#: conf/sidebar_main.py:20 conf/sidebar_question.py:76
msgid "Custom sidebar header"
msgstr ""
@@ -1914,7 +1960,7 @@ msgstr ""
#: conf/sidebar_main.py:36 conf/sidebar_main.py:111 conf/sidebar_profile.py:37
#: conf/sidebar_question.py:34 conf/sidebar_question.py:58
-#: conf/sidebar_question.py:84 conf/sidebar_question.py:149
+#: conf/sidebar_question.py:93 conf/sidebar_question.py:158
msgid "Show above only to anonymous users"
msgstr ""
@@ -1949,11 +1995,11 @@ msgid ""
"Uncheck this if you want to hide the tag cloud or tag list from the sidebar "
msgstr ""
-#: conf/sidebar_main.py:94 conf/sidebar_question.py:132
+#: conf/sidebar_main.py:94 conf/sidebar_question.py:141
msgid "Custom sidebar footer"
msgstr ""
-#: conf/sidebar_main.py:97 conf/sidebar_question.py:135
+#: conf/sidebar_main.py:97 conf/sidebar_question.py:144
msgid ""
"Use this area to enter content at the BOTTOM of the sidebarin HTML format. "
"When using this option (as well as the sidebar header), please use the HTML "
@@ -1989,12 +2035,16 @@ msgstr ""
#: conf/sidebar_question.py:45
msgid ""
-"This banner will show above the second answer. When using this option, "
-"please use the HTML validation service to make sure that your input is valid "
-"and works well in all browsers."
+"This banner will show under the first answer. When using this option, please "
+"use the HTML validation service to make sure that your input is valid and "
+"works well in all browsers."
msgstr ""
-#: conf/sidebar_question.py:70
+#: conf/sidebar_question.py:67
+msgid "Show answers banner even if there are no answers"
+msgstr ""
+
+#: conf/sidebar_question.py:79
msgid ""
"Use this area to enter content at the TOP of the sidebarin HTML format. When "
"using this option (as well as the sidebar footer), please use the HTML "
@@ -2002,29 +2052,29 @@ msgid ""
"all browsers."
msgstr ""
-#: conf/sidebar_question.py:92
+#: conf/sidebar_question.py:101
msgid "Show tag list in sidebar"
msgstr ""
-#: conf/sidebar_question.py:94
+#: conf/sidebar_question.py:103
msgid "Uncheck this if you want to hide the tag list from the sidebar "
msgstr ""
-#: conf/sidebar_question.py:105
+#: conf/sidebar_question.py:114
msgid "Show meta information in sidebar"
msgstr ""
-#: conf/sidebar_question.py:107
+#: conf/sidebar_question.py:116
msgid ""
"Uncheck this if you want to hide the meta information about the question "
"(post date, views, last updated). "
msgstr ""
-#: conf/sidebar_question.py:119
+#: conf/sidebar_question.py:128
msgid "Show related questions in sidebar"
msgstr ""
-#: conf/sidebar_question.py:121
+#: conf/sidebar_question.py:130
msgid "Uncheck this if you want to hide the list of related questions. "
msgstr ""
@@ -2112,105 +2162,25 @@ msgstr ""
msgid "To change the logo, select new file, then submit this whole form."
msgstr ""
-#: conf/skin_general_settings.py:34
-msgid "English"
-msgstr ""
-
-#: conf/skin_general_settings.py:35
-msgid "Spanish"
-msgstr ""
-
-#: conf/skin_general_settings.py:36
-msgid "Catalan"
-msgstr ""
-
-#: conf/skin_general_settings.py:37
-msgid "German"
-msgstr ""
-
-#: conf/skin_general_settings.py:38
-msgid "Greek"
-msgstr ""
-
-#: conf/skin_general_settings.py:39
-msgid "Finnish"
-msgstr ""
-
-#: conf/skin_general_settings.py:40
-msgid "French"
-msgstr ""
-
-#: conf/skin_general_settings.py:41
-msgid "Hindi"
-msgstr ""
-
#: conf/skin_general_settings.py:42
-msgid "Hungarian"
-msgstr ""
-
-#: conf/skin_general_settings.py:43
-msgid "Italian"
-msgstr ""
-
-#: conf/skin_general_settings.py:44
-msgid "Japanese"
-msgstr ""
-
-#: conf/skin_general_settings.py:45
-msgid "Korean"
-msgstr ""
-
-#: conf/skin_general_settings.py:46
-msgid "Portuguese"
-msgstr ""
-
-#: conf/skin_general_settings.py:47
-msgid "Brazilian Portuguese"
-msgstr ""
-
-#: conf/skin_general_settings.py:48
-msgid "Romanian"
-msgstr ""
-
-#: conf/skin_general_settings.py:49
-msgid "Russian"
+msgid "Select Language"
msgstr ""
#: conf/skin_general_settings.py:50
-msgid "Serbian"
-msgstr ""
-
-#: conf/skin_general_settings.py:51
-msgid "Turkish"
-msgstr ""
-
-#: conf/skin_general_settings.py:52
-msgid "Vietnamese"
-msgstr ""
-
-#: conf/skin_general_settings.py:53
-msgid "Chinese"
-msgstr ""
-
-#: conf/skin_general_settings.py:54
-msgid "Chinese (Taiwan)"
-msgstr ""
-
-#: conf/skin_general_settings.py:73
msgid "Show logo"
msgstr ""
-#: conf/skin_general_settings.py:75
+#: conf/skin_general_settings.py:52
msgid ""
"Check if you want to show logo in the forum header or uncheck in the case "
"you do not want the logo to appear in the default location"
msgstr ""
-#: conf/skin_general_settings.py:87
+#: conf/skin_general_settings.py:64
msgid "Site favicon"
msgstr ""
-#: conf/skin_general_settings.py:89
+#: conf/skin_general_settings.py:66
#, python-format
msgid ""
"A small 16x16 or 32x32 pixel icon image used to distinguish your site in the "
@@ -2218,40 +2188,40 @@ msgid ""
"href=\"%(favicon_info_url)s\">this page</a>."
msgstr ""
-#: conf/skin_general_settings.py:105
+#: conf/skin_general_settings.py:82
msgid "Password login button"
msgstr ""
-#: conf/skin_general_settings.py:107
+#: conf/skin_general_settings.py:84
msgid ""
"An 88x38 pixel image that is used on the login screen for the password login "
"button."
msgstr ""
-#: conf/skin_general_settings.py:120
+#: conf/skin_general_settings.py:97
msgid "Show all UI functions to all users"
msgstr ""
-#: conf/skin_general_settings.py:122
+#: conf/skin_general_settings.py:99
msgid ""
"If checked, all forum functions will be shown to users, regardless of their "
"reputation. However to use those functions, moderation rules, reputation and "
"other limits will still apply."
msgstr ""
-#: conf/skin_general_settings.py:137
+#: conf/skin_general_settings.py:114
msgid "Select skin"
msgstr ""
-#: conf/skin_general_settings.py:148
+#: conf/skin_general_settings.py:125
msgid "Customize HTML <HEAD>"
msgstr ""
-#: conf/skin_general_settings.py:157
+#: conf/skin_general_settings.py:134
msgid "Custom portion of the HTML <HEAD>"
msgstr ""
-#: conf/skin_general_settings.py:159
+#: conf/skin_general_settings.py:136
msgid ""
"<strong>To use this option</strong>, check \"Customize HTML &lt;HEAD&gt;\" "
"above. Contents of this box will be inserted into the &lt;HEAD&gt; portion "
@@ -2263,11 +2233,11 @@ msgid ""
"please test the site with the W3C HTML validator service."
msgstr ""
-#: conf/skin_general_settings.py:181
+#: conf/skin_general_settings.py:158
msgid "Custom header additions"
msgstr ""
-#: conf/skin_general_settings.py:183
+#: conf/skin_general_settings.py:160
msgid ""
"Header is the bar at the top of the content that contains user info and site "
"links, and is common to all pages. Use this area to enter contents of the "
@@ -2276,21 +2246,21 @@ msgid ""
"sure that your input is valid and works well in all browsers."
msgstr ""
-#: conf/skin_general_settings.py:198
+#: conf/skin_general_settings.py:175
msgid "Site footer mode"
msgstr ""
-#: conf/skin_general_settings.py:200
+#: conf/skin_general_settings.py:177
msgid ""
"Footer is the bottom portion of the content, which is common to all pages. "
"You can disable, customize, or use the default footer."
msgstr ""
-#: conf/skin_general_settings.py:217
+#: conf/skin_general_settings.py:194
msgid "Custom footer (HTML format)"
msgstr ""
-#: conf/skin_general_settings.py:219
+#: conf/skin_general_settings.py:196
msgid ""
"<strong>To enable this function</strong>, please select option 'customize' "
"in the \"Site footer mode\" above. Use this area to enter contents of the "
@@ -2299,21 +2269,21 @@ msgid ""
"that your input is valid and works well in all browsers."
msgstr ""
-#: conf/skin_general_settings.py:234
+#: conf/skin_general_settings.py:211
msgid "Apply custom style sheet (CSS)"
msgstr ""
-#: conf/skin_general_settings.py:236
+#: conf/skin_general_settings.py:213
msgid ""
"Check if you want to change appearance of your form by adding custom style "
"sheet rules (please see the next item)"
msgstr ""
-#: conf/skin_general_settings.py:248
+#: conf/skin_general_settings.py:225
msgid "Custom style sheet (CSS)"
msgstr ""
-#: conf/skin_general_settings.py:250
+#: conf/skin_general_settings.py:227
msgid ""
"<strong>To use this function</strong>, check \"Apply custom style sheet\" "
"option above. The CSS rules added in this window will be applied after the "
@@ -2322,19 +2292,19 @@ msgid ""
"depends (default is empty string) on the url configuration in your urls.py."
msgstr ""
-#: conf/skin_general_settings.py:266
+#: conf/skin_general_settings.py:243
msgid "Add custom javascript"
msgstr ""
-#: conf/skin_general_settings.py:269
+#: conf/skin_general_settings.py:246
msgid "Check to enable javascript that you can enter in the next field"
msgstr ""
-#: conf/skin_general_settings.py:279
+#: conf/skin_general_settings.py:256
msgid "Custom javascript"
msgstr ""
-#: conf/skin_general_settings.py:281
+#: conf/skin_general_settings.py:258
msgid ""
"Type or paste plain javascript that you would like to run on your site. Link "
"to the script will be inserted at the bottom of the HTML output and will be "
@@ -2345,19 +2315,19 @@ msgid ""
"above)."
msgstr ""
-#: conf/skin_general_settings.py:299
+#: conf/skin_general_settings.py:276
msgid "Skin media revision number"
msgstr ""
-#: conf/skin_general_settings.py:301
+#: conf/skin_general_settings.py:278
msgid "Will be set automatically but you can modify it if necessary."
msgstr ""
-#: conf/skin_general_settings.py:312
+#: conf/skin_general_settings.py:289
msgid "Hash to update the media revision number automatically."
msgstr ""
-#: conf/skin_general_settings.py:316
+#: conf/skin_general_settings.py:293
msgid "Will be set automatically, it is not necesary to modify manually."
msgstr ""
@@ -2555,6 +2525,208 @@ msgid ""
"question poster"
msgstr ""
+#: conf/words.py:14
+msgid "Site term vocalbulary"
+msgstr ""
+
+#: conf/words.py:22 conf/words.py:23 templates/ask.html:4
+msgid "Ask Your Question"
+msgstr ""
+
+#: conf/words.py:24 conf/words.py:34 conf/words.py:44 conf/words.py:54
+#: conf/words.py:64
+msgid "Used on a button"
+msgstr ""
+
+#: conf/words.py:32 conf/words.py:33
+msgid "Ask the Group"
+msgstr ""
+
+#: conf/words.py:42 conf/words.py:43
+msgid "Post Your Answer"
+msgstr ""
+
+#: conf/words.py:52 conf/words.py:53
+msgid "Answer Your Own Question"
+msgstr ""
+
+#: conf/words.py:62 conf/words.py:63
+msgid "Edit Your Previous Answer"
+msgstr ""
+
+#: conf/words.py:72 conf/words.py:73
+msgid "asked"
+msgstr ""
+
+#: conf/words.py:81 conf/words.py:82
+msgid "answered"
+msgstr ""
+
+#: conf/words.py:91
+msgid "question (noun, singular)"
+msgstr ""
+
+#: conf/words.py:100
+msgid "questions (noun, plural)"
+msgstr ""
+
+#: conf/words.py:108 templates/widgets/question_summary.html:30
+msgid "answer"
+msgstr ""
+
+#: conf/words.py:109
+msgid "answer (noun, sungular)"
+msgstr ""
+
+#: conf/words.py:117 conf/words.py:118
+msgid "Show only questions from"
+msgstr ""
+
+#: conf/words.py:126 conf/words.py:127
+msgid "Please ask your question here"
+msgstr ""
+
+#: conf/words.py:135 conf/words.py:136
+msgid "Please enter your question"
+msgstr ""
+
+#: conf/words.py:144 conf/words.py:145
+msgid "ask a question interesting to this community"
+msgstr ""
+
+#: conf/words.py:153 conf/words.py:154
+msgid "No questions here."
+msgstr ""
+
+#: conf/words.py:162 conf/words.py:163
+msgid "Please follow some questions or follow some users."
+msgstr ""
+
+#: conf/words.py:171 conf/words.py:172
+msgid "Please feel free to ask your question!"
+msgstr ""
+
+#: conf/words.py:180 conf/words.py:181
+msgid "swap with question"
+msgstr ""
+
+#: conf/words.py:189 conf/words.py:190
+msgid "repost as a question comment"
+msgstr ""
+
+#: conf/words.py:198 conf/words.py:199
+msgid "repost as a comment under older answer"
+msgstr ""
+
+#: conf/words.py:207 conf/words.py:208
+msgid "invite other to help answer this question"
+msgstr ""
+
+#: conf/words.py:216 conf/words.py:217
+msgid "Related questions"
+msgstr ""
+
+#: conf/words.py:225 conf/words.py:226
+msgid "Question Tools"
+msgstr ""
+
+#: conf/words.py:234 conf/words.py:235
+msgid "Phrase: this question is currently shared only with:"
+msgstr ""
+
+#: conf/words.py:243 conf/words.py:244
+msgid "Be the first one to answer this question!"
+msgstr ""
+
+#: conf/words.py:252 conf/words.py:253
+msgid "followed questions"
+msgstr ""
+
+#: conf/words.py:262
+msgid "Phrase: comments and answers to others questions"
+msgstr ""
+
+#: conf/words.py:270 conf/words.py:271
+msgid "You can post questions by emailing them at"
+msgstr ""
+
+#: conf/words.py:279 conf/words.py:280
+msgid "List of questions"
+msgstr ""
+
+#: conf/words.py:288 conf/words.py:289
+msgid "Community gives you awards for your questions, answers and votes"
+msgstr ""
+
+#: conf/words.py:297 conf/words.py:298
+msgid "Close question"
+msgstr ""
+
+#: conf/words.py:306 conf/words.py:307
+msgid "Edit question"
+msgstr ""
+
+#: conf/words.py:315 conf/words.py:316
+msgid "Question - in one sentence"
+msgstr ""
+
+#: conf/words.py:324 conf/words.py:325
+msgid "Retag question"
+msgstr ""
+
+#: conf/words.py:333 conf/words.py:334
+msgid "Reopen question"
+msgstr ""
+
+#: conf/words.py:342 conf/words.py:343
+msgid "There are no unanswered questions here"
+msgstr ""
+
+#: conf/words.py:351 conf/words.py:352
+#: templates/user_profile/user_answers_list.html:5
+msgid "this answer has been selected as correct"
+msgstr ""
+
+#: conf/words.py:360 conf/words.py:361
+msgid "mark this answer as correct"
+msgstr ""
+
+#: conf/words.py:369 conf/words.py:370
+msgid "Login/Signup to Answer"
+msgstr ""
+
+#: conf/words.py:378 conf/words.py:379
+msgid "Your Answer"
+msgstr ""
+
+#: conf/words.py:387 conf/words.py:388
+msgid "Add Answer"
+msgstr ""
+
+#: conf/words.py:396 conf/words.py:397
+msgid "give an answer interesting to this community"
+msgstr ""
+
+#: conf/words.py:405 conf/words.py:406
+msgid "try to give an answer, rather than engage into a discussion"
+msgstr ""
+
+#: conf/words.py:414 conf/words.py:415
+msgid "show only selected answers to enquirers"
+msgstr ""
+
+#: conf/words.py:423 conf/words.py:424
+msgid "UNANSWERED"
+msgstr ""
+
+#: conf/words.py:432 conf/words.py:433
+msgid "Edit Answer"
+msgstr ""
+
+#: conf/words.py:441 conf/words.py:442
+msgid "Answered"
+msgstr ""
+
#: const/__init__.py:11
msgid "duplicate question"
msgstr ""
@@ -2663,284 +2835,296 @@ msgid ""
"%(subject)s\">this link</a>"
msgstr ""
-#: const/__init__.py:122 templates/user_inbox/responses_and_flags.html:9
+#: const/__init__.py:114
+msgid "latest first"
+msgstr ""
+
+#: const/__init__.py:115
+msgid "oldest first"
+msgstr ""
+
+#: const/__init__.py:116
+msgid "most voted first"
+msgstr ""
+
+#: const/__init__.py:126 templates/user_inbox/responses_and_flags.html:9
msgid "all"
msgstr ""
-#: const/__init__.py:123
+#: const/__init__.py:127
msgid "unanswered"
msgstr ""
-#: const/__init__.py:124
+#: const/__init__.py:128
msgid "followed"
msgstr ""
-#: const/__init__.py:129
+#: const/__init__.py:133
msgid "list"
msgstr ""
-#: const/__init__.py:130
+#: const/__init__.py:134
msgid "cloud"
msgstr ""
-#: const/__init__.py:138
+#: const/__init__.py:143
msgid "Question has no answers"
msgstr ""
-#: const/__init__.py:139
+#: const/__init__.py:144
msgid "Question has no accepted answers"
msgstr ""
-#: const/__init__.py:195
+#: const/__init__.py:200
msgid "asked a question"
msgstr ""
-#: const/__init__.py:196
+#: const/__init__.py:201
msgid "answered a question"
msgstr ""
-#: const/__init__.py:197 const/__init__.py:301
+#: const/__init__.py:202 const/__init__.py:306
msgid "commented question"
msgstr ""
-#: const/__init__.py:198 const/__init__.py:302
+#: const/__init__.py:203 const/__init__.py:307
msgid "commented answer"
msgstr ""
-#: const/__init__.py:199
+#: const/__init__.py:204
msgid "edited question"
msgstr ""
-#: const/__init__.py:200
+#: const/__init__.py:205
msgid "edited answer"
msgstr ""
-#: const/__init__.py:201
+#: const/__init__.py:206
msgid "received badge"
msgstr ""
-#: const/__init__.py:202
+#: const/__init__.py:207
msgid "marked best answer"
msgstr ""
-#: const/__init__.py:203
+#: const/__init__.py:208
msgid "upvoted"
msgstr ""
-#: const/__init__.py:204
+#: const/__init__.py:209
msgid "downvoted"
msgstr ""
-#: const/__init__.py:205
+#: const/__init__.py:210
msgid "canceled vote"
msgstr ""
-#: const/__init__.py:206
+#: const/__init__.py:211
msgid "deleted question"
msgstr ""
-#: const/__init__.py:207
+#: const/__init__.py:212
msgid "deleted answer"
msgstr ""
-#: const/__init__.py:208
+#: const/__init__.py:213
msgid "marked offensive"
msgstr ""
-#: const/__init__.py:209
+#: const/__init__.py:214
msgid "updated tags"
msgstr ""
-#: const/__init__.py:210
+#: const/__init__.py:215
msgid "selected favorite"
msgstr ""
-#: const/__init__.py:211
+#: const/__init__.py:216
msgid "completed user profile"
msgstr ""
-#: const/__init__.py:212
+#: const/__init__.py:217
msgid "email update sent to user"
msgstr ""
-#: const/__init__.py:213
+#: const/__init__.py:218
msgid "a post was shared"
msgstr ""
-#: const/__init__.py:216
+#: const/__init__.py:221
msgid "reminder about unanswered questions sent"
msgstr ""
-#: const/__init__.py:220
+#: const/__init__.py:225
msgid "reminder about accepting the best answer sent"
msgstr ""
-#: const/__init__.py:222
+#: const/__init__.py:227
msgid "mentioned in the post"
msgstr ""
-#: const/__init__.py:225
+#: const/__init__.py:230
msgid "created tag description"
msgstr ""
-#: const/__init__.py:229
+#: const/__init__.py:234
msgid "updated tag description"
msgstr ""
-#: const/__init__.py:231
+#: const/__init__.py:236
msgid "made a new post"
msgstr ""
-#: const/__init__.py:234
+#: const/__init__.py:239
msgid "made an edit"
msgstr ""
-#: const/__init__.py:238
+#: const/__init__.py:243
msgid "created post reject reason"
msgstr ""
-#: const/__init__.py:242
+#: const/__init__.py:247
msgid "updated post reject reason"
msgstr ""
-#: const/__init__.py:300
+#: const/__init__.py:305
msgid "answered question"
msgstr ""
-#: const/__init__.py:303
+#: const/__init__.py:308
msgid "accepted answer"
msgstr ""
-#: const/__init__.py:307
+#: const/__init__.py:312
msgid "[closed]"
msgstr ""
-#: const/__init__.py:308
+#: const/__init__.py:313
msgid "[deleted]"
msgstr ""
-#: const/__init__.py:309 views/readers.py:642
+#: const/__init__.py:314 views/readers.py:681
msgid "initial version"
msgstr ""
-#: const/__init__.py:310
+#: const/__init__.py:315
msgid "retagged"
msgstr ""
-#: const/__init__.py:311
+#: const/__init__.py:316
msgid "[private]"
msgstr ""
-#: const/__init__.py:320
+#: const/__init__.py:325
msgid "show all tags"
msgstr ""
-#: const/__init__.py:321 const/__init__.py:330 const/__init__.py:336
-#: const/__init__.py:342
+#: const/__init__.py:326 const/__init__.py:335 const/__init__.py:341
+#: const/__init__.py:347
msgid "exclude ignored tags"
msgstr ""
-#: const/__init__.py:322 const/__init__.py:331 const/__init__.py:343
+#: const/__init__.py:327 const/__init__.py:336 const/__init__.py:348
msgid "only interesting tags"
msgstr ""
-#: const/__init__.py:326 const/__init__.py:337 const/__init__.py:344
+#: const/__init__.py:331 const/__init__.py:342 const/__init__.py:349
msgid "only subscribed tags"
msgstr ""
-#: const/__init__.py:329 const/__init__.py:335 const/__init__.py:341
+#: const/__init__.py:334 const/__init__.py:340 const/__init__.py:346
msgid "email for all tags"
msgstr ""
-#: const/__init__.py:348
+#: const/__init__.py:353
msgid "instantly"
msgstr ""
-#: const/__init__.py:349
+#: const/__init__.py:354
msgid "daily"
msgstr ""
-#: const/__init__.py:350
+#: const/__init__.py:355
msgid "weekly"
msgstr ""
-#: const/__init__.py:351
+#: const/__init__.py:356
msgid "no email"
msgstr ""
-#: const/__init__.py:358
+#: const/__init__.py:363
msgid "identicon"
msgstr ""
-#: const/__init__.py:359
+#: const/__init__.py:364
msgid "mystery-man"
msgstr ""
-#: const/__init__.py:360
+#: const/__init__.py:365
msgid "monsterid"
msgstr ""
-#: const/__init__.py:361
+#: const/__init__.py:366
msgid "wavatar"
msgstr ""
-#: const/__init__.py:362
+#: const/__init__.py:367
msgid "retro"
msgstr ""
-#: const/__init__.py:409 templates/badges.html:33
+#: const/__init__.py:414 templates/badges.html:34
msgid "gold"
msgstr ""
-#: const/__init__.py:410 templates/badges.html:43
+#: const/__init__.py:415 templates/badges.html:44
msgid "silver"
msgstr ""
-#: const/__init__.py:411 templates/badges.html:50
+#: const/__init__.py:416 templates/badges.html:51
msgid "bronze"
msgstr ""
-#: const/__init__.py:423
+#: const/__init__.py:428
msgid "None"
msgstr ""
-#: const/__init__.py:424
+#: const/__init__.py:429
msgid "Gravatar"
msgstr ""
-#: const/__init__.py:425
+#: const/__init__.py:430
msgid "Uploaded Avatar"
msgstr ""
-#: const/__init__.py:429
+#: const/__init__.py:434
msgid "date descendant"
msgstr ""
-#: const/__init__.py:430
+#: const/__init__.py:435
msgid "date ascendant"
msgstr ""
-#: const/__init__.py:431
+#: const/__init__.py:436
msgid "activity descendant"
msgstr ""
-#: const/__init__.py:432
+#: const/__init__.py:437
msgid "activity ascendant"
msgstr ""
-#: const/__init__.py:433
+#: const/__init__.py:438
msgid "answers descendant"
msgstr ""
-#: const/__init__.py:434
+#: const/__init__.py:439
msgid "answers ascendant"
msgstr ""
-#: const/__init__.py:435
+#: const/__init__.py:440
msgid "votes descendant"
msgstr ""
-#: const/__init__.py:436
+#: const/__init__.py:441
msgid "votes ascendant"
msgstr ""
@@ -3031,7 +3215,7 @@ msgid ""
"reach a resolution."
msgstr ""
-#: const/message_keys.py:52 models/__init__.py:1136
+#: const/message_keys.py:52 models/__init__.py:1158
msgid ""
"Sorry, your account appears to be suspended and you cannot make new posts "
"until this issue is resolved. You can, however edit your existing posts. "
@@ -3044,7 +3228,7 @@ msgid ""
"screen name, if necessary."
msgstr ""
-#: deps/django_authopenid/forms.py:112 deps/django_authopenid/views.py:206
+#: deps/django_authopenid/forms.py:112 deps/django_authopenid/views.py:208
msgid "i-names are not supported"
msgstr ""
@@ -3069,35 +3253,37 @@ msgstr ""
msgid "Passwords did not match"
msgstr ""
-#: deps/django_authopenid/forms.py:300
+#: deps/django_authopenid/forms.py:300 deps/django_authopenid/forms.py:355
#, python-format
-msgid "Please choose password > %(len)s characters"
+msgid "choose password > %(len)s characters"
msgstr ""
-#: deps/django_authopenid/forms.py:338
-msgid "Current password"
+#: deps/django_authopenid/forms.py:340 utils/forms.py:265
+msgid "password is required"
msgstr ""
-#: deps/django_authopenid/forms.py:349
-msgid ""
-"Old password is incorrect. Please enter the correct "
-"password."
+#: deps/django_authopenid/forms.py:346
+msgid "retype your password"
+msgstr ""
+
+#: deps/django_authopenid/forms.py:366 utils/forms.py:270
+msgid "entered passwords did not match, please try again"
msgstr ""
-#: deps/django_authopenid/forms.py:399
+#: deps/django_authopenid/forms.py:416
msgid "Sorry, we don't have this email address in the database"
msgstr ""
-#: deps/django_authopenid/forms.py:438
+#: deps/django_authopenid/forms.py:455
msgid "Your user name (<i>required</i>)"
msgstr ""
-#: deps/django_authopenid/forms.py:455
+#: deps/django_authopenid/forms.py:472
msgid "sorry, there is no such user name"
msgstr ""
#: deps/django_authopenid/urls.py:14 deps/django_authopenid/urls.py:20
-#: deps/django_authopenid/urls.py:23 setup_templates/settings.py:229
+#: deps/django_authopenid/urls.py:23 setup_templates/settings.py:232
msgid "signin/"
msgstr ""
@@ -3121,15 +3307,15 @@ msgstr ""
msgid "signup/"
msgstr ""
-#: deps/django_authopenid/urls.py:38
+#: deps/django_authopenid/urls.py:43
msgid "logout/"
msgstr ""
-#: deps/django_authopenid/urls.py:43
+#: deps/django_authopenid/urls.py:48
msgid "recover/"
msgstr ""
-#: deps/django_authopenid/urls.py:45
+#: deps/django_authopenid/urls.py:50
msgid "verify-email/"
msgstr ""
@@ -3138,7 +3324,7 @@ msgstr ""
msgid "%(site)s user name and password"
msgstr ""
-#: deps/django_authopenid/util.py:385 templates/authopenid/signin.html:117
+#: deps/django_authopenid/util.py:385 templates/authopenid/signin.html:120
#: templates/authopenid/widget_signin.html:120
msgid "Create a password-protected account"
msgstr ""
@@ -3225,88 +3411,88 @@ msgstr ""
msgid "Sign in with your %(provider)s account"
msgstr ""
-#: deps/django_authopenid/views.py:213
+#: deps/django_authopenid/views.py:215
#, python-format
msgid "OpenID %(openid_url)s is invalid"
msgstr ""
-#: deps/django_authopenid/views.py:391
+#: deps/django_authopenid/views.py:394
msgid ""
"Sorry, there was some problem connecting to the login provider, please try "
"again or use another login method"
msgstr ""
-#: deps/django_authopenid/views.py:520
+#: deps/django_authopenid/views.py:523 deps/django_authopenid/views.py:798
msgid "Your new password is saved"
msgstr ""
-#: deps/django_authopenid/views.py:568 deps/django_authopenid/views.py:583
+#: deps/django_authopenid/views.py:571 deps/django_authopenid/views.py:586
#, python-format
msgid ""
"Unfortunately, there was some problem when connecting to %(provider)s, "
"please try again or use another provider"
msgstr ""
-#: deps/django_authopenid/views.py:613
+#: deps/django_authopenid/views.py:616
msgid "The login password combination was not correct"
msgstr ""
-#: deps/django_authopenid/views.py:717
+#: deps/django_authopenid/views.py:720
msgid "Please click any of the icons below to sign in"
msgstr ""
-#: deps/django_authopenid/views.py:719
+#: deps/django_authopenid/views.py:722
msgid "Account recovery email sent"
msgstr ""
-#: deps/django_authopenid/views.py:722
+#: deps/django_authopenid/views.py:725
msgid "Please add one or more login methods."
msgstr ""
-#: deps/django_authopenid/views.py:724
+#: deps/django_authopenid/views.py:727
msgid "If you wish, please add, remove or re-validate your login methods"
msgstr ""
-#: deps/django_authopenid/views.py:726
+#: deps/django_authopenid/views.py:729
msgid "Please wait a second! Your account is recovered, but ..."
msgstr ""
-#: deps/django_authopenid/views.py:728
+#: deps/django_authopenid/views.py:731
msgid "Sorry, this account recovery key has expired or is invalid"
msgstr ""
-#: deps/django_authopenid/views.py:801
+#: deps/django_authopenid/views.py:818
#, python-format
msgid "Login method %(provider_name)s does not exist"
msgstr ""
-#: deps/django_authopenid/views.py:807
+#: deps/django_authopenid/views.py:824
msgid "Oops, sorry - there was some error - please try again"
msgstr ""
-#: deps/django_authopenid/views.py:882
+#: deps/django_authopenid/views.py:905
msgid ""
"If you are trying to sign in to another account, please sign out first. "
"Otherwise, please report the incident to the site administrator."
msgstr ""
-#: deps/django_authopenid/views.py:914
+#: deps/django_authopenid/views.py:937
#, python-format
msgid "Your %(provider)s login works fine"
msgstr ""
-#: deps/django_authopenid/views.py:1112
+#: deps/django_authopenid/views.py:1135
msgid ""
"Sorry, registration failed. The token can be already used or has expired. "
"Please try again"
msgstr ""
-#: deps/django_authopenid/views.py:1257
+#: deps/django_authopenid/views.py:1280
#, python-format
msgid "Recover your %(site)s account"
msgstr ""
-#: deps/django_authopenid/views.py:1292
+#: deps/django_authopenid/views.py:1315
msgid "Please check your email and visit the enclosed link."
msgstr ""
@@ -3398,23 +3584,23 @@ msgid ""
"of your user account</p>"
msgstr ""
-#: mail/lamson_handlers.py:160
+#: mail/lamson_handlers.py:162
msgid ""
"You were replying to an email address unknown to the system or "
"you were replying from a different address from the one where "
"you received the notification."
msgstr ""
-#: mail/lamson_handlers.py:251
+#: mail/lamson_handlers.py:265
#, python-format
msgid "Re: Welcome to %(site_name)s"
msgstr ""
-#: mail/lamson_handlers.py:258
+#: mail/lamson_handlers.py:272
msgid "Please reply to the welcome email without editing it"
msgstr ""
-#: mail/lamson_handlers.py:318
+#: mail/lamson_handlers.py:340
#, python-format
msgid "Re: %s"
msgstr ""
@@ -3432,14 +3618,14 @@ msgstr ""
msgid "Please accept the best answer for these questions:"
msgstr ""
-#: management/commands/send_email_alerts.py:434
+#: management/commands/send_email_alerts.py:436
#, python-format
msgid "%(question_count)d updated question about %(topics)s"
msgid_plural "%(question_count)d updated questions about %(topics)s"
msgstr[0] ""
msgstr[1] ""
-#: management/commands/send_email_alerts.py:455
+#: management/commands/send_email_alerts.py:457
msgid "new question"
msgstr ""
@@ -3455,90 +3641,94 @@ msgstr[1] ""
msgid "Please log in to use %s"
msgstr ""
-#: models/__init__.py:569 models/__init__.py:1388 views/writers.py:226
+#: models/__init__.py:591 models/__init__.py:1410 views/writers.py:226
msgid "Sorry, but you have only read access"
msgstr ""
-#: models/__init__.py:573
+#: models/__init__.py:595
msgid "Sorry, this operation is not allowed"
msgstr ""
-#: models/__init__.py:623
+#: models/__init__.py:645
msgid ""
"Sorry, you cannot accept or unaccept best answers because your account is "
"blocked"
msgstr ""
-#: models/__init__.py:627
+#: models/__init__.py:649
msgid ""
"Sorry, you cannot accept or unaccept best answers because your account is "
"suspended"
msgstr ""
-#: models/__init__.py:641
+#: models/__init__.py:663
#, python-format
msgid ""
">%(points)s points required to accept or unaccept your own answer to your "
"own question"
msgstr ""
-#: models/__init__.py:665
+#: models/__init__.py:687
#, python-format
msgid ""
"Sorry, you will be able to accept this answer only after %(will_be_able_at)s"
msgstr ""
-#: models/__init__.py:674
+#: models/__init__.py:696
#, python-format
msgid ""
"Sorry, only moderators or original author of the question - %(username)s - "
"can accept or unaccept the best answer"
msgstr ""
-#: models/__init__.py:697
+#: models/__init__.py:719
msgid "Sorry, you cannot vote for your own posts"
msgstr ""
-#: models/__init__.py:701
-msgid "Sorry your account appears to be blocked "
+#: models/__init__.py:723
+msgid ""
+"Sorry your account appears to be blocked and you cannot vote - please "
+"contact the site administrator to resolve the issue"
msgstr ""
-#: models/__init__.py:706
-msgid "Sorry your account appears to be suspended "
+#: models/__init__.py:728
+msgid ""
+"Sorry your account appears to be suspended and you cannot vote - please "
+"contact the site administrator to resolve the issue"
msgstr ""
-#: models/__init__.py:716
+#: models/__init__.py:738
#, python-format
msgid ">%(points)s points required to upvote"
msgstr ""
-#: models/__init__.py:722
+#: models/__init__.py:744
#, python-format
msgid ">%(points)s points required to downvote"
msgstr ""
-#: models/__init__.py:737
+#: models/__init__.py:759
msgid "Sorry, blocked users cannot upload files"
msgstr ""
-#: models/__init__.py:738
+#: models/__init__.py:760
msgid "Sorry, suspended users cannot upload files"
msgstr ""
-#: models/__init__.py:740
+#: models/__init__.py:762
#, python-format
msgid "sorry, file uploading requires karma >%(min_rep)s"
msgstr ""
-#: models/__init__.py:759
+#: models/__init__.py:781
msgid "Could not post, because your karma is insufficient to publish links"
msgstr ""
-#: models/__init__.py:785
+#: models/__init__.py:807
msgid "Sorry, you already gave an answer, please edit it instead."
msgstr ""
-#: models/__init__.py:809
+#: models/__init__.py:831
#, python-format
msgid ""
"Sorry, comments (except the last one) are editable only within %(minutes)s "
@@ -3549,56 +3739,56 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: models/__init__.py:821
+#: models/__init__.py:843
msgid "Sorry, but only post owners or moderators can edit comments"
msgstr ""
-#: models/__init__.py:850
+#: models/__init__.py:872
msgid ""
"Sorry, since your account is suspended you can comment only your own posts"
msgstr ""
-#: models/__init__.py:854
+#: models/__init__.py:876
#, python-format
msgid ""
"Sorry, to comment any post a minimum reputation of %(min_rep)s points is "
"required. You can still comment your own posts and answers to your questions"
msgstr ""
-#: models/__init__.py:884
+#: models/__init__.py:906
msgid ""
"This post has been deleted and can be seen only by post owners, site "
"administrators and moderators"
msgstr ""
-#: models/__init__.py:901
+#: models/__init__.py:923
msgid ""
"Sorry, only moderators, site administrators and post owners can edit deleted "
"posts"
msgstr ""
-#: models/__init__.py:917
+#: models/__init__.py:939
msgid "Sorry, since your account is blocked you cannot edit posts"
msgstr ""
-#: models/__init__.py:921
+#: models/__init__.py:943
msgid "Sorry, since your account is suspended you can edit only your own posts"
msgstr ""
-#: models/__init__.py:926
+#: models/__init__.py:948
#, python-format
msgid ""
"Sorry, to edit wiki posts, a minimum reputation of %(min_rep)s is required"
msgstr ""
-#: models/__init__.py:933
+#: models/__init__.py:955
#, python-format
msgid ""
"Sorry, to edit other people's posts, a minimum reputation of %(min_rep)s is "
"required"
msgstr ""
-#: models/__init__.py:996
+#: models/__init__.py:1018
msgid ""
"Sorry, cannot delete your question since it has an upvoted answer posted by "
"someone else"
@@ -3608,101 +3798,101 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: models/__init__.py:1011
+#: models/__init__.py:1033
msgid "Sorry, since your account is blocked you cannot delete posts"
msgstr ""
-#: models/__init__.py:1015
+#: models/__init__.py:1037
msgid ""
"Sorry, since your account is suspended you can delete only your own posts"
msgstr ""
-#: models/__init__.py:1019
+#: models/__init__.py:1041
#, python-format
msgid ""
"Sorry, to delete other people's posts, a minimum reputation of %(min_rep)s "
"is required"
msgstr ""
-#: models/__init__.py:1040
+#: models/__init__.py:1062
msgid "Sorry, since your account is blocked you cannot close questions"
msgstr ""
-#: models/__init__.py:1044
+#: models/__init__.py:1066
msgid "Sorry, since your account is suspended you cannot close questions"
msgstr ""
-#: models/__init__.py:1048
+#: models/__init__.py:1070
#, python-format
msgid ""
"Sorry, to close other people' posts, a minimum reputation of %(min_rep)s is "
"required"
msgstr ""
-#: models/__init__.py:1057
+#: models/__init__.py:1079
#, python-format
msgid ""
"Sorry, to close own question a minimum reputation of %(min_rep)s is required"
msgstr ""
-#: models/__init__.py:1084
+#: models/__init__.py:1106
#, python-format
msgid ""
"Sorry, only administrators, moderators or post owners with reputation > "
"%(min_rep)s can reopen questions."
msgstr ""
-#: models/__init__.py:1090
+#: models/__init__.py:1112
#, python-format
msgid ""
"Sorry, to reopen own question a minimum reputation of %(min_rep)s is required"
msgstr ""
-#: models/__init__.py:1095
+#: models/__init__.py:1117
msgid "Sorry, you cannot reopen questions because your account is blocked"
msgstr ""
-#: models/__init__.py:1100
+#: models/__init__.py:1122
msgid "Sorry, you cannot reopen questions because your account is suspended"
msgstr ""
-#: models/__init__.py:1123
+#: models/__init__.py:1145
msgid "You have flagged this question before and cannot do it more than once"
msgstr ""
-#: models/__init__.py:1131
+#: models/__init__.py:1153
msgid "Sorry, since your account is blocked you cannot flag posts as offensive"
msgstr ""
-#: models/__init__.py:1142
+#: models/__init__.py:1164
#, python-format
msgid ""
"Sorry, to flag posts as offensive a minimum reputation of %(min_rep)s is "
"required"
msgstr ""
-#: models/__init__.py:1163
+#: models/__init__.py:1185
#, python-format
msgid ""
"Sorry, you have exhausted the maximum number of %(max_flags_per_day)s "
"offensive flags per day."
msgstr ""
-#: models/__init__.py:1175
+#: models/__init__.py:1197
msgid "cannot remove non-existing flag"
msgstr ""
-#: models/__init__.py:1181
+#: models/__init__.py:1203
msgid "Sorry, since your account is blocked you cannot remove flags"
msgstr ""
-#: models/__init__.py:1185
+#: models/__init__.py:1207
msgid ""
"Sorry, your account appears to be suspended and you cannot remove flags. "
"Please contact the forum administrator to reach a resolution."
msgstr ""
-#: models/__init__.py:1191
+#: models/__init__.py:1213
#, python-format
msgid "Sorry, to flag posts a minimum reputation of %(min_rep)d is required"
msgid_plural ""
@@ -3710,221 +3900,221 @@ msgid_plural ""
msgstr[0] ""
msgstr[1] ""
-#: models/__init__.py:1210
+#: models/__init__.py:1232
msgid "you don't have the permission to remove all flags"
msgstr ""
-#: models/__init__.py:1211
+#: models/__init__.py:1233
msgid "no flags for this entry"
msgstr ""
-#: models/__init__.py:1235
+#: models/__init__.py:1257
msgid ""
"Sorry, only question owners, site administrators and moderators can retag "
"deleted questions"
msgstr ""
-#: models/__init__.py:1243
+#: models/__init__.py:1265
msgid "Sorry, since your account is blocked you cannot retag questions"
msgstr ""
-#: models/__init__.py:1247
+#: models/__init__.py:1269
msgid ""
"Sorry, since your account is suspended you can retag only your own questions"
msgstr ""
-#: models/__init__.py:1251
+#: models/__init__.py:1273
#, python-format
msgid ""
"Sorry, to retag questions a minimum reputation of %(min_rep)s is required"
msgstr ""
-#: models/__init__.py:1270
+#: models/__init__.py:1292
msgid "Sorry, since your account is blocked you cannot delete comment"
msgstr ""
-#: models/__init__.py:1274
+#: models/__init__.py:1296
msgid ""
"Sorry, since your account is suspended you can delete only your own comments"
msgstr ""
-#: models/__init__.py:1278
+#: models/__init__.py:1300
#, python-format
msgid "Sorry, to delete comments reputation of %(min_rep)s is required"
msgstr ""
-#: models/__init__.py:1303
+#: models/__init__.py:1325
msgid "sorry, but older votes cannot be revoked"
msgstr ""
-#: models/__init__.py:1995 utils/functions.py:98
+#: models/__init__.py:2045 utils/functions.py:98
#, python-format
msgid "on %(date)s"
msgstr ""
-#: models/__init__.py:1997
+#: models/__init__.py:2047
msgid "in two days"
msgstr ""
-#: models/__init__.py:1999
+#: models/__init__.py:2049
msgid "tomorrow"
msgstr ""
-#: models/__init__.py:2001
+#: models/__init__.py:2051
#, python-format
msgid "in %(hr)d hour"
msgid_plural "in %(hr)d hours"
msgstr[0] ""
msgstr[1] ""
-#: models/__init__.py:2003
+#: models/__init__.py:2053
#, python-format
msgid "in %(min)d min"
msgid_plural "in %(min)d mins"
msgstr[0] ""
msgstr[1] ""
-#: models/__init__.py:2004
+#: models/__init__.py:2054
#, python-format
msgid "%(days)d day"
msgid_plural "%(days)d days"
msgstr[0] ""
msgstr[1] ""
-#: models/__init__.py:2006
+#: models/__init__.py:2056
#, python-format
msgid ""
"New users must wait %(days)s before answering their own question. You can "
"post an answer %(left)s"
msgstr ""
-#: models/__init__.py:2194 templates/email/feedback_email.txt:9
+#: models/__init__.py:2244 templates/email/feedback_email.txt:9
msgid "Anonymous"
msgstr ""
-#: models/__init__.py:2298
+#: models/__init__.py:2348
msgid "Site Adminstrator"
msgstr ""
-#: models/__init__.py:2300
+#: models/__init__.py:2350
msgid "Forum Moderator"
msgstr ""
-#: models/__init__.py:2302
+#: models/__init__.py:2352
msgid "Suspended User"
msgstr ""
-#: models/__init__.py:2304
+#: models/__init__.py:2354
msgid "Blocked User"
msgstr ""
-#: models/__init__.py:2306
+#: models/__init__.py:2356
msgid "Registered User"
msgstr ""
-#: models/__init__.py:2308
+#: models/__init__.py:2358
msgid "Watched User"
msgstr ""
-#: models/__init__.py:2310
+#: models/__init__.py:2360
msgid "Approved User"
msgstr ""
-#: models/__init__.py:2495
+#: models/__init__.py:2551
#, python-format
msgid "%(username)s karma is %(reputation)s"
msgstr ""
-#: models/__init__.py:2508
+#: models/__init__.py:2564
#, python-format
msgid "one gold badge"
msgid_plural "%(count)d gold badges"
msgstr[0] ""
msgstr[1] ""
-#: models/__init__.py:2515
+#: models/__init__.py:2571
#, python-format
msgid "one silver badge"
msgid_plural "%(count)d silver badges"
msgstr[0] ""
msgstr[1] ""
-#: models/__init__.py:2522
+#: models/__init__.py:2578
#, python-format
msgid "one bronze badge"
msgid_plural "%(count)d bronze badges"
msgstr[0] ""
msgstr[1] ""
-#: models/__init__.py:2533
+#: models/__init__.py:2589
#, python-format
msgid "%(item1)s and %(item2)s"
msgstr ""
-#: models/__init__.py:2535
+#: models/__init__.py:2591
#, python-format
msgid "%(user)s has %(badges)s"
msgstr ""
-#: models/__init__.py:2682
+#: models/__init__.py:2738
#, python-format
msgid "At least %d karma point is required to post links"
msgid_plural "At least %d karma points is required to post links"
msgstr[0] ""
msgstr[1] ""
-#: models/__init__.py:3159
+#: models/__init__.py:3221
#, python-format
msgid "%(user)s shared a %(post_link)s."
msgstr ""
-#: models/__init__.py:3162 models/__init__.py:3172
+#: models/__init__.py:3224 models/__init__.py:3234
#, python-format
msgid "%(user)s edited a %(post_link)s."
msgstr ""
-#: models/__init__.py:3164
+#: models/__init__.py:3226
#, python-format
msgid "%(user)s posted a %(post_link)s"
msgstr ""
-#: models/__init__.py:3167
+#: models/__init__.py:3229
#, python-format
msgid "%(user)s edited an %(post_link)s."
msgstr ""
-#: models/__init__.py:3169
+#: models/__init__.py:3231
#, python-format
msgid "%(user)s posted an %(post_link)s."
msgstr ""
-#: models/__init__.py:3174
+#: models/__init__.py:3236
#, python-format
msgid "%(user)s posted a %(post_link)s."
msgstr ""
-#: models/__init__.py:3190
+#: models/__init__.py:3252
msgid "To reply, PLEASE WRITE ABOVE THIS LINE."
msgstr ""
-#: models/__init__.py:3232
+#: models/__init__.py:3294
#, python-format
msgid "\"%(title)s\""
msgstr ""
-#: models/__init__.py:3384
+#: models/__init__.py:3446
#, python-format
msgid ""
"Congratulations, you have received a badge '%(badge_name)s'. Check out <a "
"href=\"%(user_profile)s\">your profile</a>."
msgstr ""
-#: models/__init__.py:3657
+#: models/__init__.py:3725
#, python-format
msgid "Welcome to %(site_name)s"
msgstr ""
-#: models/__init__.py:3678 views/commands.py:697
+#: models/__init__.py:3746 views/commands.py:697
msgid "Your tag subscription was saved, thanks!"
msgstr ""
@@ -4194,57 +4384,62 @@ msgstr ""
msgid "message"
msgstr ""
-#: models/post.py:414
+#: models/post.py:418
msgid "Question: "
msgstr ""
-#: models/post.py:416
+#: models/post.py:420
msgid "Answer: "
msgstr ""
-#: models/post.py:1570
+#: models/post.py:912 templates/question/answer_controls.html:58
+#: templatetags/extra_filters_jinja.py:128
+msgid "more"
+msgstr ""
+
+#: models/post.py:1602
msgid "Sorry, this question has been deleted and is no longer accessible"
msgstr ""
-#: models/post.py:1586
+#: models/post.py:1618
msgid ""
"Sorry, the answer you are looking for is no longer available, because the "
"parent question has been removed"
msgstr ""
-#: models/post.py:1593
+#: models/post.py:1625
msgid "Sorry, this answer has been removed and is no longer accessible"
msgstr ""
-#: models/post.py:1609
+#: models/post.py:1641
msgid ""
"Sorry, the comment you are looking for is no longer accessible, because the "
"parent question has been removed"
msgstr ""
-#: models/post.py:1616
+#: models/post.py:1648
msgid ""
"Sorry, the comment you are looking for is no longer accessible, because the "
"parent answer has been removed"
msgstr ""
-#: models/post.py:1638
+#: models/post.py:1670
msgid "This post is temporarily not available"
msgstr ""
-#: models/post.py:2147
+#: models/post.py:2179
#, python-format
msgid ""
"Thank you for your post to %(site)s. It will be published after the "
"moderators review."
msgstr ""
-#: models/post.py:2151
+#: models/post.py:2183
#, python-format
msgid "your post to %(site)s"
msgstr ""
-#: models/post.py:2158
+#: models/post.py:2190
msgid ""
"Your post was placed on the moderation queue and will be published after the "
"moderator approval."
@@ -4259,24 +4454,24 @@ msgstr ""
msgid "\" and more"
msgstr ""
-#: models/question.py:834
+#: models/question.py:840
#, python-format
msgid "%(count)d answer:"
msgid_plural "%(count)d answers:"
msgstr[0] ""
msgstr[1] ""
-#: models/question.py:1346
+#: models/question.py:1359
#, python-format
msgid "Tag %s is new and will be submitted for the moderators approval"
msgstr ""
-#: models/question.py:1351 models/tag.py:217
+#: models/question.py:1364 models/tag.py:217
#, python-format
msgid "Tags %s are new and will be submitted for the moderators approval"
msgstr ""
-#: models/question.py:1590
+#: models/question.py:1603
#, python-format
msgid "Please, <a href=\"%s\">review your question</a>."
msgstr ""
@@ -4410,7 +4605,7 @@ msgid "This might have happened for the following reasons:"
msgstr ""
#: templates/404.html:17
-msgid "this question or answer has been deleted;"
+msgid "This page has been deleted"
msgstr ""
#: templates/404.html:18
@@ -4435,18 +4630,6 @@ msgstr ""
msgid "report this problem"
msgstr ""
-#: templates/404.html:30 templates/500.html:11
-msgid "back to previous page"
-msgstr ""
-
-#: templates/404.html:31 templates/widgets/scope_nav.html:17
-msgid "see all questions"
-msgstr ""
-
-#: templates/404.html:32
-msgid "see all tags"
-msgstr ""
-
#: templates/500.html:3 templates/500.html.py:5
msgid "Internal server error"
msgstr ""
@@ -4456,34 +4639,23 @@ msgid "system error log is recorded, error will be fixed as soon as possible"
msgstr ""
#: templates/500.html:9
-msgid "please report the error to the site administrators if you wish"
-msgstr ""
-
-#: templates/500.html:12
-msgid "see latest questions"
-msgstr ""
-
-#: templates/500.html:13
-msgid "see tags"
-msgstr ""
-
-#: templates/answer_edit.html:4 templates/answer_edit.html.py:10
-msgid "Edit answer"
+msgid "please report the error to the site administrators"
msgstr ""
-#: templates/answer_edit.html:10 templates/question_edit.html:9
+#: templates/answer_edit.html:11 templates/question_edit.html:9
#: templates/question_retag.html:5 templates/revisions.html:7
msgid "back"
msgstr ""
-#: templates/answer_edit.html:41 templates/question_edit.html:61
+#: templates/answer_edit.html:42 templates/question_edit.html:61
msgid "Save edit"
msgstr ""
-#: templates/answer_edit.html:46 templates/close.html:16
+#: templates/answer_edit.html:47 templates/close.html:16
#: templates/feedback.html:64 templates/question_edit.html:62
-#: templates/question_retag.html:22 templates/reopen.html:28
-#: templates/subscribe_for_tags.html:16
+#: templates/question_retag.html:22 templates/reopen.html:26
+#: templates/subscribe_for_tags.html:16 templates/avatar/add.html:17
+#: templates/avatar/change.html:26 templates/avatar/confirm_delete.html:16
#: templates/user_profile/reject_post_dialog.html:36
#: templates/user_profile/reject_post_dialog.html:74
#: templates/user_profile/reject_post_dialog.html:104
@@ -4491,24 +4663,19 @@ msgstr ""
msgid "Cancel"
msgstr ""
-#: templates/answer_edit.html:86 templates/answer_edit.html.py:89
-#: templates/ask.html:81 templates/ask.html.py:84
+#: templates/answer_edit.html:87 templates/answer_edit.html.py:90
+#: templates/ask.html:82 templates/ask.html.py:85
#: templates/question_edit.html:100 templates/question_edit.html.py:103
-#: templates/question/javascript.html:72 templates/question/javascript.html:75
-#: templates/widgets/edit_post.html:73
+#: templates/question/javascript.html:103
+#: templates/question/javascript.html:106 templates/widgets/edit_post.html:73
msgid "hide preview"
msgstr ""
-#: templates/answer_edit.html:89 templates/ask.html:84
-#: templates/question_edit.html:103 templates/question/javascript.html:75
+#: templates/answer_edit.html:90 templates/ask.html:85
+#: templates/question_edit.html:103 templates/question/javascript.html:106
msgid "show preview"
msgstr ""
-#: templates/ask.html:4 templates/widgets/ask_button.html:9
-#: templates/widgets/ask_form.html:67
-msgid "Ask Your Question"
-msgstr ""
-
#: templates/ask.html:21
msgid ""
"since you are not logged in right now, you will be asked to sign in or "
@@ -4524,34 +4691,28 @@ msgid ""
"that. Meanwhile, your question will saved as pending."
msgstr ""
-#: templates/ask.html:29
-msgid "please, try to make your question interesting to this community"
-msgstr ""
-
-#: templates/ask.html:30 templates/widgets/answer_edit_tips.html:12
-#: templates/widgets/question_edit_tips.html:8
+#: templates/ask.html:30 templates/widgets/answer_edit_tips.html:8
+#: templates/widgets/question_edit_tips.html:6
msgid "provide enough details"
msgstr ""
-#: templates/ask.html:31 templates/widgets/answer_edit_tips.html:15
-#: templates/widgets/question_edit_tips.html:11
+#: templates/ask.html:31 templates/widgets/answer_edit_tips.html:9
+#: templates/widgets/question_edit_tips.html:7
msgid "be clear and concise"
msgstr ""
-#: templates/ask.html:36 templates/widgets/answer_edit_tips.html:20
-#: templates/widgets/question_edit_tips.html:16
+#: templates/ask.html:36
msgid "see frequently asked questions"
msgstr ""
#: templates/ask.html:36 templates/faq_static.html:3
-#: templates/faq_static.html.py:5 templates/widgets/answer_edit_tips.html:20
-#: templates/widgets/question_edit_tips.html:16 views/meta.py:71
+#: templates/faq_static.html.py:5 views/meta.py:71
msgid "FAQ"
msgstr ""
#: templates/badge.html:5 templates/badge.html.py:9
#: templates/user_profile/user_recent.html:18
-#: templates/user_profile/user_stats.html:73
+#: templates/user_profile/user_stats.html:72
#, python-format
msgid "%(name)s"
msgstr ""
@@ -4566,7 +4727,7 @@ msgid "Badge \"%(name)s\""
msgstr ""
#: templates/badge.html:9 templates/user_profile/user_recent.html:16
-#: templates/user_profile/user_stats.html:71
+#: templates/user_profile/user_stats.html:70
#, python-format
msgid "%(description)s"
msgstr ""
@@ -4581,37 +4742,33 @@ msgstr[1] ""
msgid "Badges"
msgstr ""
-#: templates/badges.html:7
-msgid "Community gives you awards for your questions, answers and votes."
-msgstr ""
-
-#: templates/badges.html:8
+#: templates/badges.html:9
msgid ""
"Below is the list of available badges and number of times each type of badge "
"has been awarded."
msgstr ""
-#: templates/badges.html:31
+#: templates/badges.html:32
msgid "Community badges"
msgstr "Badge levels"
-#: templates/badges.html:33
+#: templates/badges.html:34
msgid "gold badge: the highest honor and is very rare"
msgstr ""
-#: templates/badges.html:36
+#: templates/badges.html:37
msgid ""
"Gold badge is the highest award in this community. To obtain it you have to "
"show \n"
"profound knowledge and ability in addition to your active participation."
msgstr ""
-#: templates/badges.html:42 templates/badges.html.py:46
+#: templates/badges.html:43 templates/badges.html.py:47
msgid ""
"silver badge: occasionally awarded for the very high quality contributions"
msgstr ""
-#: templates/badges.html:49 templates/badges.html.py:53
+#: templates/badges.html:50 templates/badges.html.py:54
msgid "bronze badge: often given as a special honor"
msgstr ""
@@ -4620,14 +4777,6 @@ msgstr ""
msgid "RSS feed from %(site_title)s"
msgstr ""
-#: templates/close.html:3 templates/close.html.py:5
-msgid "Close question"
-msgstr ""
-
-#: templates/close.html:6
-msgid "Close the question"
-msgstr ""
-
#: templates/close.html:11
msgid "Reasons"
msgstr ""
@@ -4866,7 +5015,7 @@ msgid "Send Feedback"
msgstr ""
#: templates/groups.html:3 templates/groups.html.py:6
-#: templates/question/sidebar.html:108
+#: templates/question/sidebar.html:107
#: templates/tags/list_bulk_tag_subscription.html:15
msgid "Groups"
msgstr ""
@@ -5075,23 +5224,23 @@ msgstr ""
msgid "There are no questions with this tag yet"
msgstr ""
-#: templates/list_suggested_tags.html:62
+#: templates/list_suggested_tags.html:61
#, python-format
msgid "Apply tag \"%(name)s\" to all above questions"
msgstr ""
-#: templates/list_suggested_tags.html:63
+#: templates/list_suggested_tags.html:62
msgid "Reject tag"
msgstr ""
-#: templates/list_suggested_tags.html:71 templates/tags/content.html:5
+#: templates/list_suggested_tags.html:70 templates/tags/content.html:5
#: templates/tags/content.html.py:31
msgid "Nothing found"
msgstr ""
#: templates/macros.html:5
#, python-format
-msgid "Share this question on %(site)s"
+msgid "Share this content on %(site)s"
msgstr ""
#: templates/macros.html:44
@@ -5102,14 +5251,6 @@ msgstr ""
msgid "anonymous user"
msgstr ""
-#: templates/macros.html:91 templates/macros.html.py:110
-msgid "asked"
-msgstr ""
-
-#: templates/macros.html:93 templates/macros.html.py:112
-msgid "answered"
-msgstr ""
-
#: templates/macros.html:95 templates/macros.html.py:114
msgid "posted"
msgstr ""
@@ -5165,91 +5306,95 @@ msgstr ""
msgid "Comments"
msgstr ""
-#: templates/macros.html:430
+#: templates/macros.html:433
msgid "delete this comment"
msgstr ""
-#: templates/macros.html:443 templates/revisions.html:38
+#: templates/macros.html:446 templates/revisions.html:38
#: templates/revisions.html.py:41 templates/question/answer_controls.html:5
#: templates/question/question_controls.html:1
msgid "edit"
msgstr ""
-#: templates/macros.html:452
+#: templates/macros.html:455
msgid "convert to answer"
msgstr ""
-#: templates/macros.html:579
+#: templates/macros.html:582
#, python-format
msgid "follow %(alias)s"
msgstr ""
-#: templates/macros.html:582
+#: templates/macros.html:585
#, python-format
msgid "unfollow %(alias)s"
msgstr ""
-#: templates/macros.html:583
+#: templates/macros.html:586
#, python-format
msgid "following %(alias)s"
msgstr ""
-#: templates/macros.html:662 templatetags/extra_tags.py:44
+#: templates/macros.html:667 templatetags/extra_tags.py:44
#, python-format
msgid "%(username)s gravatar image"
msgstr ""
-#: templates/macros.html:671
+#: templates/macros.html:676
#, python-format
msgid "%(username)s's website is %(url)s"
msgstr ""
-#: templates/macros.html:686 templates/macros.html.py:687
-#: templates/macros.html:725 templates/macros.html.py:726
+#: templates/macros.html:697 templates/macros.html.py:698
+#: templates/macros.html:759 templates/macros.html.py:760
msgid "previous"
msgstr ""
-#: templates/macros.html:698 templates/macros.html.py:737
+#: templates/macros.html:716 templates/macros.html.py:771
msgid "current page"
msgstr ""
-#: templates/macros.html:700 templates/macros.html.py:707
-#: templates/macros.html:739 templates/macros.html.py:746
+#: templates/macros.html:722 templates/macros.html.py:735
+#: templates/macros.html:773 templates/macros.html.py:780
#, python-format
msgid "page %(num)s"
msgstr ""
-#: templates/macros.html:711 templates/macros.html.py:750
+#: templates/macros.html:744 templates/macros.html.py:784
msgid "next page"
msgstr ""
-#: templates/macros.html:762
+#: templates/macros.html:745
+msgid "next"
+msgstr ""
+
+#: templates/macros.html:796
#, python-format
msgid "responses for %(username)s"
msgstr ""
-#: templates/macros.html:765
+#: templates/macros.html:799
#, python-format
msgid "you have %(response_count)s new response"
msgid_plural "you have %(response_count)s new responses"
msgstr[0] ""
msgstr[1] ""
-#: templates/macros.html:768
+#: templates/macros.html:802
msgid "no new responses yet"
msgstr ""
-#: templates/macros.html:783 templates/macros.html.py:784
+#: templates/macros.html:817 templates/macros.html.py:818
#, python-format
msgid "%(new)s new flagged posts and %(seen)s previous"
msgstr ""
-#: templates/macros.html:786 templates/macros.html.py:787
+#: templates/macros.html:820 templates/macros.html.py:821
#, python-format
msgid "%(new)s new flagged posts"
msgstr ""
-#: templates/macros.html:792 templates/macros.html.py:793
+#: templates/macros.html:826 templates/macros.html.py:827
#, python-format
msgid "%(seen)s flagged posts"
msgstr ""
@@ -5258,34 +5403,18 @@ msgstr ""
msgid "Questions"
msgstr ""
-#: templates/question.html:230
+#: templates/question.html:232
msgid "see more comments"
msgstr ""
-#: templates/question.html:232 templates/question.html.py:335
+#: templates/question.html:234 templates/question.html.py:337
msgid "add a comment"
msgstr ""
-#: templates/question.html:245 templates/question/content.html:46
-msgid "Answer Your Own Question"
-msgstr ""
-
-#: templates/question.html:250
-msgid "Post Your Answer"
-msgstr ""
-
-#: templates/question.html:256 templates/widgets/ask_form.html:65
+#: templates/question.html:258 templates/widgets/ask_form.html:65
msgid "Login/Signup to Post"
msgstr ""
-#: templates/question_edit.html:4 templates/question_edit.html.py:9
-msgid "Edit question"
-msgstr ""
-
-#: templates/question_edit.html:16
-msgid "Question - in one sentence"
-msgstr ""
-
#: templates/question_edit.html:23
msgid "Details"
msgstr ""
@@ -5294,10 +5423,6 @@ msgstr ""
msgid "Change language"
msgstr ""
-#: templates/question_retag.html:3 templates/question_retag.html.py:5
-msgid "Retag question"
-msgstr ""
-
#: templates/question_retag.html:21
msgid "Retag"
msgstr ""
@@ -5318,10 +5443,6 @@ msgstr ""
msgid "up to 5 tags, less than 20 characters each"
msgstr ""
-#: templates/reopen.html:4 templates/reopen.html.py:6
-msgid "Reopen question"
-msgstr ""
-
#: templates/reopen.html:12
#, python-format
msgid ""
@@ -5337,14 +5458,6 @@ msgstr ""
msgid "When:"
msgstr ""
-#: templates/reopen.html:23
-msgid "Reopen this question?"
-msgstr ""
-
-#: templates/reopen.html:27
-msgid "Reopen this question"
-msgstr ""
-
#: templates/revisions.html:4 templates/revisions.html.py:7
msgid "Revision history"
msgstr ""
@@ -5404,7 +5517,7 @@ msgstr ""
#: templates/users.html:41 templates/user_profile/user_info.html:25
#: templates/user_profile/user_reputation.html:5
-#: templates/user_profile/user_tabs.html:24
+#: templates/user_profile/user_tabs.html:20
msgid "karma"
msgstr ""
@@ -5447,7 +5560,7 @@ msgid "(or select another login method above)"
msgstr ""
#: templates/authopenid/authopenid_macros.html:66
-#: templates/authopenid/signin.html:115
+#: templates/authopenid/signin.html:118
#: templates/authopenid/widget_signin.html:118
msgid "Sign in"
msgstr ""
@@ -5495,15 +5608,15 @@ msgstr ""
msgid "Registration"
msgstr ""
-#: templates/authopenid/complete.html:23
+#: templates/authopenid/complete.html:24
msgid "User registration"
msgstr ""
-#: templates/authopenid/complete.html:47
+#: templates/authopenid/complete.html:48
msgid "<strong>Screen Name</strong> (<i>will be shown to others</i>)"
msgstr ""
-#: templates/authopenid/complete.html:56
+#: templates/authopenid/complete.html:57
msgid ""
"<strong>Email Address</strong> (<i>will <strong>not</strong> be shared "
"with \n"
@@ -5511,7 +5624,7 @@ msgid ""
" "
msgstr ""
-#: templates/authopenid/complete.html:71
+#: templates/authopenid/complete.html:72
#: templates/authopenid/signup_with_password.html:5
#: templates/authopenid/signup_with_password.html:45
msgid "Signup"
@@ -5593,10 +5706,10 @@ msgstr "User login"
#: templates/authopenid/signin.html:15
#: templates/authopenid/widget_signin.html:19
-#, python-format
+#, fuzzy, python-format
msgid ""
"\n"
-" Your answer to %(title)s %(summary)s will be posted once you log in\n"
+" Your answer to %(title)s will be posted once you log in\n"
" "
msgstr ""
"\n"
@@ -5606,10 +5719,10 @@ msgstr ""
#: templates/authopenid/signin.html:22
#: templates/authopenid/widget_signin.html:26
-#, python-format
+#, fuzzy, python-format
msgid ""
"Your question \n"
-" %(title)s %(summary)s will be posted once you log in\n"
+" %(title)s will be posted once you log in\n"
" "
msgstr ""
"<span class=\"strong big\">Your question</span> <i>\"<strong>%(title)s</"
@@ -5652,109 +5765,109 @@ msgid ""
"account"
msgstr ""
-#: templates/authopenid/signin.html:90
+#: templates/authopenid/signin.html:93
msgid "or enter your <span>user name and password</span>"
msgstr ""
-#: templates/authopenid/signin.html:94
+#: templates/authopenid/signin.html:97
#: templates/authopenid/widget_signin.html:98
msgid "Please, sign in"
msgstr ""
-#: templates/authopenid/signin.html:101
+#: templates/authopenid/signin.html:104
#: templates/authopenid/widget_signin.html:105
msgid "Login failed, please try again"
msgstr ""
-#: templates/authopenid/signin.html:106
+#: templates/authopenid/signin.html:109
#: templates/authopenid/widget_signin.html:109
msgid "Login or email"
msgstr ""
-#: templates/authopenid/signin.html:110
+#: templates/authopenid/signin.html:113
#: templates/authopenid/widget_signin.html:113 utils/forms.py:264
msgid "Password"
msgstr ""
-#: templates/authopenid/signin.html:122
+#: templates/authopenid/signin.html:125
#: templates/authopenid/widget_signin.html:125
msgid "To change your password - please enter the new one twice, then submit"
msgstr ""
-#: templates/authopenid/signin.html:126
+#: templates/authopenid/signin.html:129
#: templates/authopenid/widget_signin.html:129
msgid "New password"
msgstr ""
-#: templates/authopenid/signin.html:135
+#: templates/authopenid/signin.html:138
#: templates/authopenid/widget_signin.html:138
msgid "Please, retype"
msgstr ""
-#: templates/authopenid/signin.html:145
+#: templates/authopenid/signin.html:148
#: templates/authopenid/widget_signin.html:148
#: templates/livesettings/site_settings.html:24
msgid "Change password"
msgstr ""
-#: templates/authopenid/signin.html:159
+#: templates/authopenid/signin.html:162
#: templates/authopenid/widget_signin.html:162
msgid "Here are your current login methods"
msgstr ""
-#: templates/authopenid/signin.html:163
+#: templates/authopenid/signin.html:166
#: templates/authopenid/widget_signin.html:166
msgid "provider"
msgstr ""
-#: templates/authopenid/signin.html:164
+#: templates/authopenid/signin.html:167
#: templates/authopenid/widget_signin.html:167
msgid "last used"
msgstr ""
-#: templates/authopenid/signin.html:165
+#: templates/authopenid/signin.html:168
#: templates/authopenid/widget_signin.html:168
msgid "delete, if you like"
msgstr ""
-#: templates/authopenid/signin.html:179
+#: templates/authopenid/signin.html:182
#: templates/authopenid/widget_signin.html:182
#: templates/question/answer_controls.html:33
#: templates/question/question_controls.html:36
msgid "delete"
msgstr ""
-#: templates/authopenid/signin.html:181
+#: templates/authopenid/signin.html:184
#: templates/authopenid/widget_signin.html:184
msgid "cannot be deleted"
msgstr ""
-#: templates/authopenid/signin.html:194
+#: templates/authopenid/signin.html:197
#: templates/authopenid/widget_signin.html:197
msgid "Still have trouble signing in?"
msgstr ""
-#: templates/authopenid/signin.html:199
+#: templates/authopenid/signin.html:202
#: templates/authopenid/widget_signin.html:202
-msgid "Please, enter your email address below and obtain a new key"
+msgid "Enter your email address below and obtain a new key"
msgstr ""
-#: templates/authopenid/signin.html:201
+#: templates/authopenid/signin.html:204
#: templates/authopenid/widget_signin.html:204
-msgid "Please, enter your email address below to recover your account"
+msgid "Enter your email address below to recover your account"
msgstr ""
-#: templates/authopenid/signin.html:204
+#: templates/authopenid/signin.html:207
#: templates/authopenid/widget_signin.html:207
msgid "recover your account via email"
msgstr ""
-#: templates/authopenid/signin.html:215
+#: templates/authopenid/signin.html:218
#: templates/authopenid/widget_signin.html:217
msgid "Send a new recovery key"
msgstr ""
-#: templates/authopenid/signin.html:217
+#: templates/authopenid/signin.html:220
#: templates/authopenid/widget_signin.html:219
msgid "Recover your account via email"
msgstr ""
@@ -5836,7 +5949,7 @@ msgstr ""
msgid "You haven't uploaded an avatar yet. Please upload one now."
msgstr ""
-#: templates/avatar/add.html:13
+#: templates/avatar/add.html:14
msgid "Upload New Image"
msgstr ""
@@ -5848,7 +5961,7 @@ msgstr ""
msgid "Choose new Default"
msgstr ""
-#: templates/avatar/change.html:22
+#: templates/avatar/change.html:23
msgid "Upload"
msgstr ""
@@ -5867,7 +5980,7 @@ msgid ""
"\">upload one</a> now."
msgstr ""
-#: templates/avatar/confirm_delete.html:12
+#: templates/avatar/confirm_delete.html:13
msgid "Delete These"
msgstr ""
@@ -5947,7 +6060,7 @@ msgstr ""
#: templates/email/insufficient_rep_to_post_by_email.html:10
#, python-format
-msgid "%(username)s, your question could not be posted by email just yet."
+msgid "%(username)s, your content could not be posted by email just yet."
msgstr ""
#: templates/email/insufficient_rep_to_post_by_email.html:14
@@ -5958,7 +6071,7 @@ msgstr ""
#: templates/email/insufficient_rep_to_post_by_email.html:15
#, python-format
-msgid "At this time, please post your question at %(link)s"
+msgid "At this time, please post your content at %(link)s"
msgstr ""
#: templates/email/macros.html:19
@@ -5974,10 +6087,6 @@ msgid ""
" "
msgstr ""
-#: templates/email/macros.html:26
-msgid "Question :"
-msgstr ""
-
#: templates/email/macros.html:33
#, python-format
msgid "Asked by %(author)s:"
@@ -6055,11 +6164,6 @@ msgstr[1] ""
msgid "Great, you are ready to use %(site_name)s!"
msgstr ""
-#: templates/email/re_welcome_lamson_on.html:7
-#, python-format
-msgid "You can post questions by emailing them at %(ask_address)s."
-msgstr ""
-
#: templates/email/re_welcome_lamson_on.html:8
msgid ""
"When you receive update notifications, you will be able to respond to them, "
@@ -6118,8 +6222,8 @@ msgstr ""
#: templates/email/welcome_lamson_on.html:14
#, python-format
msgid ""
-"Until we receive the response from you, you will not be able ask or answer "
-"questions on %(site_name)s by email."
+"Until we receive the response from you, you will not be able to post content "
+"on %(site_name)s by email."
msgstr ""
#: templates/embed/list_widgets.html:44
@@ -6153,10 +6257,6 @@ msgid ""
"Create and embed widgets into your sites, here a list of available widgets."
msgstr ""
-#: templates/embed/widgets.html:16
-msgid "Ask a question"
-msgstr ""
-
#: templates/embed/widgets.html:17 templates/embed/widgets.html.py:26
msgid "create"
msgstr ""
@@ -6165,10 +6265,6 @@ msgstr ""
msgid "view list"
msgstr ""
-#: templates/embed/widgets.html:25
-msgid "List of questions"
-msgstr ""
-
#: templates/group_messaging/email_alert.html:7
#, python-format
msgid "%(author)s wrote:"
@@ -6195,7 +6291,7 @@ msgid "Messages by sender:"
msgstr ""
#: templates/group_messaging/senders_list.html:5
-#: templates/user_inbox/base.html:6 templates/user_profile/user_tabs.html:12
+#: templates/user_inbox/base.html:6 templates/user_profile/user_tabs.html:10
msgid "inbox"
msgstr ""
@@ -6269,7 +6365,7 @@ msgstr ""
msgid "Uncollapse all"
msgstr ""
-#: templates/main_page/headline.html:4 views/readers.py:151
+#: templates/main_page/headline.html:4 views/readers.py:157
#, python-format
msgid "%(q_num)s question"
msgid_plural "%(q_num)s questions"
@@ -6319,18 +6415,6 @@ msgstr ""
msgid "add tags and a query to focus your search"
msgstr ""
-#: templates/main_page/nothing_found.html:4
-msgid "There are no unanswered questions here"
-msgstr ""
-
-#: templates/main_page/nothing_found.html:7
-msgid "No questions here. "
-msgstr ""
-
-#: templates/main_page/nothing_found.html:8
-msgid "Please follow some questions or follow some users."
-msgstr ""
-
#: templates/main_page/nothing_found.html:13
msgid "You can expand your search by "
msgstr ""
@@ -6348,20 +6432,12 @@ msgstr ""
msgid "starting over"
msgstr ""
-#: templates/main_page/nothing_found.html:30
-msgid "Please always feel free to ask your question!"
-msgstr ""
-
#: templates/main_page/questions_loop.html:9
msgid "Did not find what you were looking for?"
msgstr ""
-#: templates/main_page/questions_loop.html:10
-msgid "Ask your question!"
-msgstr ""
-
#: templates/main_page/tab_bar.html:11
-msgid "subscribe to the questions feed"
+msgid "subscribe to the feed"
msgstr ""
#: templates/main_page/tab_bar.html:12
@@ -6408,10 +6484,6 @@ msgstr ""
msgid "This response is published"
msgstr ""
-#: templates/question/answer_controls.html:2
-msgid "swap with question"
-msgstr ""
-
#: templates/question/answer_controls.html:11
msgid "remove offensive flag"
msgstr ""
@@ -6459,18 +6531,6 @@ msgstr ""
msgid "link"
msgstr ""
-#: templates/question/answer_controls.html:58
-msgid "more"
-msgstr ""
-
-#: templates/question/answer_controls.html:71
-msgid "repost as a question comment"
-msgstr ""
-
-#: templates/question/answer_controls.html:85
-msgid "repost as a comment under the older answer"
-msgstr ""
-
#: templates/question/answer_tab_bar.html:3
#, python-format
msgid ""
@@ -6500,47 +6560,34 @@ msgstr ""
msgid "most voted answers will be shown first"
msgstr ""
-#: templates/question/answer_vote_buttons.html:8
-#: templates/user_profile/users_answers.html:7
-msgid "this answer has been selected as correct"
-msgstr ""
-
#: templates/question/answer_vote_buttons.html:10
-msgid "mark this answer as correct (click again to undo)"
+msgid "(click again to undo)"
msgstr ""
#: templates/question/closed_question_info.html:2
+msgid "Closed for the following reason"
+msgstr ""
+
+#: templates/question/closed_question_info.html:3
+msgid "by"
+msgstr ""
+
+#: templates/question/closed_question_info.html:5
#, python-format
msgid ""
"The question has been closed for the following reason <b>\"%(close_reason)s"
"\"</b> <i>by"
msgstr ""
-#: templates/question/closed_question_info.html:4
+#: templates/question/closed_question_info.html:8
#, python-format
msgid "close date %(closed_at)s"
msgstr ""
-#: templates/question/content.html:33
-msgid "Edit Your Previous Answer"
-msgstr ""
-
-#: templates/question/content.html:34
+#: templates/question/content.html:39
msgid "(only one answer per user is allowed)"
msgstr ""
-#: templates/question/new_answer_form.html:12
-msgid "Login/Signup to Answer"
-msgstr ""
-
-#: templates/question/new_answer_form.html:20
-msgid "Your answer"
-msgstr ""
-
-#: templates/question/new_answer_form.html:22
-msgid "Be the first one to answer this question!"
-msgstr ""
-
#: templates/question/new_answer_form.html:28
msgid ""
"<span class='strong big'>Please start posting your answer anonymously</span> "
@@ -6570,10 +6617,6 @@ msgid ""
"best questions and answers!"
msgstr ""
-#: templates/question/new_answer_form.html:39
-msgid "Add answer"
-msgstr ""
-
#: templates/question/question_controls.html:5
msgid "retag"
msgstr ""
@@ -6586,12 +6629,8 @@ msgstr ""
msgid "close"
msgstr ""
-#: templates/question/sidebar.html:8
-msgid "Question tools"
-msgstr ""
-
#: templates/question/sidebar.html:11
-msgid "click to unfollow this question"
+msgid "click to unfollow "
msgstr ""
#: templates/question/sidebar.html:12
@@ -6603,7 +6642,7 @@ msgid "Unfollow"
msgstr ""
#: templates/question/sidebar.html:17
-msgid "click to follow this question"
+msgid "click to follow "
msgstr ""
#: templates/question/sidebar.html:18
@@ -6618,7 +6657,7 @@ msgstr[0] ""
msgstr[1] ""
#: templates/question/sidebar.html:33
-msgid "subscribe to this question rss feed"
+msgid "subscribe to the rss feed"
msgstr ""
#: templates/question/sidebar.html:34
@@ -6629,7 +6668,7 @@ msgstr ""
msgid "Invite"
msgstr ""
-#: templates/question/sidebar.html:50 templates/question/sidebar.html.py:56
+#: templates/question/sidebar.html:49 templates/question/sidebar.html.py:55
#: templates/user_profile/user_email_subscriptions.html:59
#: templates/widgets/tag_selector.html:20
#: templates/widgets/tag_selector.html:37
@@ -6637,68 +6676,60 @@ msgstr ""
msgid "add"
msgstr ""
-#: templates/question/sidebar.html:52 templates/question/sidebar.html.py:58
+#: templates/question/sidebar.html:51 templates/question/sidebar.html.py:57
msgid "- or -"
msgstr ""
-#: templates/question/sidebar.html:70
+#: templates/question/sidebar.html:69
msgid "share with everyone"
msgstr ""
-#: templates/question/sidebar.html:81
-msgid "This question is currently shared only with:"
-msgstr ""
-
-#: templates/question/sidebar.html:83
+#: templates/question/sidebar.html:82
msgid "Individual users"
msgstr ""
-#: templates/question/sidebar.html:88
+#: templates/question/sidebar.html:87
msgid "You"
msgstr ""
-#: templates/question/sidebar.html:95 templates/question/sidebar.html:115
+#: templates/question/sidebar.html:94 templates/question/sidebar.html:114
msgid "and"
msgstr ""
-#: templates/question/sidebar.html:120
+#: templates/question/sidebar.html:119
#, python-format
msgid "%(more_count)s more"
msgstr ""
-#: templates/question/sidebar.html:126
+#: templates/question/sidebar.html:125
msgid "Public thread"
msgstr ""
-#: templates/question/sidebar.html:127
+#: templates/question/sidebar.html:126
#, python-format
msgid "This thread is public, all members of %(site_name)s can read this page."
msgstr ""
-#: templates/question/sidebar.html:135
+#: templates/question/sidebar.html:134
msgid "Stats"
msgstr ""
-#: templates/question/sidebar.html:137
+#: templates/question/sidebar.html:136
msgid "Asked"
msgstr ""
-#: templates/question/sidebar.html:140
+#: templates/question/sidebar.html:139
msgid "Seen"
msgstr ""
-#: templates/question/sidebar.html:140
+#: templates/question/sidebar.html:139
msgid "times"
msgstr ""
-#: templates/question/sidebar.html:143
+#: templates/question/sidebar.html:142
msgid "Last updated"
msgstr ""
-#: templates/question/sidebar.html:151
-msgid "Related questions"
-msgstr ""
-
#: templates/tags/form_bulk_tag_subscription.html:4
msgid "Tag subscriptions"
msgstr ""
@@ -6925,6 +6956,18 @@ msgstr ""
msgid "%(username)s's profile"
msgstr ""
+#: templates/user_profile/user_answers_list.html:5
+#, python-format
+msgid "the answer has been voted for %(answer_score)s times"
+msgstr ""
+
+#: templates/user_profile/user_answers_list.html:15
+#, python-format
+msgid "(%(comment_count)s comment)"
+msgid_plural "the answer has been commented %(comment_count)s times"
+msgstr[0] ""
+msgstr[1] ""
+
#: templates/user_profile/user_edit.html:4
msgid "Edit user profile"
msgstr ""
@@ -6961,7 +7004,7 @@ msgid "Update"
msgstr ""
#: templates/user_profile/user_email_subscriptions.html:5
-#: templates/user_profile/user_tabs.html:44
+#: templates/user_profile/user_tabs.html:36
msgid "subscriptions"
msgstr ""
@@ -6994,11 +7037,6 @@ msgstr ""
msgid "Subscribed Tags"
msgstr ""
-#: templates/user_profile/user_favorites.html:4
-#: templates/user_profile/user_tabs.html:29
-msgid "followed questions"
-msgstr ""
-
#: templates/user_profile/user_info.html:37
msgid "update profile"
msgstr ""
@@ -7053,7 +7091,7 @@ msgid "votes left"
msgstr ""
#: templates/user_profile/user_moderate.html:4
-#: templates/user_profile/user_tabs.html:50
+#: templates/user_profile/user_tabs.html:41
msgid "moderation"
msgstr ""
@@ -7135,7 +7173,7 @@ msgid ""
msgstr ""
#: templates/user_profile/user_network.html:5
-#: templates/user_profile/user_tabs.html:18
+#: templates/user_profile/user_tabs.html:15
msgid "network"
msgstr ""
@@ -7165,13 +7203,12 @@ msgid "%(username)s's network is empty"
msgstr ""
#: templates/user_profile/user_recent.html:5
-#: templates/user_profile/user_tabs.html:31
-#: templates/user_profile/user_tabs.html:33
+#: templates/user_profile/user_tabs.html:27
msgid "activity"
msgstr ""
-#: templates/user_profile/user_recent.html:23
-#: templates/user_profile/user_recent.html:27
+#: templates/user_profile/user_recent.html:25
+#: templates/user_profile/user_recent.html:30
msgid "source"
msgstr ""
@@ -7185,7 +7222,7 @@ msgid "%(user_name)s's karma change log"
msgstr ""
#: templates/user_profile/user_stats.html:6
-#: templates/user_profile/user_tabs.html:7
+#: templates/user_profile/user_tabs.html:6
msgid "overview"
msgstr ""
@@ -7202,97 +7239,41 @@ msgid_plural "Answers"
msgstr[0] ""
msgstr[1] ""
-#: templates/user_profile/user_stats.html:23
+#: templates/user_profile/user_stats.html:22
#, python-format
msgid "<span class=\"count\">%(cnt)s</span> Vote"
msgid_plural "<span class=\"count\">%(cnt)s</span> Votes "
msgstr[0] ""
msgstr[1] ""
-#: templates/user_profile/user_stats.html:31
+#: templates/user_profile/user_stats.html:30
#, python-format
msgid "<span class=\"count\">%(counter)s</span> Tag"
msgid_plural "<span class=\"count\">%(counter)s</span> Tags"
msgstr[0] ""
msgstr[1] ""
-#: templates/user_profile/user_stats.html:65
+#: templates/user_profile/user_stats.html:64
#, python-format
msgid "<span class=\"count\">%(counter)s</span> Badge"
msgid_plural "<span class=\"count\">%(counter)s</span> Badges"
msgstr[0] ""
msgstr[1] ""
-#: templates/user_profile/user_stats.html:85
+#: templates/user_profile/user_stats.html:84
msgid "Answer to:"
msgstr ""
-#: templates/user_profile/user_tabs.html:5
-msgid "User profile"
-msgstr ""
-
-#: templates/user_profile/user_tabs.html:10 views/users.py:819
-msgid "comments and answers to others questions"
-msgstr ""
-
-#: templates/user_profile/user_tabs.html:16
-msgid "followers and followed users"
-msgstr ""
-
-#: templates/user_profile/user_tabs.html:22
-msgid "Graph of user karma"
-msgstr ""
-
-#: templates/user_profile/user_tabs.html:27
-msgid "questions that user is following"
-msgstr ""
-
-#: templates/user_profile/user_tabs.html:36 views/users.py:861
-msgid "user vote record"
-msgstr ""
-
-#: templates/user_profile/user_tabs.html:38
+#: templates/user_profile/user_tabs.html:31
#: templates/user_profile/user_votes.html:5
msgid "votes"
msgstr ""
-#: templates/user_profile/user_tabs.html:42 views/users.py:973
-msgid "email subscription settings"
-msgstr ""
-
-#: templates/user_profile/user_tabs.html:48 views/users.py:286
-msgid "moderate this user"
-msgstr ""
-
-#: templates/user_profile/users_answers.html:7
-#, python-format
-msgid "the answer has been voted for %(answer_score)s times"
-msgstr ""
-
-#: templates/user_profile/users_answers.html:17
-#, python-format
-msgid "(%(comment_count)s comment)"
-msgid_plural "the answer has been commented %(comment_count)s times"
-msgstr[0] ""
-msgstr[1] ""
-
#: templates/widgets/answer_edit_tips.html:3
#: templates/widgets/question_edit_tips.html:3
msgid "Tips"
msgstr ""
-#: templates/widgets/answer_edit_tips.html:6
-msgid "give an answer interesting to this community"
-msgstr ""
-
-#: templates/widgets/answer_edit_tips.html:9
-msgid "try to give an answer, rather than engage into a discussion"
-msgstr ""
-
-#: templates/widgets/ask_button.html:9
-msgid "Ask the Group"
-msgstr ""
-
#: templates/widgets/ask_form.html:22 templates/widgets/ask_form.html.py:24
msgid "Add details (optional)"
msgstr ""
@@ -7340,7 +7321,7 @@ msgstr ""
msgid "about"
msgstr ""
-#: templates/widgets/footer.html:40 templates/widgets/user_navigation.html:26
+#: templates/widgets/footer.html:40 templates/widgets/user_navigation.html:27
msgid "help"
msgstr ""
@@ -7373,11 +7354,7 @@ msgid "add logo"
msgstr ""
#: templates/widgets/group_info.html:46
-msgid "moderate emailed questions"
-msgstr ""
-
-#: templates/widgets/group_info.html:58
-msgid "show only selected answers to enquirers"
+msgid "moderate emailed content"
msgstr ""
#: templates/widgets/group_info.html:63
@@ -7392,38 +7369,30 @@ msgstr ""
msgid "Allow only read access"
msgstr ""
-#: templates/widgets/group_info.html:102
-msgid "list of email addresses of pre-approved users"
-msgstr ""
-
-#: templates/widgets/group_info.html:107
+#: templates/widgets/group_info.html:106
msgid "List of preapproved email addresses"
msgstr ""
-#: templates/widgets/group_info.html:108
+#: templates/widgets/group_info.html:107
msgid ""
"Users with these email adderesses will be added to the group automatically."
msgstr ""
-#: templates/widgets/group_info.html:109
+#: templates/widgets/group_info.html:108
msgid "edit preapproved emails"
msgstr ""
-#: templates/widgets/group_info.html:113
-msgid "list of preapproved email address domain names"
-msgstr ""
-
-#: templates/widgets/group_info.html:118
+#: templates/widgets/group_info.html:116
msgid "List of preapproved email domain names"
msgstr ""
-#: templates/widgets/group_info.html:119
+#: templates/widgets/group_info.html:117
msgid ""
"Users whose email adderesses belong to these domains will be added to the "
"group automatically."
msgstr ""
-#: templates/widgets/group_info.html:120
+#: templates/widgets/group_info.html:118
msgid "edit preapproved email domains"
msgstr ""
@@ -7477,34 +7446,24 @@ msgstr ""
msgid "learn more about Markdown"
msgstr ""
-#: templates/widgets/meta_nav.html:12
+#: templates/widgets/meta_nav.html:13
msgid "people & groups"
msgstr ""
-#: templates/widgets/meta_nav.html:20
+#: templates/widgets/meta_nav.html:21
msgid "users"
msgstr "people"
-#: templates/widgets/meta_nav.html:27
+#: templates/widgets/meta_nav.html:28
msgid "badges"
msgstr ""
-#: templates/widgets/question_edit_tips.html:5
-msgid "ask a question interesting to this community"
-msgstr ""
-
#: templates/widgets/question_summary.html:12
msgid "view"
msgid_plural "views"
msgstr[0] ""
msgstr[1] ""
-#: templates/widgets/question_summary.html:30
-msgid "answer"
-msgid_plural "answers"
-msgstr[0] ""
-msgstr[1] ""
-
#: templates/widgets/question_summary.html:41
msgid "vote"
msgid_plural "votes"
@@ -7515,26 +7474,10 @@ msgstr[1] ""
msgid "ALL"
msgstr ""
-#: templates/widgets/scope_nav.html:22
-msgid "see unanswered questions"
-msgstr ""
-
-#: templates/widgets/scope_nav.html:22
-msgid "UNANSWERED"
-msgstr ""
-
-#: templates/widgets/scope_nav.html:27
-msgid "see your followed questions"
-msgstr ""
-
#: templates/widgets/scope_nav.html:27
msgid "FOLLOWED"
msgstr ""
-#: templates/widgets/scope_nav.html:30
-msgid "Please ask your question here"
-msgstr ""
-
#: templates/widgets/tag_selector.html:4
msgid "Interesting tags"
msgstr ""
@@ -7547,10 +7490,6 @@ msgstr ""
msgid "Subscribed tags"
msgstr ""
-#: templates/widgets/tag_selector.html:59
-msgid "Show only questions from"
-msgstr ""
-
#: templates/widgets/tag_selector.html:70
msgid "Send me email alerts for"
msgstr ""
@@ -7587,19 +7526,19 @@ msgstr ""
msgid "badges:"
msgstr ""
-#: templates/widgets/user_navigation.html:17
+#: templates/widgets/user_navigation.html:18
msgid "sign out"
msgstr ""
-#: templates/widgets/user_navigation.html:20
+#: templates/widgets/user_navigation.html:21
msgid "Hi there! Please sign in"
msgstr ""
-#: templates/widgets/user_navigation.html:23
+#: templates/widgets/user_navigation.html:24
msgid "settings"
msgstr ""
-#: templates/widgets/user_navigation.html:24
+#: templates/widgets/user_navigation.html:25
msgid "widgets"
msgstr ""
@@ -7631,7 +7570,7 @@ msgstr ""
msgid "Post questions, answers and comments"
msgstr ""
-#: templatetags/extra_filters_jinja.py:332
+#: templatetags/extra_filters_jinja.py:342
msgid "no"
msgstr ""
@@ -7711,10 +7650,6 @@ msgstr ""
msgid "this email address is not authorized"
msgstr ""
-#: utils/forms.py:265
-msgid "password is required"
-msgstr ""
-
#: utils/forms.py:268
msgid "Password <i>(please retype)</i>"
msgstr ""
@@ -7723,10 +7658,6 @@ msgstr ""
msgid "please, retype your password"
msgstr ""
-#: utils/forms.py:270
-msgid "sorry, entered passwords did not match, please try again"
-msgstr ""
-
#: utils/functions.py:102
msgid "2 days ago"
msgstr ""
@@ -7882,92 +7813,108 @@ msgstr ""
msgid "Suggested tags"
msgstr ""
-#: views/readers.py:256
+#: views/readers.py:278
#, python-format
msgid ""
"Please go to <a href=\"%s\">\"settings->URLs, keywords and greetings\"</a> "
"and set the base url for your site to function properly"
msgstr ""
-#: views/readers.py:421
+#: views/readers.py:460
msgid ""
"Sorry, the comment you are looking for has been deleted and is no longer "
"accessible"
msgstr ""
+#: views/users.py:286
+msgid "moderate this user"
+msgstr ""
+
#: views/users.py:287
msgid "moderate user"
msgstr ""
-#: views/users.py:529
+#: views/users.py:532
msgid "user profile"
msgstr ""
-#: views/users.py:530
+#: views/users.py:533
msgid "user profile overview"
msgstr ""
-#: views/users.py:650
+#: views/users.py:656
msgid "recent user activity"
msgstr ""
-#: views/users.py:651
+#: views/users.py:657
msgid "profile - recent activity"
msgstr ""
-#: views/users.py:682
+#: views/users.py:688
msgid "group joining requests"
msgstr ""
-#: views/users.py:683
+#: views/users.py:689
msgid "profile - moderation"
msgstr ""
-#: views/users.py:739
+#: views/users.py:745
msgid "private messages"
msgstr ""
-#: views/users.py:740
+#: views/users.py:746
msgid "profile - messages"
msgstr ""
-#: views/users.py:820
+#: views/users.py:825
+msgid "comments and answers to others questions"
+msgstr ""
+
+#: views/users.py:826
msgid "profile - responses"
msgstr ""
-#: views/users.py:862
+#: views/users.py:867
+msgid "user vote record"
+msgstr ""
+
+#: views/users.py:868
msgid "profile - votes"
msgstr ""
-#: views/users.py:883
+#: views/users.py:889
msgid "user karma"
msgstr ""
-#: views/users.py:884
+#: views/users.py:890
msgid "Profile - User's Karma"
msgstr ""
-#: views/users.py:902
+#: views/users.py:925
msgid "users favorite questions"
msgstr ""
-#: views/users.py:903
+#: views/users.py:926
msgid "profile - favorite questions"
msgstr ""
-#: views/users.py:944 views/users.py:948
+#: views/users.py:970 views/users.py:974
msgid "changes saved"
msgstr ""
-#: views/users.py:954
+#: views/users.py:980
msgid "email updates canceled"
msgstr ""
-#: views/users.py:974
+#: views/users.py:999
+msgid "email subscription settings"
+msgstr ""
+
+#: views/users.py:1000
msgid "profile - email subscriptions"
msgstr ""
-#: views/users.py:995
+#: views/users.py:1021
#, python-format
msgid "profile - %(section)s"
msgstr ""
@@ -8033,11 +7980,11 @@ msgstr ""
msgid "sorry, we seem to have some technical difficulties"
msgstr ""
-#: views/writers.py:888
+#: views/writers.py:869
msgid "Error - could not find the destination post"
msgstr ""
-#: views/writers.py:912
+#: views/writers.py:893
#, python-format
msgid ""
"Cannot convert, because text has more characters than %(max_chars)s - "
@@ -8065,17 +8012,17 @@ msgstr ""
#~ msgstr "Verification Email from Q&A forum"
#~ msgid ""
-#~ "how to validate email info with %(send_email_key_url)s %(gravatar_faq_url)"
-#~ "s"
+#~ "how to validate email info with %(send_email_key_url)s "
+#~ "%(gravatar_faq_url)s"
#~ msgstr ""
-#~ "<form style='margin:0;padding:0;' action='%(send_email_key_url)"
-#~ "s'><p><span class=\"bigger strong\">How?</span> If you have just set or "
-#~ "changed your email address - <strong>check your email and click the "
-#~ "included link</strong>.<br>The link contains a key generated specifically "
-#~ "for you. You can also <button style='display:inline' "
-#~ "type='submit'><strong>get a new key</strong></button> and check your "
-#~ "email again.</p></form><span class=\"bigger strong\">Why?</span> Email "
-#~ "validation is required to make sure that <strong>only you can post "
+#~ "<form style='margin:0;padding:0;' "
+#~ "action='%(send_email_key_url)s'><p><span class=\"bigger strong\">How?</"
+#~ "span> If you have just set or changed your email address - <strong>check "
+#~ "your email and click the included link</strong>.<br>The link contains a "
+#~ "key generated specifically for you. You can also <button style='display:"
+#~ "inline' type='submit'><strong>get a new key</strong></button> and check "
+#~ "your email again.</p></form><span class=\"bigger strong\">Why?</span> "
+#~ "Email validation is required to make sure that <strong>only you can post "
#~ "messages</strong> on your behalf and to <strong>minimize spam</strong> "
#~ "posts.<br>With email you can <strong>subscribe for updates</strong> on "
#~ "the most interesting questions. Also, when you sign up for the first time "
diff --git a/askbot/locale/en/LC_MESSAGES/djangojs.mo b/askbot/locale/en/LC_MESSAGES/djangojs.mo
index 3eead943..f158cafd 100644
--- a/askbot/locale/en/LC_MESSAGES/djangojs.mo
+++ b/askbot/locale/en/LC_MESSAGES/djangojs.mo
Binary files differ
diff --git a/askbot/locale/en/LC_MESSAGES/djangojs.po b/askbot/locale/en/LC_MESSAGES/djangojs.po
index f3ea106e..e1245db1 100644
--- a/askbot/locale/en/LC_MESSAGES/djangojs.po
+++ b/askbot/locale/en/LC_MESSAGES/djangojs.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.7\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-07-13 14:07-0500\n"
+"POT-Creation-Date: 2013-10-16 16:35-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -312,7 +312,7 @@ msgstr ""
msgid "Are you sure you don't want to post this comment?"
msgstr "Are you sure you do not want to post this comment?"
-#: media/js/post.js:1890 media/js/utils.js:3360 media/js/utils.js.c:3515
+#: media/js/post.js:1890 media/js/utils.js:3804 media/js/utils.js.c:3959
msgid "just now"
msgstr ""
@@ -374,7 +374,7 @@ msgstr[1] ""
msgid "Delete category?"
msgstr ""
-#: media/js/post.js:3888 media/js/utils.js:881
+#: media/js/post.js:3888 media/js/utils.js:1320
msgid "edit"
msgstr "edit"
@@ -395,10 +395,6 @@ msgstr ""
msgid "save tags"
msgstr ""
-#: media/js/post.js:4689 media/js/post.js.c:4723
-msgid "User name:"
-msgstr ""
-
#: media/js/post.js:4710
msgid "Group name:"
msgstr ""
@@ -519,202 +515,207 @@ msgstr ""
msgid "click to close"
msgstr ""
-#: media/js/utils.js:880
+#: media/js/utils.js:619
+#, c-format
+msgid "page %s"
+msgstr ""
+
+#: media/js/utils.js:1319
msgid "click to edit this comment"
msgstr "click to edit this comment"
-#: media/js/utils.js:905
+#: media/js/utils.js:1344
msgid "convert to answer"
msgstr ""
-#: media/js/utils.js:958
+#: media/js/utils.js:1397
msgid "Ok"
msgstr ""
-#: media/js/utils.js:959 media/js/utils.js.c:1407
+#: media/js/utils.js:1398 media/js/utils.js.c:1851
msgid "Cancel"
msgstr ""
-#: media/js/utils.js:1219
+#: media/js/utils.js:1663
#, c-format
msgid "Uploaded file: %s"
msgstr ""
-#: media/js/utils.js:1234
+#: media/js/utils.js:1678
msgid "Choose a different image"
msgstr ""
-#: media/js/utils.js:1236
+#: media/js/utils.js:1680
msgid "Choose a different file"
msgstr ""
-#: media/js/utils.js:1250
+#: media/js/utils.js:1694
msgid "Oops, looks like we had an error. Sorry."
msgstr ""
-#: media/js/utils.js:1311
+#: media/js/utils.js:1755
msgid "Choose an image to insert"
msgstr ""
-#: media/js/utils.js:1313
+#: media/js/utils.js:1757
msgid "Choose a file to insert"
msgstr ""
-#: media/js/utils.js:1326
+#: media/js/utils.js:1770
msgid "Allowed file types are:"
msgstr ""
-#: media/js/utils.js:1332
+#: media/js/utils.js:1776
#: media/js/tinymce/plugins/askbot_attachment/editor_plugin.js:35
msgid "Or paste file url here"
msgstr ""
-#: media/js/utils.js:1406
+#: media/js/utils.js:1850
msgid "Save"
msgstr ""
-#: media/js/utils.js:1478
+#: media/js/utils.js:1922
msgid "saved"
msgstr ""
-#: media/js/utils.js:1602
+#: media/js/utils.js:2046
msgid "enabled"
msgstr ""
-#: media/js/utils.js:1604
+#: media/js/utils.js:2048
msgid "disabled"
msgstr ""
-#: media/js/utils.js:2038
+#: media/js/utils.js:2482
msgid "group name"
msgstr ""
-#: media/js/utils.js:2046
+#: media/js/utils.js:2490
msgid "add new group"
msgstr ""
-#: media/js/utils.js:2138
+#: media/js/utils.js:2582
msgid "Group %(name)s already exists. Group names are case-insensitive."
msgstr ""
-#: media/js/utils.js:2311
+#: media/js/utils.js:2755
#, c-format
msgid "see questions tagged '%s'"
msgstr ""
-#: media/js/utils.js:3358
+#: media/js/utils.js:3802
msgid "ago"
msgstr ""
-#: media/js/utils.js:3359
+#: media/js/utils.js:3803
msgid "from now"
msgstr ""
-#: media/js/utils.js:3361
+#: media/js/utils.js:3805
msgid "about a minute"
msgstr ""
-#: media/js/utils.js:3362
+#: media/js/utils.js:3806
#, c-format
msgid "%d minutes"
msgstr ""
-#: media/js/utils.js:3363
+#: media/js/utils.js:3807
msgid "about an hour"
msgstr ""
-#: media/js/utils.js:3364
+#: media/js/utils.js:3808
#, c-format
msgid "%d hours"
msgstr ""
-#: media/js/utils.js:3365 media/js/utils.js.c:3493
+#: media/js/utils.js:3809 media/js/utils.js.c:3937
msgid "yesterday"
msgstr ""
-#: media/js/utils.js:3366
+#: media/js/utils.js:3810
#, c-format
msgid "%d days"
msgstr ""
-#: media/js/utils.js:3367
+#: media/js/utils.js:3811
msgid "about a month"
msgstr ""
-#: media/js/utils.js:3368
+#: media/js/utils.js:3812
#, c-format
msgid "%d months"
msgstr ""
-#: media/js/utils.js:3369
+#: media/js/utils.js:3813
msgid "about a year"
msgstr ""
-#: media/js/utils.js:3370
+#: media/js/utils.js:3814
#, c-format
msgid "%d years"
msgstr ""
-#: media/js/utils.js:3468
+#: media/js/utils.js:3912
msgid "Jan"
msgstr ""
-#: media/js/utils.js:3469
+#: media/js/utils.js:3913
msgid "Feb"
msgstr ""
-#: media/js/utils.js:3470
+#: media/js/utils.js:3914
msgid "Mar"
msgstr ""
-#: media/js/utils.js:3471
+#: media/js/utils.js:3915
msgid "Apr"
msgstr ""
-#: media/js/utils.js:3472
+#: media/js/utils.js:3916
msgid "May"
msgstr ""
-#: media/js/utils.js:3473
+#: media/js/utils.js:3917
msgid "Jun"
msgstr ""
-#: media/js/utils.js:3474
+#: media/js/utils.js:3918
msgid "Jul"
msgstr ""
-#: media/js/utils.js:3475
+#: media/js/utils.js:3919
msgid "Aug"
msgstr ""
-#: media/js/utils.js:3476
+#: media/js/utils.js:3920
msgid "Sep"
msgstr ""
-#: media/js/utils.js:3477
+#: media/js/utils.js:3921
msgid "Oct"
msgstr ""
-#: media/js/utils.js:3478
+#: media/js/utils.js:3922
msgid "Nov"
msgstr ""
-#: media/js/utils.js:3479
+#: media/js/utils.js:3923
msgid "Dec"
msgstr ""
-#: media/js/utils.js:3491
+#: media/js/utils.js:3935
msgid "2 days ago"
msgstr ""
-#: media/js/utils.js:3498
+#: media/js/utils.js:3942
#, c-format
msgid "%s hour ago"
msgid_plural "%s hours ago"
msgstr[0] ""
msgstr[1] ""
-#: media/js/utils.js:3508
+#: media/js/utils.js:3952
#, c-format
msgid "%s min ago"
msgid_plural "%s mins ago"
diff --git a/askbot/locale/es/LC_MESSAGES/django.mo b/askbot/locale/es/LC_MESSAGES/django.mo
index db1375a0..cc2d8161 100644
--- a/askbot/locale/es/LC_MESSAGES/django.mo
+++ b/askbot/locale/es/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/es/LC_MESSAGES/django.po b/askbot/locale/es/LC_MESSAGES/django.po
index c69723e9..fcc1d1a0 100644
--- a/askbot/locale/es/LC_MESSAGES/django.po
+++ b/askbot/locale/es/LC_MESSAGES/django.po
@@ -4,6 +4,7 @@
#
# Translators:
# Adolfo Fitoria <adolfo.fitoria@gmail.com>, 2013
+# fmmainere <fmmainere@gmail.com>, 2013
# Gustavo Gómez <gustavo.gomez@nuevosmedios.ws>, 2013
# Gustavo Gómez <gustavo.gomez@nuevosmedios.ws>, 2013
# Victor Trujillo <>, 2012
@@ -12,8 +13,8 @@ msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:06-0500\n"
-"PO-Revision-Date: 2013-08-08 15:45+0000\n"
-"Last-Translator: Adolfo Fitoria <adolfo.fitoria@gmail.com>\n"
+"PO-Revision-Date: 2013-08-27 19:14+0000\n"
+"Last-Translator: fmmainere <fmmainere@gmail.com>\n"
"Language-Team: Spanish (http://www.transifex.com/projects/p/askbot/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -82,12 +83,12 @@ msgstr[1] "debe de ser > %d caracteres"
#: forms.py:270
#, python-format
msgid "The question is too long, maximum allowed size is %d characters"
-msgstr ""
+msgstr "La pregunta es muy larga, el tamaño máximo permitido es de %d caracteres"
#: forms.py:277
#, python-format
msgid "The question is too long, maximum allowed size is %d bytes"
-msgstr ""
+msgstr "La pregunta es muy larga, el maximo permitido es de %d bytes"
#: forms.py:309
msgid "content"
@@ -710,7 +711,7 @@ msgstr "Este parámetro toma su valor predeterminado de la configuración de dja
#: conf/email.py:44
msgid "Site administrator email address"
-msgstr ""
+msgstr "Dirección de correo electronico del administrador del sitio"
#: conf/email.py:53
msgid "Enable email alerts"
@@ -1094,25 +1095,25 @@ msgstr "Marca la casilla para permitir a los usuarios enviar preguntas o respues
#: conf/forum_data_rules.py:118
msgid "Auto-follow questions by the Author"
-msgstr ""
+msgstr "Auto-seguir preguntas hechas por el Autor"
#: conf/forum_data_rules.py:123
msgid "Fully open by default"
-msgstr ""
+msgstr "Abierto del todo por defecto"
#: conf/forum_data_rules.py:124
msgid "Folded by default"
-msgstr ""
+msgstr "Plegado por defecto"
#: conf/forum_data_rules.py:133
msgid "Question details/body editor should be"
-msgstr ""
+msgstr "El editor de detalles/cuerpo de la pregunta debe ser"
#: conf/forum_data_rules.py:135
msgid ""
"To use folded mode, please first set minimum question body length to 0. Also"
" - please make tags optional."
-msgstr ""
+msgstr "Para usar el modo plegado, por favor establezca el largo mínimo del cuerpo de la respuesta a 0. Ademas, haga las etiquetas opcionales."
#: conf/forum_data_rules.py:147
msgid "Allow swapping answer with question"
@@ -1142,7 +1143,7 @@ msgstr "Tamaño minimo de la respuesta (numero de caracteres)"
#: conf/forum_data_rules.py:202
msgid "Minimum length of comment (number of characters)"
-msgstr ""
+msgstr "Longitud mínima del comentario(numero de caracteres)"
#: conf/forum_data_rules.py:213
msgid "Limit one answer per question per user"
@@ -1311,7 +1312,7 @@ msgstr "Configuración de grupos"
#: conf/group_settings.py:18
msgid "Enable user groups"
-msgstr ""
+msgstr "Habilitar grupos de usuarios"
#: conf/group_settings.py:41
msgid "everyone"
@@ -1335,7 +1336,7 @@ msgstr "Si está seleccionada, los usuarios pueden publicar a los grupos con el
#: conf/karma_and_badges_visibility.py:12
msgid "Karma & Badge visibility"
-msgstr ""
+msgstr "Visibilidad de Karma y Medallas"
#: conf/karma_and_badges_visibility.py:27
msgid "Visibility of karma"
@@ -1343,7 +1344,7 @@ msgstr "Visibilidad de reputacion"
#: conf/karma_and_badges_visibility.py:30
msgid "User's karma may be shown publicly or only to the owners"
-msgstr ""
+msgstr "El Karma del usuario puede ser mostrado públicamente solo a sus dueños"
#: conf/karma_and_badges_visibility.py:44
msgid "Visibility of badges"
@@ -1769,7 +1770,7 @@ msgstr "Hacer publicaciones por email"
#: conf/minimum_reputation.py:223
msgid "Trigger email notifications"
-msgstr ""
+msgstr "Disparar notificaciones por correo electrónico "
#: conf/minimum_reputation.py:224 conf/minimum_reputation.py:234
msgid "Reduces spam"
@@ -1777,7 +1778,7 @@ msgstr "Reduce spam"
#: conf/minimum_reputation.py:233
msgid "Trigger tweets on others accounts"
-msgstr ""
+msgstr "Disparar tweets en otras cuentas"
#: conf/moderation.py:19
msgid "Content moderation"
@@ -1808,15 +1809,15 @@ msgstr ""
#: conf/question_lists.py:21 conf/question_lists.py:31
#: conf/question_lists.py:41
msgid "At least one of these selectors must be enabled"
-msgstr ""
+msgstr "Por lo menos uno de estos selectores debe estar habilitado"
#: conf/question_lists.py:30
msgid "Enable \"Unanswered Questions\" selector"
-msgstr ""
+msgstr "Habilitar el selector \"Preguntas sin contestar\""
#: conf/question_lists.py:40
msgid "Enable \"Followed Questions\" selector"
-msgstr ""
+msgstr "Habilitar el selector \"Preguntas Seguidas\""
#: conf/question_lists.py:53 conf/question_lists.py:70
msgid "All Questions"
@@ -1832,11 +1833,11 @@ msgstr "Preguntas seguidas"
#: conf/question_lists.py:64
msgid "Default questions selector for the authenticated users"
-msgstr ""
+msgstr "Selector de preguntas por defecto para usuarios autenticados"
#: conf/question_lists.py:80
msgid "Default questions selector for the anonymous users"
-msgstr ""
+msgstr "Selector de preguntas por defecto para usuarios anonimos"
#: conf/reputation_changes.py:13
msgid "Karma loss and gain rules"
@@ -1918,7 +1919,7 @@ msgstr "Utiliza este area para introducir el contenido en la parte superior de
#: conf/sidebar_question.py:34 conf/sidebar_question.py:58
#: conf/sidebar_question.py:84 conf/sidebar_question.py:149
msgid "Show above only to anonymous users"
-msgstr ""
+msgstr "Abajo mostrar solo a los usuarios anonimos"
#: conf/sidebar_main.py:45
msgid "Show avatar block in sidebar"
@@ -1969,11 +1970,11 @@ msgstr "Barra lateral del perfil de usuario"
#: conf/sidebar_profile.py:20
msgid "Custom sidebar"
-msgstr ""
+msgstr "Barra lateral personalizada"
#: conf/sidebar_question.py:11
msgid "Question page banners and sidebar"
-msgstr ""
+msgstr "Barra lateral y carteles de la página de pregunta"
#: conf/sidebar_question.py:19
msgid "Top banner"
@@ -1983,7 +1984,7 @@ msgstr "Banner superior"
msgid ""
"When using this option, please use the HTML validation service to make sure "
"that your input is valid and works well in all browsers."
-msgstr ""
+msgstr "Cuando utilice esta opción, por favor use el servicio de validación de HTML para asegurarse de que lo que usted ingresó es válido y funciona bien en todos los navegadores."
#: conf/sidebar_question.py:42
msgid "Answers banner"
@@ -2076,7 +2077,7 @@ msgstr "Por favor introduzca la URL de su sitio"
#: conf/site_settings.py:73
msgid "Url must start either from http or https"
-msgstr ""
+msgstr "La url debe empezar o con http o con https"
#: conf/site_settings.py:92
msgid "Base URL for your Q&A forum, must start with http or https"
@@ -2384,7 +2385,7 @@ msgid ""
"Important - to actually start sharing on twitter, it is required to set up "
"Twitter consumer key and secret in the \"keys to external services\" "
"section."
-msgstr ""
+msgstr "Importante - para empezar a compartir en twitter, es requerido que ingrese su Twitter consumer key y secret en la sección de \"claves de servicios externos\""
#: conf/social_sharing.py:52
msgid "Check to enable sharing of questions on Facebook"
@@ -3237,7 +3238,7 @@ msgstr "OpenID %(openid_url)s incorrecto"
msgid ""
"Sorry, there was some problem connecting to the login provider, please try "
"again or use another login method"
-msgstr ""
+msgstr "Lo lamentamos, hubo un problema conectándonos con el proveedor de acceso, por favor intente de nuevo usando otro método de acceso"
#: deps/django_authopenid/views.py:520
msgid "Your new password saved"
@@ -3291,7 +3292,7 @@ msgstr "Lo siento, se ha producido un error, inténtalo de nuevo."
msgid ""
"If you are trying to sign in to another account, please sign out first. "
"Otherwise, please report the incident to the site administrator."
-msgstr ""
+msgstr "Si está intentando ingresar en otra cuenta, cierre esta cuenta primero. Si no es así, por favor reporte el incidente al administrador del sitio."
#: deps/django_authopenid/views.py:914
#, python-format
@@ -3302,7 +3303,7 @@ msgstr "Tu login de %(provider)s funciona correctamente"
msgid ""
"Sorry, registration failed. The token can be already used or has expired. "
"Please try again"
-msgstr ""
+msgstr "Lo lamentamos, el registro fallo. Su token ya fue usado o ha expirado. Por favor intente nuevamente"
#: deps/django_authopenid/views.py:1257
#, python-format
@@ -3876,8 +3877,8 @@ msgstr "%(user)s tiene %(badges)s"
#, python-format
msgid "At least %d karma point is required to post links"
msgid_plural "At least %d karma points is required to post links"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Como mínimo %d punto de karma es requerido para publicar enlaces"
+msgstr[1] "Como mínimo %d puntos de karma son requeridos para publicar enlaces"
#: models/__init__.py:3159
#, python-format
@@ -5504,7 +5505,7 @@ msgid ""
"<strong>Email Address</strong> (<i>will <strong>not</strong> be shared with \n"
"anyone, must be valid</i>)\n"
" "
-msgstr ""
+msgstr "<strong>Dirección de correo electrónico</strong> (<i><strong>no</strong> va a ser compartida con \nnadie, debe ser valida</i>)\n "
#: templates/authopenid/complete.html:71
#: templates/authopenid/signup_with_password.html:5
@@ -5642,7 +5643,7 @@ msgstr "Por favor, comprueba tu email y haz click en el link que te enviamos par
#: templates/authopenid/signin.html:90
msgid "or enter your <span>user name and password</span>"
-msgstr ""
+msgstr "o ingrese su <span>nombre de usuario y contraseña</span>"
#: templates/authopenid/signin.html:94
#: templates/authopenid/widget_signin.html:98
@@ -5891,14 +5892,14 @@ msgstr "Trataremos de detectar la firma en tu respuesta y deberás podes publica
msgid ""
"To change frequency, language and content of these alerts, please visit <a "
"href=\"%(url)s\">your user profile</a>."
-msgstr ""
+msgstr "Para cambiar la frecuencia, el lenguaje y el contenido de las alertas, por favor visite <a href=\"%(url)s\">su perfil de usuario</a>."
#: templates/email/change_settings_info.html:6
#, python-format
msgid ""
"To change freqency and content of these alerts, please visit <a "
"href=\"%(url)s\">your user profile</a>."
-msgstr ""
+msgstr "Para cambiar la frecuencia, el lenguaje y el contenido de las alertas, por favor visite <a href=\"%(url)s\">su perfil de usuario</a>."
#: templates/email/change_settings_info.html:10
#, python-format
@@ -5906,7 +5907,7 @@ msgid ""
"If you believe that this message was sent in an error, please email about it"
" the forum administrator at <a "
"href=\"mailto:%(admin_email)s\">%(admin_email)s</a>."
-msgstr ""
+msgstr "Si usted piensa que este mensaje ha sido enviado por error, por favor envié un correo electronico al administrador del sitio a <a href=\"mailto:%(admin_email)s\">%(admin_email)s</a>."
#: templates/email/delayed_email_alert.html:2
#, python-format
@@ -6052,7 +6053,7 @@ msgstr "Puedes publicar pregutnas mandandolas por correo a %(ask_address)s."
msgid ""
"When you receive update notifications, you will be able to respond to them, "
"also by email."
-msgstr ""
+msgstr "Cuando recibas notificaciones, podrás contestarlas, también por correo electrónico."
#: templates/email/re_welcome_lamson_on.html:9
#, python-format
@@ -6100,14 +6101,14 @@ msgid ""
"Important: <em>Please reply</em> to this message, without editing it. We "
"need this to determine your email signature and that the email address is "
"valid and was typed correctly."
-msgstr ""
+msgstr "Importante: <em>Por favor responda</em> a este mensaje, sin editarlo. Necesitamos determinar que la firma de su correo electronico y su dirección son válidas y fueron tipeadas correctamente."
#: templates/email/welcome_lamson_on.html:14
#, python-format
msgid ""
"Until we receive the response from you, you will not be able ask or answer "
"questions on %(site_name)s by email."
-msgstr ""
+msgstr "Hasta que recibamos una respuesta de usted, no le será posible preguntar o responder preguntas en %(site_name)s por correo electronico."
#: templates/embed/list_widgets.html:44
msgid "How to use?"
@@ -6118,12 +6119,12 @@ msgid ""
"\n"
" Just copy the &lt;script&gt; tag provided and paste it in the site where you wan to put it.\n"
" "
-msgstr ""
+msgstr "\n Just copy the &lt;script&gt; tag provided and paste it in the site where you wan to put it.\n "
#: templates/embed/widget_form.html:3 templates/embed/widget_form.html.py:5
#, python-format
msgid "%(action)s an %(widget_name)s widget"
-msgstr ""
+msgstr "%(action)s un widget %(widget_name)s "
#: templates/embed/widget_form.html:14
#: templates/user_profile/user_moderate.html:20
@@ -6137,7 +6138,7 @@ msgstr "Widgets"
#: templates/embed/widgets.html:11
msgid ""
"Create and embed widgets into your sites, here a list of available widgets."
-msgstr ""
+msgstr "Cree y embeba widgets a sus sitios, aquí hay una lista de widgets disponibles"
#: templates/embed/widgets.html:16
msgid "Ask a question"
@@ -6158,27 +6159,27 @@ msgstr "Lista de preguntas"
#: templates/group_messaging/email_alert.html:7
#, python-format
msgid "%(author)s wrote:"
-msgstr ""
+msgstr "%(author)s escribió:"
#: templates/group_messaging/email_alert.html:11
msgid ""
"To reply please <a class=\"thread-link\" href=\"THREAD_URL_HOLE\">visit your"
" message inbox</a>"
-msgstr ""
+msgstr "Para contestar por favor <a class=\"thread-link\" href=\"THREAD_URL_HOLE\">visite su bandeja de entrada</a>"
#: templates/group_messaging/home.html:7
#: templates/group_messaging/home_thread_details.html:7
msgid "compose"
-msgstr ""
+msgstr "escribir"
#: templates/group_messaging/macros.html:5
#, python-format
msgid "You wrote on %(date)s:"
-msgstr ""
+msgstr "Usted escribió el dia %(date)s:"
#: templates/group_messaging/senders_list.html:3
msgid "Messages by sender:"
-msgstr ""
+msgstr "Mensajes por remitente:"
#: templates/group_messaging/senders_list.html:5
#: templates/user_inbox/base.html:6 templates/user_profile/user_tabs.html:12
@@ -6430,7 +6431,7 @@ msgstr "revivir"
#: templates/question/answer_controls.html:43
msgid "unpublish"
-msgstr ""
+msgstr "no publicar"
#: templates/question/answer_controls.html:48
msgid "publish"
@@ -6509,11 +6510,11 @@ msgstr "fecha de cierre %(closed_at)s"
#: templates/question/content.html:33
msgid "Edit Your Previous Answer"
-msgstr ""
+msgstr "Editar tu respuesta anterior"
#: templates/question/content.html:34
msgid "(only one answer per user is allowed)"
-msgstr ""
+msgstr "(Solo una respuesta por usuario es permitida)"
#: templates/question/new_answer_form.html:12
msgid "Login/Signup to Answer"
@@ -6660,7 +6661,7 @@ msgstr "Hilo público"
#, python-format
msgid ""
"This thread is public, all members of %(site_name)s can read this page."
-msgstr ""
+msgstr "Este hilo es publico, todos los miembros de %(site_name)s pueden leer esta página."
#: templates/question/sidebar.html:135
msgid "Stats"
@@ -6692,12 +6693,12 @@ msgstr "Subscripciones de etiqueta"
#: templates/tags/form_bulk_tag_subscription.html:6
msgid "Tag Subscriptions"
-msgstr ""
+msgstr "Etiquetar suscripciones"
#: templates/tags/header.html:7
#, python-format
msgid "Tags, matching \"%(tag_query)s\""
-msgstr ""
+msgstr "Etiquetas que coinciden con \"%(tag_query)s\""
#: templates/tags/header.html:19
msgid "sorted alphabetically"
@@ -6729,7 +6730,7 @@ msgstr "Administrar subscripciones de etiquetas"
#: templates/tags/list_bulk_tag_subscription.html:6
msgid "Manage Tag subscription</a> "
-msgstr ""
+msgstr "Editar suscripción a etiquetas\n</a>"
#: templates/tags/list_bulk_tag_subscription.html:6
msgid "Create New"
@@ -6763,15 +6764,15 @@ msgstr "respuestas (%(re_count)s)"
#: templates/user_inbox/base.html:31
#, python-format
msgid "flagged items (%(flags_count)s)"
-msgstr ""
+msgstr "Elementos marcados (%(flags_count)s)"
#: templates/user_inbox/base.html:38
msgid "group join requests"
-msgstr ""
+msgstr "solicitudes de adhesion a grupos"
#: templates/user_inbox/group_join_requests.html:4
msgid "inbox - group join requests"
-msgstr ""
+msgstr "Bandeja de entrada - solicitudes de adhesión a grupos"
#: templates/user_inbox/group_join_requests.html:26
msgid "Approve"
@@ -6783,11 +6784,11 @@ msgstr "Denegar"
#: templates/user_inbox/messages.html:104
msgid "inbox - messages"
-msgstr ""
+msgstr "Bandeja de entrada - mensajes"
#: templates/user_inbox/responses_and_flags.html:4
msgid "inbox - responses"
-msgstr ""
+msgstr "Bandeja de entrada - Respuestas"
#: templates/user_inbox/responses_and_flags.html:8
msgid "select:"
@@ -6819,7 +6820,7 @@ msgstr "cancelar"
#: templates/user_inbox/responses_and_flags.html:19
msgid "remove flags/approve"
-msgstr ""
+msgstr "quitar marcas/aprobar"
#: templates/user_inbox/responses_and_flags.html:23
msgid "delete post"
@@ -6831,16 +6832,16 @@ msgstr "Rechazar la(s) publicación(es)?"
#: templates/user_profile/reject_post_dialog.html:11
msgid "1) Enter a brief description of why you are rejecting the post."
-msgstr ""
+msgstr "1) Ingrese una breve descripcion de porque usted está rechazando esta publicación"
#: templates/user_profile/reject_post_dialog.html:14
msgid "2) Please enter details here. This text will be sent to the user."
-msgstr ""
+msgstr "2) Por favor ingrese detalles aqui. Este texto será enviado al usuario."
#: templates/user_profile/reject_post_dialog.html:20
#: templates/user_profile/reject_post_dialog.html:88
msgid "Use this reason &amp; reject"
-msgstr ""
+msgstr "Usar esta razón &amp; rechazar"
#: templates/user_profile/reject_post_dialog.html:27
#: templates/user_profile/reject_post_dialog.html:95
@@ -6853,7 +6854,7 @@ msgstr "Guardar razón pero no rechazar"
#: templates/user_profile/reject_post_dialog.html:43
msgid "Please, choose a reason for the rejection."
-msgstr ""
+msgstr "Por favor, elija una razón para el rechazo."
#: templates/user_profile/reject_post_dialog.html:58
msgid "Select this reason"
@@ -6881,7 +6882,7 @@ msgstr "Editar esta razón"
#: templates/user_profile/twitter_sharing_controls.html:8
#, python-format
msgid "Auto-tweeting to @%(handle)s"
-msgstr ""
+msgstr "Auto-tweeteando a @%(handle)s"
#: templates/user_profile/twitter_sharing_controls.html:19
msgid "stop tweeting"
@@ -7119,7 +7120,7 @@ msgstr "Los usuarios suspendidos solo pueden editar o eliminar sus propios posts
msgid ""
"Blocked users can only login and send feedback to the site administrators, "
"their url and profile will also be hidden."
-msgstr ""
+msgstr "Los usuarios bloqueados solo pueden acceder y enviar aportes a los administradores del sitio, su url y perfil también estaran ocultos."
#: templates/user_profile/user_network.html:5
#: templates/user_profile/user_tabs.html:18
@@ -7316,7 +7317,7 @@ msgstr "Vista preliminar en tiempo real del editor Markdown"
msgid ""
"To post on behalf of someone else, enter user name <strong>and</strong> "
"email below."
-msgstr ""
+msgstr "Para publicar en lugar de alguien mas, ingrese su nombre <strong>y</strong> su email abajo."
#: templates/widgets/footer.html:33
#, python-format
@@ -7365,7 +7366,7 @@ msgstr "moderar preguntas enviadas por email"
#: templates/widgets/group_info.html:58
msgid "show only selected answers to enquirers"
-msgstr ""
+msgstr "mostrar solo las respuestas seleccionadas a buscadores"
#: templates/widgets/group_info.html:63
msgid "How users join this group?"
@@ -7390,7 +7391,7 @@ msgstr "Lista de direcciones de correo pre-aprobadas"
#: templates/widgets/group_info.html:108
msgid ""
"Users with these email adderesses will be added to the group automatically."
-msgstr ""
+msgstr "Los usuarios con esta dirección de correo electrónico va a ser añadida al grupo automaticamente. "
#: templates/widgets/group_info.html:109
msgid "edit preapproved emails"
@@ -7398,21 +7399,21 @@ msgstr "editar direcciones de correo pre-aprobadas"
#: templates/widgets/group_info.html:113
msgid "list of preapproved email address domain names"
-msgstr ""
+msgstr "lista de dominios de direcciones de correo electrónico pre-aprobadas."
#: templates/widgets/group_info.html:118
msgid "List of preapproved email domain names"
-msgstr ""
+msgstr "Lista de nombres de dominio de correo electronico pre-aprobados"
#: templates/widgets/group_info.html:119
msgid ""
"Users whose email adderesses belong to these domains will be added to the "
"group automatically."
-msgstr ""
+msgstr "Los usuarios cuyas direcciones de email pertenecen a estos dominios van a ser agregados al grupo automáticamente."
#: templates/widgets/group_info.html:120
msgid "edit preapproved email domains"
-msgstr ""
+msgstr "editar dominios de correo electronico pre-aprobados"
#: templates/widgets/logo.html:3
msgid "back to home page"
@@ -7550,12 +7551,12 @@ msgstr "Cambiar la frecuencia de correo electrónico"
msgid ""
"Categorize your question using this tag selector or entering text in tag "
"box."
-msgstr ""
+msgstr "Categorice su pregunta usando el selector de etiquetas o ingresando texto en la caja de etiquetas"
#: templates/widgets/three_column_category_selector.html:7
#: templates/widgets/three_column_category_selector.html:10
msgid "(done editing)"
-msgstr ""
+msgstr "(Terminé de editar)"
#: templates/widgets/three_column_category_selector.html:8
#: templates/widgets/three_column_category_selector.html:9
@@ -7581,7 +7582,7 @@ msgstr "cerrar sesión"
#: templates/widgets/user_navigation.html:20
msgid "Hi there! Please sign in"
-msgstr ""
+msgstr "Hola! Ingrese por favor"
#: templates/widgets/user_navigation.html:23
msgid "settings"
@@ -7598,18 +7599,18 @@ msgstr "Su reputación es %(karma)s"
#: templates/widgets/user_perms.html:4
msgid "Karma reflects the value of your contribution to this community."
-msgstr ""
+msgstr "El Karma refleja el valor de tu contribución a esta comunidad."
#: templates/widgets/user_perms.html:13
#, python-format
msgid ""
"Since you are the site %(role)s, you have access to all functions regardless"
" of your karma."
-msgstr ""
+msgstr "Como eres el %(role)s del sitio, tienes acceso a todas las funciones sin importar tu karma."
#: templates/widgets/user_perms.html:15
msgid "The higher is your karma, the more rights you have on this site."
-msgstr ""
+msgstr "Cuanto mas alto es tu karma, más derechos tienes en este sitio."
#: templates/widgets/user_perms.html:19
msgid "Currently, you can:"
@@ -7637,7 +7638,7 @@ msgstr "Se ha detectado spam en tu post, perdona si esto es un error"
#: utils/decorators.py:243
msgid "This function is limited to moderators and administrators"
-msgstr ""
+msgstr "Esta funcion es limitada solo a moderadores y administradores"
#: utils/forms.py:66
msgid "this field is required"
@@ -7822,12 +7823,12 @@ msgstr "EL grupo %(name)s no existe"
#: views/commands.py:1408 views/commands.py:1441
msgid "Sorry, looks like sharing request was invalid"
-msgstr ""
+msgstr "Lo lamentamos, parece que su pedido de compartir es invalido"
#: views/commands.py:1464
#, python-format
msgid "%(user)s, welcome to group %(group)s!"
-msgstr ""
+msgstr "%(user)s, bienvenido al grupo %(group)s!"
#: views/commands.py:1521
msgid "Sorry, only thread moderators can use this function"
@@ -7848,7 +7849,7 @@ msgstr "Sobre %(site)s"
#: views/meta.py:91
msgid "Please sign in or register to send your feedback"
-msgstr ""
+msgstr "Por favor ingrese o registresé para enviarnos sus sugerencias"
#: views/meta.py:118
msgid "Q&A forum feedback"
@@ -7875,7 +7876,7 @@ msgstr "Etiquetas sugeridas"
msgid ""
"Please go to <a href=\"%s\">\"settings->URLs, keywords and greetings\"</a> "
"and set the base url for your site to function properly"
-msgstr ""
+msgstr "Por favor vaya a <a href=\"%s\">\"configuraciones->URLs, palabras clave y saludos\"</a> y establezca la url del sitio para que funcione apropiadamente"
#: views/readers.py:421
msgid ""
@@ -7905,7 +7906,7 @@ msgstr "perfil - actividad reciente"
#: views/users.py:682
msgid "group joining requests"
-msgstr ""
+msgstr "solicitudes de adhesión a grupos"
#: views/users.py:683
msgid "profile - moderation"
@@ -8024,14 +8025,14 @@ msgstr "lo sentimos, tenemos dificultades técnicas"
#: views/writers.py:888
msgid "Error - could not find the destination post"
-msgstr ""
+msgstr "Error - no se puede encontrar la publicación de destino"
#: views/writers.py:912
#, python-format
msgid ""
"Cannot convert, because text has more characters than %(max_chars)s - "
"maximum allowed for comments"
-msgstr ""
+msgstr "No se puede convertir, porque el texto tiene mas caracteres que %(max_chars)s - el maximo permitido para comentarios"
#~ msgid "your email needs to be validated see %(details_url)s"
#~ msgstr ""
diff --git a/askbot/locale/fr/LC_MESSAGES/django.mo b/askbot/locale/fr/LC_MESSAGES/django.mo
index ad9b2875..de12940d 100644
--- a/askbot/locale/fr/LC_MESSAGES/django.mo
+++ b/askbot/locale/fr/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/fr/LC_MESSAGES/django.po b/askbot/locale/fr/LC_MESSAGES/django.po
index 2df654dc..76ec2105 100644
--- a/askbot/locale/fr/LC_MESSAGES/django.po
+++ b/askbot/locale/fr/LC_MESSAGES/django.po
@@ -4,14 +4,15 @@
#
# Translators:
# Alban Tiberghien <alban.tiberghien@gmail.com>, 2012
+# noirbizarre <noirbizarre@gmail.com>, 2013
# Camille Baldock <mademoisellegeek42@gmail.com>, 2011
# Christophe kryskool <christophe.chauvet@gmail.com>, 2011-2013
# Emmanuel <emmanuel@raviart.com>, 2013
# evgeny <evgeny.fadeev@gmail.com>, 2009
-# fbureau <francois.bureau@cloudwatt.com>, 2013
+# François Bureau <francois.bureau@cloudwatt.com>, 2013
# florent <fpam1108@gmail.com>, 2012
# florent <fpam1108@gmail.com>, 2012
-# fbureau <francois.bureau@cloudwatt.com>, 2013
+# François Bureau <francois.bureau@cloudwatt.com>, 2013
# Camille Baldock <mademoisellegeek42@gmail.com>, 2011
# Camille Baldock <mademoisellegeek42@gmail.com>, 2011
msgid ""
@@ -19,8 +20,8 @@ msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:06-0500\n"
-"PO-Revision-Date: 2013-08-10 20:34+0000\n"
-"Last-Translator: Emmanuel <emmanuel@raviart.com>\n"
+"PO-Revision-Date: 2013-09-27 13:14+0000\n"
+"Last-Translator: noirbizarre <noirbizarre@gmail.com>\n"
"Language-Team: French (http://www.transifex.com/projects/p/askbot/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -1109,7 +1110,7 @@ msgstr "Complètement ouvert par défaut"
#: conf/forum_data_rules.py:124
msgid "Folded by default"
-msgstr ""
+msgstr "Replié par défaut"
#: conf/forum_data_rules.py:133
msgid "Question details/body editor should be"
@@ -1815,7 +1816,7 @@ msgstr "Activer le sélecteur \"Toutes les questions\""
#: conf/question_lists.py:21 conf/question_lists.py:31
#: conf/question_lists.py:41
msgid "At least one of these selectors must be enabled"
-msgstr ""
+msgstr "Au moins un de ces sélecteurs doit être activé"
#: conf/question_lists.py:30
msgid "Enable \"Unanswered Questions\" selector"
@@ -1976,7 +1977,7 @@ msgstr "Identification utilisateur"
#: conf/sidebar_profile.py:20
msgid "Custom sidebar"
-msgstr ""
+msgstr "Barre latérale personnalisée"
#: conf/sidebar_question.py:11
msgid "Question page banners and sidebar"
@@ -3467,7 +3468,7 @@ msgstr "Veuillez vous connecter pour utiliser %s"
#: models/__init__.py:569 models/__init__.py:1388 views/writers.py:226
msgid "Sorry, but you have only read access"
-msgstr ""
+msgstr "Désolé, mais vous n'avez q'un accès en lecture seule"
#: models/__init__.py:573
msgid "Sorry, this operation is not allowed"
@@ -5173,7 +5174,7 @@ msgstr "Voir les questions marquées par '%(tag)s'."
#: templates/macros.html:395
msgid "Comments"
-msgstr ""
+msgstr "Commentaires"
#: templates/macros.html:430
msgid "delete this comment"
@@ -5274,7 +5275,7 @@ msgstr "voir plus de commentaires"
#: templates/question.html:232 templates/question.html.py:335
msgid "add a comment"
-msgstr ""
+msgstr "ajouter un commentaire"
#: templates/question.html:245 templates/question/content.html:46
msgid "Answer Your Own Question"
@@ -5918,15 +5919,15 @@ msgstr ""
#: templates/email/delayed_email_alert.html:2
#, python-format
msgid "Dear %(name)s,"
-msgstr ""
+msgstr "Cher %(name)s,"
#: templates/email/delayed_email_alert.html:3
#, python-format
msgid "The following question has been updated %(site_name)s:"
msgid_plural ""
"The following %(num)s questions have been updated on %(site_name)s:"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "La question suivante a été mise à jour %(site_name)s:"
+msgstr[1] "Les %(num)s questions suivantes ont été mises à jour sur %(site_name)s:"
#: templates/email/feedback_email.txt:2
#, python-format
@@ -6041,8 +6042,8 @@ msgid_plural ""
"\n"
" %(count)s comments:\n"
" "
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "\n%(count)s commentaire:"
+msgstr[1] "\n%(count)s commentaires:"
#: templates/email/re_welcome_lamson_on.html:2
#: templates/email/re_welcome_lamson_on.html:3
@@ -6532,7 +6533,7 @@ msgstr "Votre réponse"
#: templates/question/new_answer_form.html:22
msgid "Be the first one to answer this question!"
-msgstr "Soyez le premier à répondre à cette quesion !"
+msgstr "Soyez le premier à répondre à cette question !"
#: templates/question/new_answer_form.html:28
msgid ""
@@ -7543,11 +7544,11 @@ msgstr ""
#: templates/widgets/tag_selector.html:59
msgid "Show only questions from"
-msgstr ""
+msgstr "Ne montrer que les questions de"
#: templates/widgets/tag_selector.html:70
msgid "Send me email alerts for"
-msgstr ""
+msgstr "Envoyez-moi des alertes par email pour"
#: templates/widgets/tag_selector.html:86
msgid "Change frequency of emails"
@@ -7684,7 +7685,7 @@ msgstr "veuillez utiliser au moins quelques caractères alphabétiques dans le n
#: utils/forms.py:110
msgid "symbol \"@\" is not allowed"
-msgstr ""
+msgstr "symbole \"@\" non autorisé"
#: utils/forms.py:222
msgid "Your email <i>(never shared)</i>"
@@ -7704,7 +7705,7 @@ msgstr "Cette adresse email est déjà utilisée par un autre utilisateur; veuil
#: utils/forms.py:227
msgid "this email address is not authorized"
-msgstr ""
+msgstr "cette adresse email n'est pas autorisée"
#: utils/forms.py:265
msgid "password is required"
@@ -7825,7 +7826,7 @@ msgstr "Veuillez vous inscrire pour supprimer/récupérer une publication"
#: views/commands.py:1042
#, python-format
msgid "Group %(name)s does not exist"
-msgstr ""
+msgstr "Le groupe %(name)s n'existe pas"
#: views/commands.py:1408 views/commands.py:1441
msgid "Sorry, looks like sharing request was invalid"
@@ -7920,7 +7921,7 @@ msgstr ""
#: views/users.py:739
msgid "private messages"
-msgstr ""
+msgstr "messages privés"
#: views/users.py:740
msgid "profile - messages"
diff --git a/askbot/locale/fr/LC_MESSAGES/djangojs.po b/askbot/locale/fr/LC_MESSAGES/djangojs.po
index 22b9918d..8cf842e3 100644
--- a/askbot/locale/fr/LC_MESSAGES/djangojs.po
+++ b/askbot/locale/fr/LC_MESSAGES/djangojs.po
@@ -6,8 +6,8 @@
# Camille Baldock <mademoisellegeek42@gmail.com>, 2011
# Christophe kryskool <christophe.chauvet@gmail.com>, 2011-2013
# Emmanuel <emmanuel@raviart.com>, 2013
-# fbureau <francois.bureau@cloudwatt.com>, 2013
-# fbureau <francois.bureau@cloudwatt.com>, 2013
+# François Bureau <francois.bureau@cloudwatt.com>, 2013
+# François Bureau <francois.bureau@cloudwatt.com>, 2013
# Camille Baldock <mademoisellegeek42@gmail.com>, 2011
msgid ""
msgstr ""
diff --git a/askbot/locale/it/LC_MESSAGES/django.mo b/askbot/locale/it/LC_MESSAGES/django.mo
index fc17f1a6..01c3c6bc 100644
--- a/askbot/locale/it/LC_MESSAGES/django.mo
+++ b/askbot/locale/it/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/it/LC_MESSAGES/django.po b/askbot/locale/it/LC_MESSAGES/django.po
index ee277555..bd5a1054 100644
--- a/askbot/locale/it/LC_MESSAGES/django.po
+++ b/askbot/locale/it/LC_MESSAGES/django.po
@@ -6,13 +6,14 @@
# evgeny <evgeny.fadeev@gmail.com>, 2009
# giohappy <giohappy@gmail.com>, 2013
# giohappy <giohappy@gmail.com>, 2013
+# noizer, 2013
msgid ""
msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:06-0500\n"
-"PO-Revision-Date: 2013-08-02 06:24+0000\n"
-"Last-Translator: evgeny <evgeny.fadeev@gmail.com>\n"
+"PO-Revision-Date: 2013-08-28 14:51+0000\n"
+"Last-Translator: noizer\n"
"Language-Team: Italian (http://www.transifex.com/projects/p/askbot/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -3793,8 +3794,8 @@ msgstr[1] "%(min)d minuti fa"
#, python-format
msgid "%(days)d day"
msgid_plural "%(days)d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%(days)d giorno"
+msgstr[1] "%(days)d giorni"
#: models/__init__.py:2006
#, python-format
@@ -3864,12 +3865,12 @@ msgstr[1] "%(count)d medaglie di bronzo"
#: models/__init__.py:2533
#, python-format
msgid "%(item1)s and %(item2)s"
-msgstr ""
+msgstr "%(item1)s e %(item2)s"
#: models/__init__.py:2535
#, python-format
msgid "%(user)s has %(badges)s"
-msgstr ""
+msgstr "%(user)s ha %(badges)s"
#: models/__init__.py:2682
#, python-format
diff --git a/askbot/locale/it/LC_MESSAGES/djangojs.mo b/askbot/locale/it/LC_MESSAGES/djangojs.mo
index 9fac4301..6aa23a9d 100644
--- a/askbot/locale/it/LC_MESSAGES/djangojs.mo
+++ b/askbot/locale/it/LC_MESSAGES/djangojs.mo
Binary files differ
diff --git a/askbot/locale/it/LC_MESSAGES/djangojs.po b/askbot/locale/it/LC_MESSAGES/djangojs.po
index 70791c4b..183802fb 100644
--- a/askbot/locale/it/LC_MESSAGES/djangojs.po
+++ b/askbot/locale/it/LC_MESSAGES/djangojs.po
@@ -3,14 +3,15 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
+# noizer, 2013
# Valter Mura <valtermura@gmail.com>, 2012
msgid ""
msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:07-0500\n"
-"PO-Revision-Date: 2013-08-02 06:25+0000\n"
-"Last-Translator: evgeny <evgeny.fadeev@gmail.com>\n"
+"PO-Revision-Date: 2013-08-28 14:50+0000\n"
+"Last-Translator: noizer\n"
"Language-Team: Italian (http://www.transifex.com/projects/p/askbot/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -78,11 +79,11 @@ msgstr ""
#: media/js/group_messaging.js:139
msgid "Your message:"
-msgstr ""
+msgstr "Il tuo messaggio:"
#: media/js/group_messaging.js:152
msgid "send"
-msgstr ""
+msgstr "invia"
#: media/js/group_messaging.js:164 media/js/post.js:1809
#: media/js/post.js.c:3081 media/js/post.js.c:4598 media/js/user.js:888
@@ -91,11 +92,11 @@ msgstr "annulla"
#: media/js/group_messaging.js:227
msgid "Reply"
-msgstr ""
+msgstr "Rispondi"
#: media/js/group_messaging.js:236 media/js/group_messaging.js.c:743
msgid "message sent"
-msgstr ""
+msgstr "Messaggio inviato"
#: media/js/group_messaging.js:271
msgid "user {{str}} does not exist"
@@ -105,7 +106,7 @@ msgstr[1] ""
#: media/js/group_messaging.js:278
msgid "cannot send message to yourself"
-msgstr ""
+msgstr "impossibile inviare un messaggio a te stesso"
#: media/js/group_messaging.js:323
msgid "Recipient:"
@@ -117,7 +118,7 @@ msgstr ""
#: media/js/live_search.js:218
msgid "Ask Your Question"
-msgstr ""
+msgstr "Fai la tua domanda"
#: media/js/live_search.js:299
msgid "Sorry, this tag does not exist"
@@ -127,7 +128,7 @@ msgstr[1] ""
#: media/js/live_search.js:313
msgid "search or ask your question"
-msgstr ""
+msgstr "cerca o fai la tua domanda"
#: media/js/post.js:28
msgid "loading..."
@@ -178,11 +179,11 @@ msgstr[1] ""
#: media/js/post.js:253
msgid "Back to the question"
-msgstr ""
+msgstr "Torna alla domanda"
#: media/js/post.js:303
msgid "draft saved..."
-msgstr ""
+msgstr "bozza salvata..."
#: media/js/post.js:548
msgid "insufficient privilege"
@@ -214,7 +215,7 @@ msgstr "conferma che questo post è offensivo"
#: media/js/post.js:559
msgid "please confirm removal of offensive flag"
-msgstr ""
+msgstr "sei certo che questo post sia offensivo, contenga spam, pubblicità, osservazioni poco idonee, ecc.?"
#: media/js/post.js:560
msgid "anonymous users cannot flag offensive posts"
@@ -253,11 +254,11 @@ msgstr "<div>Segui</div><div class=\"unfollow\">Non seguire</div>"
#: media/js/post.js:901
msgid "remove flag"
-msgstr ""
+msgstr "rimuovi flag"
#: media/js/post.js:935 media/js/post.js.c:964
msgid "flag offensive"
-msgstr ""
+msgstr "sei certo che questo post sia offensivo, contenga spam, pubblicità, osservazioni poco idonee, ecc.?"
#: media/js/post.js:990 media/js/post.js.c:1497
msgid "undelete"
diff --git a/askbot/locale/ko/LC_MESSAGES/django.po b/askbot/locale/ko/LC_MESSAGES/django.po
index b674aad2..32d7c156 100644
--- a/askbot/locale/ko/LC_MESSAGES/django.po
+++ b/askbot/locale/ko/LC_MESSAGES/django.po
@@ -10,7 +10,7 @@
# Jihui Choi <jihui.choi@gmail.com>, 2013
# alisol <nocaca@daum.net>, 2012
# seok woojing <ultra066@gmail.com>, 2012
-# Sungjin Gang <potopro@gmail.com>, 2013
+# ujuc Gang <potopro@gmail.com>, 2013
# Whoami Jeong <>, 2012
# Yong Choi <sk8er.choi@gmail.com>, 2012
msgid ""
diff --git a/askbot/locale/ko/LC_MESSAGES/djangojs.mo b/askbot/locale/ko/LC_MESSAGES/djangojs.mo
index a2c4d34e..9e789b0a 100644
--- a/askbot/locale/ko/LC_MESSAGES/djangojs.mo
+++ b/askbot/locale/ko/LC_MESSAGES/djangojs.mo
Binary files differ
diff --git a/askbot/locale/ko/LC_MESSAGES/djangojs.po b/askbot/locale/ko/LC_MESSAGES/djangojs.po
index dd26141d..4e32aa64 100644
--- a/askbot/locale/ko/LC_MESSAGES/djangojs.po
+++ b/askbot/locale/ko/LC_MESSAGES/djangojs.po
@@ -4,15 +4,15 @@
#
# Translators:
# EunMiLee <16thetower@gmail.com>, 2012
-# Sungjin Gang <potopro@gmail.com>, 2013
+# ujuc Gang <potopro@gmail.com>, 2013
# Yong Choi <sk8er.choi@gmail.com>, 2012
msgid ""
msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:07-0500\n"
-"PO-Revision-Date: 2013-08-20 08:22+0000\n"
-"Last-Translator: Sungjin Gang <potopro@gmail.com>\n"
+"PO-Revision-Date: 2013-08-20 16:24+0000\n"
+"Last-Translator: ujuc Gang <potopro@gmail.com>\n"
"Language-Team: Korean (http://www.transifex.com/projects/p/askbot/language/ko/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -144,23 +144,23 @@ msgstr "ì ì–´ë„ í•˜ë‚˜ì˜ íƒœê·¸ë¥¼ 입력하십시오."
#: media/js/post.js:160
msgid "details are required"
-msgstr ""
+msgstr "detailsì´ í•„ìš”í•©ë‹ˆë‹¤."
#: media/js/post.js:163
#, c-format
msgid "details must have > %s character"
msgid_plural "details must have > %s characters"
-msgstr[0] ""
+msgstr[0] "ì ì–´ë„ %s ê¸€ìž ì´ìƒìœ¼ë¡œ ìž…ë ¥ì„ í•´ì£¼ì‹­ì‹œì˜¤."
#: media/js/post.js:171
msgid "enter your question"
-msgstr ""
+msgstr "ì§ˆë¬¸ì„ ìž…ë ¥í•´ì£¼ì„¸ìš”."
#: media/js/post.js:174
#, c-format
msgid "question must have > %s character"
msgid_plural "question must have > %s characters"
-msgstr[0] ""
+msgstr[0] "ì ì–´ë„ %s ê¸€ìž ì´ìƒìœ¼ë¡œ ìž…ë ¥ì„ í•´ì£¼ì‹­ì‹œì˜¤."
#: media/js/post.js:193
msgid "content cannot be empty"
@@ -264,7 +264,7 @@ msgstr "ê¸€ì´ ì‚­ì œë˜ì—ˆìŠµë‹ˆë‹¤."
#: media/js/post.js:1218 media/js/post.js.c:1445
msgid "sorry, something is not right here"
-msgstr ""
+msgstr "죄송합니다. 뭔가 올바르지 않습니다."
#: media/js/post.js:1665
msgid "add comment"
@@ -319,7 +319,7 @@ msgstr "ì§ˆë¬¸ì„ ìž…ë ¥í•´ 주세요 (10ìž ì´ìƒ)"
#: media/js/post.js:2612 media/js/post.js.c:4626
msgid "Sorry, you have only read access"
-msgstr ""
+msgstr "죄송합니다. ì½ê¸°ë§Œ 가능합니다."
#: media/js/post.js:3075 media/js/post.js.c:3869 media/js/post.js.c:4058
msgid "save"
@@ -366,7 +366,7 @@ msgstr "최소 í•˜ë‚˜ì˜ tag를 입력해 주십시오."
#: media/js/post.js:4011
msgid "already exists at the current level!"
-msgstr ""
+msgstr "ì´ë¯¸ 현재 ë ˆë²¨ì´ ì¡´ìž¬í•©ë‹ˆë‹¤!"
#: media/js/post.js:4047
msgid "add category"
@@ -430,35 +430,35 @@ msgstr "ê¸€ì´ ë³µì›ë˜ì—ˆìŠµë‹ˆë‹¤."
#: media/js/user.js:246
msgid "Accept"
-msgstr ""
+msgstr "수ë½"
#: media/js/user.js:255
msgid "Reject"
-msgstr ""
+msgstr "ê±°ì ˆ"
#: media/js/user.js:270
msgid "add new reject reason"
-msgstr ""
+msgstr "새로운 ê±°ì ˆ ì´ìœ  추가"
#: media/js/user.js:375
msgid "Looks there are some things to fix:"
-msgstr ""
+msgstr "해결하기 위한 어떤 것들:"
#: media/js/user.js:443
msgid "Please provide description."
-msgstr ""
+msgstr "ì„¤ëª…ì„ ìž‘ì„±í•˜ì‹­ì‹œì˜¤."
#: media/js/user.js:446
msgid "Please provide details."
-msgstr ""
+msgstr "세부 ì‚¬í•­ì„ ìž‘ì„±í•˜ì‹­ì‹œì˜¤."
#: media/js/user.js:560
msgid "A reason must be selected to delete one."
-msgstr ""
+msgstr "하나를 삭제하려면 ì„ íƒí•˜ì—¬ì•¼ 합니다."
#: media/js/user.js:659
msgid "A reason must be selected to reject post."
-msgstr ""
+msgstr "í¬ìŠ¤íŠ¸ë¥¼ 거절하기 위해서는 ì„ íƒí•˜ì—¬ì•¼ 합니다."
#: media/js/user.js:708
msgid "Please <a href=\"%(signin_url)s\">signin</a> to follow %(username)s"
@@ -481,15 +481,15 @@ msgstr "%s 팔로우"
#: media/js/user.js:883
msgid "add group"
-msgstr ""
+msgstr "그룹 추가"
#: media/js/user.js:963
msgid "add"
-msgstr ""
+msgstr "추가"
#: media/js/utils.js:99
msgid "and"
-msgstr ""
+msgstr "그리고"
#: media/js/utils.js:117
msgid "click to close"
@@ -497,211 +497,211 @@ msgstr "close를 ì„ íƒ"
#: media/js/utils.js:880
msgid "click to edit this comment"
-msgstr ""
+msgstr "í´ë¦­í•˜ì—¬ ì´ ëŒ“ê¸€ 수정"
#: media/js/utils.js:905
msgid "convert to answer"
-msgstr ""
+msgstr "답변 변경"
#: media/js/utils.js:958
msgid "Ok"
-msgstr ""
+msgstr "Ok"
#: media/js/utils.js:959 media/js/utils.js.c:1407
msgid "Cancel"
-msgstr ""
+msgstr "취소"
#: media/js/utils.js:1219
#, c-format
msgid "Uploaded file: %s"
-msgstr ""
+msgstr "íŒŒì¼ ì—…ë¡œë“œ: %s"
#: media/js/utils.js:1234
msgid "Choose a different image"
-msgstr ""
+msgstr "다른 ì´ë¯¸ì§€ ì„ íƒ"
#: media/js/utils.js:1236
msgid "Choose a different file"
-msgstr ""
+msgstr "다른 íŒŒì¼ ì„ íƒ"
#: media/js/utils.js:1250
msgid "Oops, looks like we had an error. Sorry."
-msgstr ""
+msgstr "ì´ëŸ°! 오류가 ë°œìƒí–ˆë„¤ìš”. 죄송합니다."
#: media/js/utils.js:1311
msgid "Choose an image to insert"
-msgstr ""
+msgstr "삽입할 ì´ë¯¸ì§€ ì„ íƒ"
#: media/js/utils.js:1313
msgid "Choose a file to insert"
-msgstr ""
+msgstr "삽입할 íŒŒì¼ ì„ íƒ"
#: media/js/utils.js:1326
msgid "Allowed file types are:"
-msgstr ""
+msgstr "íŒŒì¼ í˜•ì‹ í—ˆìš©:"
#: media/js/utils.js:1332
#: media/js/tinymce/plugins/askbot_attachment/editor_plugin.js:35
msgid "Or paste file url here"
-msgstr ""
+msgstr "íŒŒì¼ urlì„ ì—¬ê¸°ì— ë¶™ì—¬ë„£ê¸° 하십시오."
#: media/js/utils.js:1406
msgid "Save"
-msgstr ""
+msgstr "저장"
#: media/js/utils.js:1478
msgid "saved"
-msgstr ""
+msgstr "저장"
#: media/js/utils.js:1602
msgid "enabled"
-msgstr ""
+msgstr "활성화"
#: media/js/utils.js:1604
msgid "disabled"
-msgstr ""
+msgstr "비활성화"
#: media/js/utils.js:2038
msgid "group name"
-msgstr ""
+msgstr "그룹 ì´ë¦„"
#: media/js/utils.js:2046
msgid "add new group"
-msgstr ""
+msgstr "새로운 그룹 추가"
#: media/js/utils.js:2138
msgid "Group %(name)s already exists. Group names are case-insensitive."
-msgstr ""
+msgstr "그룹 %(name)sì´ ì¡´ìž¬í•©ë‹ˆë‹¤. 그룹 ì´ë¦„ì€ ëŒ€ì†Œë¬¸ìž êµ¬ë¶„í•©ë‹ˆë‹¤."
#: media/js/utils.js:2311
#, c-format
msgid "see questions tagged '%s'"
-msgstr ""
+msgstr "'%s'ë¡œ íƒœê·¸ëœ ì§ˆë¬¸ë“¤ 보기"
#: media/js/utils.js:3358
msgid "ago"
-msgstr ""
+msgstr "ì „"
#: media/js/utils.js:3359
msgid "from now"
-msgstr ""
+msgstr "지금부터"
#: media/js/utils.js:3361
msgid "about a minute"
-msgstr ""
+msgstr "ë¶„ì— ëŒ€í•´ì„œ"
#: media/js/utils.js:3362
#, c-format
msgid "%d minutes"
-msgstr ""
+msgstr "%d 분"
#: media/js/utils.js:3363
msgid "about an hour"
-msgstr ""
+msgstr "ì‹œê°„ì— ëŒ€í•´ì„œ"
#: media/js/utils.js:3364
#, c-format
msgid "%d hours"
-msgstr ""
+msgstr "%d 시간"
#: media/js/utils.js:3365 media/js/utils.js.c:3493
msgid "yesterday"
-msgstr ""
+msgstr "어제"
#: media/js/utils.js:3366
#, c-format
msgid "%d days"
-msgstr ""
+msgstr "%d ì¼"
#: media/js/utils.js:3367
msgid "about a month"
-msgstr ""
+msgstr "ê°œì›”ì— ëŒ€í•´ì„œ"
#: media/js/utils.js:3368
#, c-format
msgid "%d months"
-msgstr ""
+msgstr "%d 개월"
#: media/js/utils.js:3369
msgid "about a year"
-msgstr ""
+msgstr "ë…„ë„ì— ëŒ€í•´"
#: media/js/utils.js:3370
#, c-format
msgid "%d years"
-msgstr ""
+msgstr "%d ë…„"
#: media/js/utils.js:3468
msgid "Jan"
-msgstr ""
+msgstr "1ì›”"
#: media/js/utils.js:3469
msgid "Feb"
-msgstr ""
+msgstr "2ì›”"
#: media/js/utils.js:3470
msgid "Mar"
-msgstr ""
+msgstr "3ì›”"
#: media/js/utils.js:3471
msgid "Apr"
-msgstr ""
+msgstr "4ì›”"
#: media/js/utils.js:3472
msgid "May"
-msgstr ""
+msgstr "5ì›”"
#: media/js/utils.js:3473
msgid "Jun"
-msgstr ""
+msgstr "6ì›”"
#: media/js/utils.js:3474
msgid "Jul"
-msgstr ""
+msgstr "7ì›”"
#: media/js/utils.js:3475
msgid "Aug"
-msgstr ""
+msgstr "8ì›”"
#: media/js/utils.js:3476
msgid "Sep"
-msgstr ""
+msgstr "9ì›”"
#: media/js/utils.js:3477
msgid "Oct"
-msgstr ""
+msgstr "10ì›”"
#: media/js/utils.js:3478
msgid "Nov"
-msgstr ""
+msgstr "11ì›”"
#: media/js/utils.js:3479
msgid "Dec"
-msgstr ""
+msgstr "12ì›”"
#: media/js/utils.js:3491
msgid "2 days ago"
-msgstr ""
+msgstr "ì´í‹€ ì „"
#: media/js/utils.js:3498
#, c-format
msgid "%s hour ago"
msgid_plural "%s hours ago"
-msgstr[0] ""
+msgstr[0] "%s 시간 전"
#: media/js/utils.js:3508
#, c-format
msgid "%s min ago"
msgid_plural "%s mins ago"
-msgstr[0] ""
+msgstr[0] "%s 분 전"
#: media/js/tinymce/plugins/askbot_attachment/editor_plugin.js:71
msgid "Insert a file"
-msgstr ""
+msgstr "íŒŒì¼ ì‚½ìž…"
#: media/js/tinymce/plugins/askbot_imageuploader/editor_plugin.js:70
msgid "Insert image"
-msgstr ""
+msgstr "ì´ë¯¸ì§€ì— 대한 URL를 입력해주세요. 예를들어, http://www.example.com/image.jpg ë˜ëŠ” ì´ë¯¸ì§€ 파ì¼ì„ 올려주세요."
#: media/js/wmd/wmd.js:31
msgid "bold"
@@ -769,15 +769,15 @@ msgstr "업로드할 파ì¼ì„ ì„ íƒí•´ì£¼ì„¸ìš”"
#: media/js/wmd/wmd.js:1836
msgid "image description"
-msgstr ""
+msgstr "ì´ë¯¸ì§€ 설명"
#: media/js/wmd/wmd.js:1839
msgid "file name"
-msgstr ""
+msgstr "íŒŒì¼ ì´ë¦„"
#: media/js/wmd/wmd.js:1843
msgid "link text"
-msgstr ""
+msgstr "ë§í¬ í…스트"
#~ msgid "post a comment"
#~ msgstr "save comment"
diff --git a/askbot/locale/nb_NO/LC_MESSAGES/django.mo b/askbot/locale/nb_NO/LC_MESSAGES/django.mo
index 7016178e..a2c9f2ee 100644
--- a/askbot/locale/nb_NO/LC_MESSAGES/django.mo
+++ b/askbot/locale/nb_NO/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/nb_NO/LC_MESSAGES/django.po b/askbot/locale/nb_NO/LC_MESSAGES/django.po
index f8eacf5c..595720a5 100644
--- a/askbot/locale/nb_NO/LC_MESSAGES/django.po
+++ b/askbot/locale/nb_NO/LC_MESSAGES/django.po
@@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:06-0500\n"
-"PO-Revision-Date: 2013-08-10 19:57+0000\n"
+"PO-Revision-Date: 2013-09-09 22:33+0000\n"
"Last-Translator: injectedreality <transifex@ireality.no>\n"
"Language-Team: Norwegian Bokmål (Norway) (http://www.transifex.com/projects/p/askbot/language/nb_NO/)\n"
"MIME-Version: 1.0\n"
@@ -1367,25 +1367,25 @@ msgid ""
"Potentially reduces number of steps in the registration process but can "
"expose personal information, e.g. when LDAP login name is the same as email "
"address or real name."
-msgstr ""
+msgstr "Reduserer potensielt antall trinn i registreringsprosessen, men kan avsløre personlig informasjon, for eksempel når LDAP login navn er det samme som e-postadressen eller ekte navn."
#: conf/ldap.py:37
msgid "Version 3"
-msgstr ""
+msgstr "Versjon 3"
#: conf/ldap.py:38
msgid "Version 2 (insecure and deprecated)!!!"
-msgstr ""
+msgstr "Versjon 2 (usikker og utgått)!!!"
#: conf/ldap.py:47
msgid "LDAP protocol version"
-msgstr ""
+msgstr "LDAP protokollversjon"
#: conf/ldap.py:49
msgid ""
"Note that Version 2 protocol is not secure!!! Do not use it on unprotected "
"network."
-msgstr ""
+msgstr "Vær oppmerksom at Versjon 2 protokollen ikke er sikker!!! Ikke bruk den på et ubeskyttet nettverk."
#: conf/ldap.py:59
msgid "LDAP URL"
@@ -1393,28 +1393,28 @@ msgstr "LDAP URL"
#: conf/ldap.py:68
msgid "LDAP encoding"
-msgstr ""
+msgstr "LDAP encoding"
#: conf/ldap.py:71
msgid ""
"This value in almost all cases is \"utf-8\". Change it if yours is "
"different. This field is required"
-msgstr ""
+msgstr "Denne verdien i nesten alle tilfeller er \"UTF-8\". Hvis din er forskjellig så kan du endre den. Dette feltet er påkrevd."
#: conf/ldap.py:82
msgid "Base DN (distinguished name)"
-msgstr ""
+msgstr "Base DN (entydig navn)"
#: conf/ldap.py:85
msgid ""
"Usually base DN mirrors domain name of your organization, e.g. "
"\"dn=example,dn=com\" when your site url is \"example.com\".This value is "
"the \"root\" address of your LDAP directory."
-msgstr ""
+msgstr "Vanligvis base DN mirror domenenavnet til organisasjonen, for eksempel \"dn=example,dn=com\" når site url er \"example.com\". Denne verdien er \"root\"-adressen til LDAP-katalogen."
#: conf/ldap.py:96
msgid "User search filter template"
-msgstr ""
+msgstr "Brukers søkefiltermal"
#: conf/ldap.py:99
msgid ""
@@ -1422,55 +1422,55 @@ msgid ""
"should be left in the intact format. First placeholder will be used for the "
"user id field name, and the second - for the user id value. The template can"
" be extended to match schema of your LDAP directory."
-msgstr ""
+msgstr "Python string-format mal, må ha to string placeholders, som bør overlates i intakt form. Første placeholder vil bli brukt som brukeren id-felt-navn, og den andre - for brukerens id-verdi. Malen kan bli utvidet for bli lik skjema på din LDAP-katalog."
#: conf/ldap.py:113
msgid "UserID/login field"
-msgstr ""
+msgstr "Brukerinnlogging"
#: conf/ldap.py:116
msgid ""
"This field is required. For Microsoft Active Directory this value usually is"
" \"sAMAccountName\"."
-msgstr ""
+msgstr "Dette feltet er påkrevet. For Microsoft Active Directory denne verdien er vanligvis \"sAMAccountName\"."
#: conf/ldap.py:127
msgid "\"Common Name\" field"
-msgstr ""
+msgstr "\"Vanlig navn\"-felt"
#: conf/ldap.py:129
msgid ""
"Common name is a formal or informal name of a person, can be blank. Use it "
"only if surname and given names are not available."
-msgstr ""
+msgstr "Vanlig navn er et formellt eller uformellt navn på en person. Det kan være blankt. Bruk det bare hvis fornavn og etternavn ikke er tilgjengelig."
#: conf/ldap.py:139
msgid "First name, Last name"
-msgstr ""
+msgstr "Fornavn, Etternavn"
#: conf/ldap.py:140
msgid "Last name, First name"
-msgstr ""
+msgstr "Etternavn, Fornavn"
#: conf/ldap.py:147
msgid "\"Common Name\" field format"
-msgstr ""
+msgstr "\"Normalt navn\" felt-format"
#: conf/ldap.py:150
msgid "Use this only if \"Common Name\" field is used."
-msgstr ""
+msgstr "Bruk denne bare hvis \"Normalt navn\" feltet er i bruk."
#: conf/ldap.py:158
msgid "Given (First) name"
-msgstr ""
+msgstr "Fornavn"
#: conf/ldap.py:160 conf/ldap.py:170
msgid "This field can be blank"
-msgstr ""
+msgstr "Dette feltet kan være tomt"
#: conf/ldap.py:168
msgid "Surname (last) name"
-msgstr ""
+msgstr "Etternavn"
#: conf/ldap.py:178
msgid "LDAP Server EMAIL field name"
@@ -1478,7 +1478,7 @@ msgstr "LDAP Server EPOST feltnavn"
#: conf/ldap.py:180
msgid "This field is required"
-msgstr ""
+msgstr "Dette feltet er påkrevd"
#: conf/leading_sidebar.py:12
msgid "Common left sidebar"
@@ -1690,7 +1690,7 @@ msgstr "Aksepter eget svar"
#: conf/minimum_reputation.py:58
msgid "Accept any answer"
-msgstr ""
+msgstr "Aksepter hvilket som helst svar"
#: conf/minimum_reputation.py:67
msgid "Flag offensive"
@@ -1710,17 +1710,17 @@ msgstr "Last opp filer"
#: conf/minimum_reputation.py:115
msgid "Insert clickable links"
-msgstr ""
+msgstr "Legg til klikkbare lenker"
#: conf/minimum_reputation.py:124
msgid "Insert link suggestions as plain text"
-msgstr ""
+msgstr "Legg til lenkeforslag som klartekst"
#: conf/minimum_reputation.py:126
msgid ""
"This value should be smaller than that for \"insert clickable links\". This "
"setting should stop link-spamming by newly registered users."
-msgstr ""
+msgstr "Denne verdien bør være mindre enn for \"Sett inn klikkbare linker\". Denne innstillingen burde hindre link-spamming fra nyregistrerte brukere."
#: conf/minimum_reputation.py:137
msgid "Close own questions"
@@ -1766,7 +1766,7 @@ msgstr ""
#: conf/minimum_reputation.py:223
msgid "Trigger email notifications"
-msgstr ""
+msgstr "Trigger for epostnotifikasoner"
#: conf/minimum_reputation.py:224 conf/minimum_reputation.py:234
msgid "Reduces spam"
@@ -1778,62 +1778,62 @@ msgstr ""
#: conf/moderation.py:19
msgid "Content moderation"
-msgstr ""
+msgstr "Innholdsmoderasjon"
#: conf/moderation.py:28
msgid "Enable content moderation"
-msgstr ""
+msgstr "Aktiver innholdsmoderasjon"
#: conf/moderation.py:38
msgid "Enable tag moderation"
-msgstr ""
+msgstr "Aktiver merkelappmoderasjon"
#: conf/moderation.py:40
msgid ""
"If enabled, any new tags will not be applied to the questions, but emailed "
"to the moderators. To use this feature, tags must be optional."
-msgstr ""
+msgstr "Hvis aktivert, så vil eventuellt nye koder ikke brukes på spørsmålene, men blir sendt til moderatorene. Hvis du vil bruke denne funksjonen så må kodene være valgfrie."
#: conf/question_lists.py:11
msgid "Listings of questions"
-msgstr ""
+msgstr "Utlisting av spørsmål"
#: conf/question_lists.py:20
msgid "Enable \"All Questions\" selector"
-msgstr ""
+msgstr "Aktiver \"Alle spørsmål\"-velger"
#: conf/question_lists.py:21 conf/question_lists.py:31
#: conf/question_lists.py:41
msgid "At least one of these selectors must be enabled"
-msgstr ""
+msgstr "Minst en av disse selektorene må være aktivert"
#: conf/question_lists.py:30
msgid "Enable \"Unanswered Questions\" selector"
-msgstr ""
+msgstr "Aktiver \"Ubesvarte spørsmål\"-velger"
#: conf/question_lists.py:40
msgid "Enable \"Followed Questions\" selector"
-msgstr ""
+msgstr "Aktiver \"Fulgte spørsmåls\"-velger"
#: conf/question_lists.py:53 conf/question_lists.py:70
msgid "All Questions"
-msgstr ""
+msgstr "Alle Spørsmål"
#: conf/question_lists.py:54 conf/question_lists.py:71
msgid "Unanswered Questions"
-msgstr ""
+msgstr "Ubesvarte spørsmål"
#: conf/question_lists.py:55
msgid "Followed Questions"
-msgstr ""
+msgstr "Fulgte Spørsmål"
#: conf/question_lists.py:64
msgid "Default questions selector for the authenticated users"
-msgstr ""
+msgstr "Standard spørsmålsvelger for autentiserte brukere"
#: conf/question_lists.py:80
msgid "Default questions selector for the anonymous users"
-msgstr ""
+msgstr "Standard spørsmålsvelger for anonyme brukere"
#: conf/reputation_changes.py:13
msgid "Karma loss and gain rules"
@@ -1970,28 +1970,28 @@ msgstr ""
#: conf/sidebar_question.py:11
msgid "Question page banners and sidebar"
-msgstr ""
+msgstr "Spørsmålside banner og sidebox"
#: conf/sidebar_question.py:19
msgid "Top banner"
-msgstr ""
+msgstr "Toppbanner"
#: conf/sidebar_question.py:22
msgid ""
"When using this option, please use the HTML validation service to make sure "
"that your input is valid and works well in all browsers."
-msgstr ""
+msgstr "Når du bruker dette alternativet så kan du bruke HTML valideringstjeneste slik at du sørger for at ditt innlegg er gyldig og fungerer godt i alle nettlesere."
#: conf/sidebar_question.py:42
msgid "Answers banner"
-msgstr ""
+msgstr "Svarbanner"
#: conf/sidebar_question.py:45
msgid ""
"This banner will show above the second answer. When using this option, "
"please use the HTML validation service to make sure that your input is valid"
" and works well in all browsers."
-msgstr ""
+msgstr "Dette banneret vil vises over svar nummer to. Når du bruker dette alternativet så kan du bruke HTML valideringstjeneste slik at du sørger for at ditt innspill er gyldig og fungerer godt i alle nettlesere."
#: conf/sidebar_question.py:70
msgid ""
@@ -1999,7 +1999,7 @@ msgid ""
" using this option (as well as the sidebar footer), please use the HTML "
"validation service to make sure that your input is valid and works well in "
"all browsers."
-msgstr ""
+msgstr "Bruk dette område for å legge til innhold på toppen av sideboksen i HTML format. Når du bruker denne opsjonen (samt for sideboksfooter). bruk HTML valideringstjenesten for å være sikker på at det du legger til er gyldig og fungerer godt i alle nettlesere."
#: conf/sidebar_question.py:92
msgid "Show tag list in sidebar"
@@ -2033,7 +2033,7 @@ msgstr "Bootstrap-modus"
#: conf/site_modes.py:73
msgid "Activate a \"Large site\" mode"
-msgstr ""
+msgstr "Aktiver \"Stor nettside\" modus"
#: conf/site_modes.py:75
msgid ""
@@ -2041,7 +2041,7 @@ msgid ""
"values, more suitable for the larger communities, <strong>WARNING:</strong> "
"your current values for Minimum reputation, Badge Settings and Vote Rules "
"will be changed after you modify this setting."
-msgstr ""
+msgstr "\"Stor nettside\"-modus øker omdømme og visse medaljeterskler, til verdier, mer egnet for de større samfunn, <strong>ADVARSEL:</ strong> dine nåværende verdier for Minimum omdømme, vil medaljeinnstillinger og stemmeregler endres etter at du forandrer denne innstillingen."
#: conf/site_settings.py:14
msgid "URLS, keywords & greetings"
@@ -2101,7 +2101,7 @@ msgstr "Hvis denne forblir tom, et simpelt tilbakemeldingsforum blir brukt i ste
#: conf/skin_general_settings.py:15
msgid "Skin, logos and HTML <head> parts"
-msgstr ""
+msgstr "Mal, logoer og HTML <head> noder"
#: conf/skin_general_settings.py:23
msgid "Q&A site logo"
@@ -2113,87 +2113,87 @@ msgstr "For å endre logo, velg en ny fil og send inn hele dette skjema igjen."
#: conf/skin_general_settings.py:34
msgid "English"
-msgstr ""
+msgstr "Engelsk"
#: conf/skin_general_settings.py:35
msgid "Spanish"
-msgstr ""
+msgstr "Spansk"
#: conf/skin_general_settings.py:36
msgid "Catalan"
-msgstr ""
+msgstr "Catalan"
#: conf/skin_general_settings.py:37
msgid "German"
-msgstr ""
+msgstr "Tysk"
#: conf/skin_general_settings.py:38
msgid "Greek"
-msgstr ""
+msgstr "Gresk"
#: conf/skin_general_settings.py:39
msgid "Finnish"
-msgstr ""
+msgstr "Finsk"
#: conf/skin_general_settings.py:40
msgid "French"
-msgstr ""
+msgstr "Fransk"
#: conf/skin_general_settings.py:41
msgid "Hindi"
-msgstr ""
+msgstr "Hindi"
#: conf/skin_general_settings.py:42
msgid "Hungarian"
-msgstr ""
+msgstr "Ungarsk"
#: conf/skin_general_settings.py:43
msgid "Italian"
-msgstr ""
+msgstr "Italiensk"
#: conf/skin_general_settings.py:44
msgid "Japanese"
-msgstr ""
+msgstr "Japansk"
#: conf/skin_general_settings.py:45
msgid "Korean"
-msgstr ""
+msgstr "Koreansk"
#: conf/skin_general_settings.py:46
msgid "Portuguese"
-msgstr ""
+msgstr "Portogisisk"
#: conf/skin_general_settings.py:47
msgid "Brazilian Portuguese"
-msgstr ""
+msgstr "Brasiliansk Portogisisk"
#: conf/skin_general_settings.py:48
msgid "Romanian"
-msgstr ""
+msgstr "Rumensk"
#: conf/skin_general_settings.py:49
msgid "Russian"
-msgstr ""
+msgstr "Russisk"
#: conf/skin_general_settings.py:50
msgid "Serbian"
-msgstr ""
+msgstr "Seribisk"
#: conf/skin_general_settings.py:51
msgid "Turkish"
-msgstr ""
+msgstr "Tyrkisk"
#: conf/skin_general_settings.py:52
msgid "Vietnamese"
-msgstr ""
+msgstr "Vietnamesisk"
#: conf/skin_general_settings.py:53
msgid "Chinese"
-msgstr ""
+msgstr "Kinesisk"
#: conf/skin_general_settings.py:54
msgid "Chinese (Taiwan)"
-msgstr ""
+msgstr "Kinesisk (Taiwan)"
#: conf/skin_general_settings.py:73
msgid "Show logo"
@@ -2362,15 +2362,15 @@ msgstr "Vil bli satt automatisk og er ikke nødvendig å modifisere manuelt."
#: conf/social_sharing.py:11
msgid "Content sharing"
-msgstr ""
+msgstr "Innholdsdeling"
#: conf/social_sharing.py:20
msgid "Check to enable RSS feeds"
-msgstr ""
+msgstr "Kryss av for å aktivere RSS feeds"
#: conf/social_sharing.py:29
msgid "Hashtag or suffix to sharing messages"
-msgstr ""
+msgstr "Hash-merkelapp og suffix for meldingsdeling"
#: conf/social_sharing.py:38
msgid "Check to enable sharing of questions on Twitter"
@@ -2442,11 +2442,11 @@ msgstr "Brukerinnstillinger"
#: conf/user_settings.py:23
msgid "On-screen greeting shown to the new users"
-msgstr ""
+msgstr "Velkomstmelding som vises til nye brukere"
#: conf/user_settings.py:32
msgid "Allow anonymous users send feedback"
-msgstr ""
+msgstr "Tillat anonyme bruker å sende feedback"
#: conf/user_settings.py:41
msgid "Allow editing user screen name"
@@ -2454,11 +2454,11 @@ msgstr "Tillat endring av brukers visningsnavn"
#: conf/user_settings.py:50
msgid "Auto-fill user name, email, etc on registration"
-msgstr ""
+msgstr "Autoutfyll brukernavn, epost, etc. under registrering"
#: conf/user_settings.py:51
msgid "Implemented only for LDAP logins at this point"
-msgstr ""
+msgstr "Bare implementert for LDAP innlogging så langt"
#: conf/user_settings.py:60
msgid "Allow users change own email addresses"
@@ -2466,7 +2466,7 @@ msgstr "Tillat brukere til å endre egene epostadresser"
#: conf/user_settings.py:69
msgid "Allow email address in user name"
-msgstr ""
+msgstr "Tillat epostadresse som brukernavn"
#: conf/user_settings.py:78
msgid "Allow account recovery by email"
@@ -2646,22 +2646,22 @@ msgstr "relevanse"
#: const/__init__.py:74
msgid "Never"
-msgstr ""
+msgstr "Aldri"
#: const/__init__.py:75
msgid "When new post is published"
-msgstr ""
+msgstr "NÃ¥r nye innlegg blir publisert"
#: const/__init__.py:76
msgid "When post is published or revised"
-msgstr ""
+msgstr "NÃ¥r innlegg publiseres eller endres"
#: const/__init__.py:108
#, python-format
msgid ""
"Note: to reply with a comment, please use <a "
"href=\"mailto:%(addr)s?subject=%(subject)s\">this link</a>"
-msgstr ""
+msgstr "Notat: for å svare med en kommentar, vennligst bruk <a href=\"mailto:%(addr)s?subject=%(subject)s\">denne lenken</a>"
#: const/__init__.py:122 templates/user_inbox/responses_and_flags.html:9
msgid "all"
@@ -2673,7 +2673,7 @@ msgstr "ubesvart"
#: const/__init__.py:124
msgid "followed"
-msgstr ""
+msgstr "fulgt"
#: const/__init__.py:129
msgid "list"
@@ -2765,7 +2765,7 @@ msgstr "epostoppdatering sendt til bruker"
#: const/__init__.py:213
msgid "a post was shared"
-msgstr ""
+msgstr "et innlegg var delt"
#: const/__init__.py:216
msgid "reminder about unanswered questions sent"
@@ -2781,27 +2781,27 @@ msgstr "nevnt i en artikkel"
#: const/__init__.py:225
msgid "created tag description"
-msgstr ""
+msgstr "laget merkelappbeskrivelse"
#: const/__init__.py:229
msgid "updated tag description"
-msgstr ""
+msgstr "oppdaterte merkelappbeskrivelse"
#: const/__init__.py:231
msgid "made a new post"
-msgstr ""
+msgstr "opprettet et nytt innlegg"
#: const/__init__.py:234
msgid "made an edit"
-msgstr ""
+msgstr "gjorde en endring"
#: const/__init__.py:238
msgid "created post reject reason"
-msgstr ""
+msgstr "opprettet en innleggsavvisningsgrunn"
#: const/__init__.py:242
msgid "updated post reject reason"
-msgstr ""
+msgstr "oppdaterte innlegsavvisningsgrunn"
#: const/__init__.py:300
msgid "answered question"
@@ -2829,28 +2829,28 @@ msgstr "merkelapper omgjort"
#: const/__init__.py:311
msgid "[private]"
-msgstr ""
+msgstr "[privat]"
#: const/__init__.py:320
msgid "show all tags"
-msgstr ""
+msgstr "vis alle merkelapper"
#: const/__init__.py:321 const/__init__.py:330 const/__init__.py:336
#: const/__init__.py:342
msgid "exclude ignored tags"
-msgstr ""
+msgstr "ekskluder ignorerte merkelapper"
#: const/__init__.py:322 const/__init__.py:331 const/__init__.py:343
msgid "only interesting tags"
-msgstr ""
+msgstr "bare interresante merkelapper"
#: const/__init__.py:326 const/__init__.py:337 const/__init__.py:344
msgid "only subscribed tags"
-msgstr ""
+msgstr "bare abonnerte merkelapper"
#: const/__init__.py:329 const/__init__.py:335 const/__init__.py:341
msgid "email for all tags"
-msgstr ""
+msgstr "epost for alle merkelapper"
#: const/__init__.py:348
msgid "instantly"
@@ -2914,35 +2914,35 @@ msgstr "Opplastet Avatar"
#: const/__init__.py:429
msgid "date descendant"
-msgstr ""
+msgstr "dato stigende"
#: const/__init__.py:430
msgid "date ascendant"
-msgstr ""
+msgstr "dato fallende"
#: const/__init__.py:431
msgid "activity descendant"
-msgstr ""
+msgstr "aktivitet stigende"
#: const/__init__.py:432
msgid "activity ascendant"
-msgstr ""
+msgstr "aktivitet fallende"
#: const/__init__.py:433
msgid "answers descendant"
-msgstr ""
+msgstr "svar stigende"
#: const/__init__.py:434
msgid "answers ascendant"
-msgstr ""
+msgstr "svar fallende"
#: const/__init__.py:435
msgid "votes descendant"
-msgstr ""
+msgstr "stemmer stigende"
#: const/__init__.py:436
msgid "votes ascendant"
-msgstr ""
+msgstr "stemmer fallende"
#: const/message_keys.py:21
msgid "most relevant questions"
@@ -3014,7 +3014,7 @@ msgstr "ignorert"
#: const/message_keys.py:38 models/tag.py:313
msgid "subscribed"
-msgstr ""
+msgstr "abonnert"
#: const/message_keys.py:39 templates/question_retag.html:58
msgid "tags are required"
@@ -3022,7 +3022,7 @@ msgstr "merkelapper må fylles ut"
#: const/message_keys.py:41
msgid "please use letters, numbers and characters \"-+.#\""
-msgstr ""
+msgstr "vennligst bruk bokstaver, tall eller tegnene \"-+.#\""
#: const/message_keys.py:47
msgid ""
@@ -3103,7 +3103,7 @@ msgstr "signin/"
#: deps/django_authopenid/urls.py:15
msgid "widget/signin/"
-msgstr ""
+msgstr "widget/signin/"
#: deps/django_authopenid/urls.py:18
msgid "signout/"
@@ -3131,7 +3131,7 @@ msgstr "recover/"
#: deps/django_authopenid/urls.py:45
msgid "verify-email/"
-msgstr ""
+msgstr "verify-email/"
#: deps/django_authopenid/util.py:379
#, python-format
@@ -3157,7 +3157,7 @@ msgstr "AOL brukernavn"
#: deps/django_authopenid/util.py:502
msgid "Sign in with LaunchPad"
-msgstr ""
+msgstr "Logg inn med LaunchPad"
#: deps/django_authopenid/util.py:509
msgid "OpenID url"
@@ -3312,7 +3312,7 @@ msgstr "Sjekk din epost å følg den vedlagte lenken."
#: deps/group_messaging/models.py:356
msgid "Re: "
-msgstr ""
+msgstr "Re:"
#: deps/livesettings/models.py:107 deps/livesettings/models.py:153
msgid "Site"
@@ -3350,33 +3350,33 @@ msgstr "Gratulerer. Du er nå en Administrator"
#: mail/__init__.py:183
msgid "<p>To ask by email, please:</p>"
-msgstr ""
+msgstr "<p>For å spørre via epost:</p>"
#: mail/__init__.py:185
msgid "<li>Type title in the subject line</li>"
-msgstr ""
+msgstr "<li>Typetittel i emnelinjen</li>"
#: mail/__init__.py:188
msgid "<li>Type details of your question into the email body</li>"
-msgstr ""
+msgstr "<li>Typedetaljer for spørsmål i epostinnhold</li>"
#: mail/__init__.py:191
msgid ""
"<li>The beginning of the subject line can contain tags,\n"
"<em>enclosed in the square brackets</em> like so: [Tag1; Tag2]</li>"
-msgstr ""
+msgstr "<li>Begynnelsen av emnelinjer kan inneholde merkelpper,\n<em>omkretset av firkantparanteser</em> slik: [Merkelapp1; Merkelapp2]</li>"
#: mail/__init__.py:195
msgid ""
"<li>In the beginning of the subject add at least one tag\n"
"<em>enclosed in the brackets</em> like so: [Tag1; Tag2].</li>"
-msgstr ""
+msgstr "<li>I begynnelsen av emnet, legg til minst en merkelapp\n<em>omkranset av firkantparantes</em> slik: [Merkelapp1; Merkelapp2].</li>"
#: mail/__init__.py:199
msgid ""
"<p>Note that a tag may consist of more than one word, to separate\n"
"the tags, use a semicolon or a comma, for example, [One tag; Other tag]</p>"
-msgstr ""
+msgstr "<p>Legg merke til at merkelapp kan bestå av mer enn et ord. For å separere \nmerkelappene, bruk semikolon eller comma, som for eksempel, [En merkelapp; Annen merkelapp]</p>"
#: mail/__init__.py:214
#, python-format
diff --git a/askbot/locale/ru/LC_MESSAGES/django.mo b/askbot/locale/ru/LC_MESSAGES/django.mo
index ab73ba75..82b2b137 100644
--- a/askbot/locale/ru/LC_MESSAGES/django.mo
+++ b/askbot/locale/ru/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/ru/LC_MESSAGES/django.po b/askbot/locale/ru/LC_MESSAGES/django.po
index dc0eff25..97464485 100644
--- a/askbot/locale/ru/LC_MESSAGES/django.po
+++ b/askbot/locale/ru/LC_MESSAGES/django.po
@@ -3866,7 +3866,7 @@ msgstr "%(reputation)s кармы %(username)s "
#, python-format
msgid "one gold badge"
msgid_plural "%(count)d gold badges"
-msgstr[0] "<span class=\"hidden\">%(count)d</span>Ð·Ð¾Ð»Ð¾Ñ‚Ð°Ñ Ð¼ÐµÐ´Ð°Ð»ÑŒ"
+msgstr[0] "%(count)d Ð·Ð¾Ð»Ð¾Ñ‚Ð°Ñ Ð¼ÐµÐ´Ð°Ð»ÑŒ"
msgstr[1] "%(count)d золотых медалей"
msgstr[2] "%(count)d золотых медалей"
@@ -3874,7 +3874,7 @@ msgstr[2] "%(count)d золотых медалей"
#, python-format
msgid "one silver badge"
msgid_plural "%(count)d silver badges"
-msgstr[0] "<span class=\"hidden\">%(count)d</span>ÑеребрÑÐ½Ð°Ñ Ð¼ÐµÐ´Ð°Ð»ÑŒ"
+msgstr[0] "%(count)d ÑеребрÑÐ½Ð°Ñ Ð¼ÐµÐ´Ð°Ð»ÑŒ"
msgstr[1] "%(count)d ÑеребрÑных медалей"
msgstr[2] "%(count)d ÑеребрÑных медалей"
@@ -3882,7 +3882,7 @@ msgstr[2] "%(count)d ÑеребрÑных медалей"
#, python-format
msgid "one bronze badge"
msgid_plural "%(count)d bronze badges"
-msgstr[0] "<span class=\"hidden\">%(count)d</span>Ð±Ñ€Ð¾Ð½Ð·Ð¾Ð²Ð°Ñ Ð¼ÐµÐ´Ð°Ð»ÑŒ"
+msgstr[0] "%(count)d Ð±Ñ€Ð¾Ð½Ð·Ð¾Ð²Ð°Ñ Ð¼ÐµÐ´Ð°Ð»ÑŒ"
msgstr[1] "%(count)d бронзовых медалей"
msgstr[2] "%(count)d бронзовых медалей"
diff --git a/askbot/locale/vi/LC_MESSAGES/django.mo b/askbot/locale/vi/LC_MESSAGES/django.mo
index 7b848f14..dc54b8ef 100644
--- a/askbot/locale/vi/LC_MESSAGES/django.mo
+++ b/askbot/locale/vi/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/vi/LC_MESSAGES/django.po b/askbot/locale/vi/LC_MESSAGES/django.po
index a552642d..65462f00 100644
--- a/askbot/locale/vi/LC_MESSAGES/django.po
+++ b/askbot/locale/vi/LC_MESSAGES/django.po
@@ -5,13 +5,17 @@
# Translators:
# ppanhh <ppanhh@gmail.com>, 2013
# Cong It <EMAIL@ADDRESS>, 2010
+# linux <linux87s@gmail.com>, 2013
+# Nguyen Long <gialacmail@gmail.com>, 2013
+# ppanhh <ppanhh@gmail.com>, 2013
+# rgv151 <rgv151@gmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:06-0500\n"
-"PO-Revision-Date: 2013-08-17 04:26+0000\n"
-"Last-Translator: ppanhh <ppanhh@gmail.com>\n"
+"PO-Revision-Date: 2013-09-19 03:25+0000\n"
+"Last-Translator: evgeny <evgeny.fadeev@gmail.com>\n"
"Language-Team: Vietnamese (http://www.transifex.com/projects/p/askbot/language/vi/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -47,17 +51,17 @@ msgstr "Khung thông tin vỠquốc gia không được để trống"
#, python-format
msgid "must be > %d word"
msgid_plural "must be > %d words"
-msgstr[0] ""
+msgstr[0] "cần phải dài hơn %d kí tự"
#: forms.py:199
#, python-format
msgid "must be < %d word"
msgid_plural "must be < %d words"
-msgstr[0] ""
+msgstr[0] "cần phải ngắn hơn %d kí tự"
#: forms.py:220
msgid "minor edit (don't send alerts)"
-msgstr ""
+msgstr "chỉnh sữa nhỠ(không gửi thông báo)"
#: forms.py:247 templates/widgets/markdown_help.html:20
#: templates/widgets/markdown_help.html:24
@@ -66,23 +70,23 @@ msgstr "tiêu Ä‘á»"
#: forms.py:249 templates/embed/ask_by_widget.html:170
msgid "Please enter your question"
-msgstr ""
+msgstr "Hãy nhập câu há»i của bạn"
#: forms.py:260
#, python-format
msgid "must have > %d character"
msgid_plural "must have > %d characters"
-msgstr[0] ""
+msgstr[0] "cần phải dài hơn %d kí tự"
#: forms.py:270
#, python-format
msgid "The question is too long, maximum allowed size is %d characters"
-msgstr ""
+msgstr "Câu há»i này quá dài, tối Ä‘a cho phép là %d kí tá»±"
#: forms.py:277
#, python-format
msgid "The question is too long, maximum allowed size is %d bytes"
-msgstr ""
+msgstr "Câu há»i này quá dài, tối Ä‘a cho phép là %d byte"
#: forms.py:309
msgid "content"
@@ -98,7 +102,7 @@ msgstr[0] "mỗi thẻ đánh dấu phải có ít hơn %(max_chars)d ký tự"
msgid ""
"We ran out of space for recording the tags. Please shorten or delete some of"
" them."
-msgstr ""
+msgstr "Chúng ta đã sử dụng hết dung lượng thẻ tối đa, hãy rút ngắn lại hoặc bỠbớt để tiếp tục."
#: forms.py:410 forms.py:1006 models/widgets.py:27
#: templates/widgets/edit_post.html:32 templates/widgets/meta_nav.html:6
@@ -113,7 +117,7 @@ msgid ""
msgid_plural ""
"Tags are short keywords, with no spaces within. Up to %(max_tags)d tags can "
"be used."
-msgstr[0] ""
+msgstr[0] "Thẻ là những từ khoá ngắn, không có khoảng trống. Bạn có thể dùng tối đa %(max_tags)d."
#: forms.py:439
#, python-format
@@ -160,122 +164,122 @@ msgstr "đã theo dõi"
#: forms.py:602 const/__init__.py:377
msgid "suspended"
-msgstr ""
+msgstr "bị đình chỉ"
#: forms.py:603 const/__init__.py:378
msgid "blocked"
-msgstr ""
+msgstr "bị khóa"
#: forms.py:605
msgid "administrator"
-msgstr ""
+msgstr "quản trị viên"
#: forms.py:606 const/__init__.py:374
msgid "moderator"
-msgstr ""
+msgstr "Ä‘iá»u hành viên"
#: forms.py:625
msgid "Change status to"
-msgstr ""
+msgstr "Äổi trạng thái thành"
#: forms.py:652
msgid "which one?"
-msgstr ""
+msgstr "-- chá»n -- "
#: forms.py:673
msgid "Cannot change own status"
-msgstr ""
+msgstr "Bạn không thể thay đổi quyá»n của mình"
#: forms.py:679
msgid "Cannot turn other user to moderator"
-msgstr ""
+msgstr "Bạn không thể nâng quyá»n Ä‘iá»u hành cho ngÆ°á»i khác"
#: forms.py:686
msgid "Cannot change status of another moderator"
-msgstr ""
+msgstr "Không thể thay đổi quyá»n của ngÆ°á»i Ä‘iá»u hành khác"
#: forms.py:692
msgid "Cannot change status to admin"
-msgstr ""
+msgstr "Không thể nâng lên quyá»n quản lý"
#: forms.py:698
#, python-format
msgid ""
"If you wish to change %(username)s's status, please make a meaningful "
"selection."
-msgstr ""
+msgstr "Nếu bạn muốn thay đổi quyá»n của %(username)s, hãy Ä‘Æ°a ra lá»±a chá»n hợp lý."
#: forms.py:708
msgid "Subject line"
-msgstr ""
+msgstr "Tiêu Ä‘á»"
#: forms.py:713
msgid "Message text"
-msgstr ""
+msgstr "Ná»™i dung"
#: forms.py:727
msgid "Your name (optional):"
-msgstr ""
+msgstr "Tên của bạn (Không bắt buộc)"
#: forms.py:728
msgid "Email:"
-msgstr ""
+msgstr "Email:"
#: forms.py:730
msgid "Your message:"
-msgstr ""
+msgstr "Thông điệp:"
#: forms.py:735
msgid "I don't want to give my email or receive a response:"
-msgstr ""
+msgstr "Tôi không muốn cung cấp địa chỉ email hoặc nhận thông tin phản hồi:"
#: forms.py:758
msgid "Please mark \"I dont want to give my mail\" field."
-msgstr ""
+msgstr "Hãy đánh dấu mục \"Tôi không muốn cung cấp địa chỉ email\"."
#: forms.py:791
msgid "keep private within your groups"
-msgstr ""
+msgstr "giữ bí mật trong các nhóm của bạn"
#: forms.py:830
msgid "User name:"
-msgstr ""
+msgstr "Tên đăng nhập:"
#: forms.py:832
msgid "Enter name to post on behalf of someone else. Can create new accounts."
-msgstr ""
+msgstr "Hãy Ä‘iá»n tên của ngÆ°á»i bạn muốn đăng há»™, hoặc tạo tài khoản má»›i."
#: forms.py:839
msgid "Email address:"
-msgstr ""
+msgstr "Äịa chỉ email:"
#: forms.py:889
msgid "User name is required with the email"
-msgstr ""
+msgstr "Tên đăng nhập là bắt buộc cùng với email"
#: forms.py:894
msgid "Email is required if user name is added"
-msgstr ""
+msgstr "Bạn phải cung cấp địa chỉ email nếu dùng tên đăng nhập"
#: forms.py:914 forms.py:957
msgid "ask anonymously"
-msgstr ""
+msgstr "há»i nặc danh"
#: forms.py:916 forms.py:959
msgid "Check if you do not want to reveal your name when asking this question"
-msgstr ""
+msgstr "chá»n nếu bạn không muốn tiết lá»™ tên của bạn khi há»i câu há»i này"
#: forms.py:947
msgid ""
"Subject line is expected in the format: [tag1, tag2, tag3,...] question "
"title"
-msgstr ""
+msgstr "Tiêu đỠđược hiểu theo định dạng: [thẻ1, thẻ2, thẻ3,...] câu há»i"
#: forms.py:1213
msgid ""
"You have asked this question anonymously, if you decide to reveal your "
"identity, please check this box."
-msgstr ""
+msgstr "Bạn đã ẩn danh khi há»i câu này, nếu bạn quyết định tiết lá»™ danh tính của bạn, xin vui lòng chá»n vào đây ."
#: forms.py:1217
msgid "reveal identity"
@@ -296,7 +300,7 @@ msgstr ""
#: forms.py:1373
msgid "Real name"
-msgstr ""
+msgstr "Tên thật"
#: forms.py:1380
msgid "Website"
@@ -304,27 +308,27 @@ msgstr ""
#: forms.py:1387
msgid "City"
-msgstr ""
+msgstr "Thành phố"
#: forms.py:1396
msgid "Show country"
-msgstr ""
+msgstr "Hiển thị Quốc gia"
#: forms.py:1401
msgid "Show tag choices"
-msgstr ""
+msgstr "Hiển thị lá»±a chá»n từ khóa"
#: forms.py:1406
msgid "Date of birth"
-msgstr ""
+msgstr "Ngày sinh"
#: forms.py:1408
msgid "will not be shown, used to calculate age, format: YYYY-MM-DD"
-msgstr ""
+msgstr "sẽ không được hiển thị, được dùng để tính tuổi, định dạng : YYYY-MM-DD"
#: forms.py:1416
msgid "Profile"
-msgstr ""
+msgstr "Hồ sơ cá nhân"
#: forms.py:1425
msgid "Screen name"
@@ -332,7 +336,7 @@ msgstr ""
#: forms.py:1457 forms.py:1461
msgid "this email has already been registered, please use another one"
-msgstr ""
+msgstr "email này đã được sử dụng hãy thử lại với email khác"
#: forms.py:1470
msgid "Choose email tag filter"
@@ -340,11 +344,11 @@ msgstr ""
#: forms.py:1522
msgid "Asked by me"
-msgstr ""
+msgstr "Câu há»i của tôi"
#: forms.py:1525
msgid "Answered by me"
-msgstr ""
+msgstr "Câu trả lá»i của tôi"
#: forms.py:1528
msgid "Individually selected"
@@ -352,15 +356,15 @@ msgstr ""
#: forms.py:1531
msgid "Entire forum (tag filtered)"
-msgstr ""
+msgstr "Toàn bá»™ diá»…n đàn (đã lá»c theo từ khóa)"
#: forms.py:1535
msgid "Comments and posts mentioning me"
-msgstr ""
+msgstr "à kiến ​​và bài ​​viết đỠcập đến tôi"
#: forms.py:1619
msgid "please choose one of the options above"
-msgstr ""
+msgstr "xin vui lòng chá»n má»™t trong các tùy chá»n ở trên"
#: forms.py:1622
msgid "okay, let's try!"
@@ -373,51 +377,51 @@ msgstr ""
#: forms.py:1673 templates/reopen.html:7
msgid "Title"
-msgstr ""
+msgstr "tiêu Ä‘á»"
#: forms.py:1676 templates/groups.html:32
msgid "Description"
-msgstr ""
+msgstr "Mô tả"
#: forms.py:1695 templates/tags.html:3 templates/tags/header.html:9
#: templates/tags/list_bulk_tag_subscription.html:12
#: templates/widgets/edit_post.html:26 templates/widgets/related_tags.html:3
#: templates/widgets/tag_category_selector.html:2
msgid "Tags"
-msgstr ""
+msgstr "Thẻ đánh dấu"
#: tasks.py:98
msgid "An edit for my answer"
-msgstr ""
+msgstr "chỉnh sá»­a câu trả lá»i của tôi"
#: tasks.py:101
msgid "To add to your post EDIT ABOVE THIS LINE"
-msgstr ""
+msgstr "Äể thêm vào bài viết của bạn SỬA DÃ’NG TRÊN"
#: tasks.py:119
#, python-format
msgid "Your post at %(site_name)s is now published"
-msgstr ""
+msgstr "Bài viết của bạn đã được đăng ở mục %(site_name)s"
#: urls.py:44
msgid "questions"
-msgstr ""
+msgstr "câu há»i"
#: urls.py:56
msgid "question/"
-msgstr ""
+msgstr "câu há»i/"
#: urls.py:61
msgid "tags/"
-msgstr ""
+msgstr "thẻ đánh dấu/"
#: urls.py:66 urls.py:71 urls.py:78 urls.py:84 urls.py:93 urls.py:100
msgid "users/"
-msgstr ""
+msgstr "ngÆ°á»i dùng/"
#: urls.py:71
msgid "by-group/"
-msgstr ""
+msgstr "bởi nhóm/"
#: urls.py:78 urls.py:159 urls.py:226 urls.py:520
msgid "edit/"
@@ -556,23 +560,23 @@ msgstr ""
#: conf/access_control.py:17
msgid "Allow only registered user to access the forum"
-msgstr ""
+msgstr "Chỉ cho phép ngÆ°á»i dùng đã đăng ký được vào diá»…n đàn"
#: conf/access_control.py:22
msgid "nothing - not required"
-msgstr ""
+msgstr "không có gì - không bắt buộc"
#: conf/access_control.py:23
msgid "access to content"
-msgstr ""
+msgstr "truy cập nội dung"
#: conf/access_control.py:34
msgid "Require valid email for"
-msgstr ""
+msgstr "yêu cầu email hợp lệ cho"
#: conf/access_control.py:44
msgid "Allowed email addresses"
-msgstr ""
+msgstr "Äịa chỉ email cho phép"
#: conf/access_control.py:45
msgid "Please use space to separate the entries"
@@ -580,7 +584,7 @@ msgstr ""
#: conf/access_control.py:54
msgid "Allowed email domain names"
-msgstr ""
+msgstr "Äịa chỉ tên miá»n email cho phép"
#: conf/access_control.py:55
msgid "Please use space to separate the entries, do not use the @ symbol!"
@@ -588,7 +592,7 @@ msgstr ""
#: conf/badges.py:13
msgid "Badge settings"
-msgstr ""
+msgstr "Thiết lập huy hiệu"
#: conf/badges.py:23
msgid "Disciplined: minimum upvotes for deleted post"
@@ -628,15 +632,15 @@ msgstr ""
#: conf/badges.py:104
msgid "Popular Question: minimum views"
-msgstr ""
+msgstr "Câu há»i phổ biến: lượt xem tối thiểu"
#: conf/badges.py:113
msgid "Notable Question: minimum views"
-msgstr ""
+msgstr "Câu há»i đáng chú ý:lượt xem tối thiểu"
#: conf/badges.py:122
msgid "Famous Question: minimum views"
-msgstr ""
+msgstr "Câu há»i nổi tiếng: lượt xem tối thiểu"
#: conf/badges.py:131
msgid "Self-Learner: minimum answer upvotes"
@@ -664,7 +668,7 @@ msgstr ""
#: conf/badges.py:185
msgid "Associate Editor: minimum number of edits"
-msgstr ""
+msgstr "Phó biên tập: số lượng chỉ sửa tối thiểu"
#: conf/badges.py:194
msgid "Favorite Question: minimum stars"
@@ -688,11 +692,11 @@ msgstr ""
#: conf/email.py:15
msgid "Email and email alert settings"
-msgstr ""
+msgstr "Email và thiết lập email cảnh báo"
#: conf/email.py:24
msgid "Prefix for the email subject line"
-msgstr ""
+msgstr "Tiá»n tố cho dòng chủ Ä‘á» email"
#: conf/email.py:26
msgid ""
@@ -702,70 +706,70 @@ msgstr ""
#: conf/email.py:44
msgid "Site administrator email address"
-msgstr ""
+msgstr "Äịa chỉ email của ngÆ°á»i quản trị trang web"
#: conf/email.py:53
msgid "Enable email alerts"
-msgstr ""
+msgstr "Bật thông báo bằng email"
#: conf/email.py:62
msgid "Maximum number of news entries in an email alert"
-msgstr ""
+msgstr "Số lượng tối đa các mục tin tức trong một thông báo qua email"
#: conf/email.py:72
msgid "Default notification frequency all questions"
-msgstr ""
+msgstr "Mặc định tần số thông báo tất cả các câu há»i"
#: conf/email.py:74
msgid "Option to define frequency of emailed updates for: all questions."
-msgstr ""
+msgstr "Tùy chá»n để xác định tần số cập nhật được gá»­i qua email cho: tất cả các câu há»i."
#: conf/email.py:86
msgid "Default notification frequency questions asked by the user"
-msgstr ""
+msgstr "Mặc định tần số thông báo câu há»i của ngÆ°á»i sá»­ dụng"
#: conf/email.py:88
msgid ""
"Option to define frequency of emailed updates for: Question asked by the "
"user."
-msgstr ""
+msgstr "Tùy chá»n để xác định tần số cập nhật được gá»­i qua email cho: Câu há»i yêu cầu bởi ngÆ°á»i dùng."
#: conf/email.py:100
msgid "Default notification frequency questions answered by the user"
-msgstr ""
+msgstr "Tần số thông báo mặc định cho câu há»i đã trả lá»i bởi ngÆ°á»i dùng"
#: conf/email.py:102
msgid ""
"Option to define frequency of emailed updates for: Question answered by the "
"user."
-msgstr ""
+msgstr "Tùy chá»n để xác định tần số cập nhật được gá»­i qua email cho: Câu há»i đã trả lá»i bởi ngÆ°á»i dùng."
#: conf/email.py:114
msgid ""
"Default notification frequency questions individually"
" selected by the user"
-msgstr ""
+msgstr "Tần số thông báo mặc định câu há»i lá»±a chá»n cá nhân của ngÆ°á»i dùng"
#: conf/email.py:117
msgid ""
"Option to define frequency of emailed updates for: Question individually "
"selected by the user."
-msgstr ""
+msgstr "Tùy chá»n để xác định tần số cập nhật được gá»­i qua email cho: Câu há»i lá»±a chá»n cá nhân của ngÆ°á»i dùng."
#: conf/email.py:129
msgid ""
"Default notification frequency for mentions and "
"comments"
-msgstr ""
+msgstr "Tần số thông báo mặc định cho đỠcập và bình luận"
#: conf/email.py:132
msgid ""
"Option to define frequency of emailed updates for: Mentions and comments."
-msgstr ""
+msgstr "Tùy chá»n để xác định tần số cập nhật được gá»­i qua email cho: Äá» cập và bình luận."
#: conf/email.py:143
msgid "Send periodic reminders about unanswered questions"
-msgstr ""
+msgstr "Gá»­i lá»i nhắc nhở định kỳ vá» các câu há»i chÆ°a được trả lá»i"
#: conf/email.py:145
msgid ""
@@ -776,7 +780,7 @@ msgstr ""
#: conf/email.py:158
msgid "Days before starting to send reminders about unanswered questions"
-msgstr ""
+msgstr "Ngày trÆ°á»›c khi bắt đầu gá»­i lá»i nhắc nhở vá» những câu há»i chÆ°a được trả lá»i"
#: conf/email.py:169
msgid ""
@@ -786,11 +790,11 @@ msgstr ""
#: conf/email.py:181
msgid "Max. number of reminders to send about unanswered questions"
-msgstr ""
+msgstr "Số lượng tối Ä‘a của lá»i nhắc để gá»­i vá» các câu há»i chÆ°a được trả lá»i"
#: conf/email.py:192
msgid "Send periodic reminders to accept the best answer"
-msgstr ""
+msgstr "Gá»­i lá»i nhắc nhở định kỳ để chấp nhận câu trả lá»i tốt nhất"
#: conf/email.py:194
msgid ""
@@ -801,7 +805,7 @@ msgstr ""
#: conf/email.py:207
msgid "Days before starting to send reminders to accept an answer"
-msgstr ""
+msgstr "Ngày trÆ°á»›c khi bắt đầu gá»­i lá»i nhắc nhở để chấp nhận má»™t câu trả lá»i"
#: conf/email.py:218
msgid ""
@@ -811,11 +815,11 @@ msgstr ""
#: conf/email.py:230
msgid "Max. number of reminders to send to accept the best answer"
-msgstr ""
+msgstr "Số lượng tối Ä‘a của lá»i nhắc để gá»­i chấp nhận câu trả lá»i tốt nhất"
#: conf/email.py:242
msgid "Require email verification before allowing to post"
-msgstr ""
+msgstr "Yêu cầu xác minh email trước khi cho phép gửi"
#: conf/email.py:243
msgid ""
@@ -824,7 +828,7 @@ msgstr ""
#: conf/email.py:252
msgid "Fake email for anonymous user"
-msgstr ""
+msgstr "Email giả mạo cho ngÆ°á»i dùng vô danh"
#: conf/email.py:253
msgid "Use this setting to control gravatar for email-less user"
@@ -832,7 +836,7 @@ msgstr ""
#: conf/email.py:262
msgid "Allow posting questions by email"
-msgstr ""
+msgstr "Cho phép gá»­i câu há»i qua email"
#: conf/email.py:264
msgid ""
@@ -842,21 +846,21 @@ msgstr ""
#: conf/email.py:275
msgid "Replace space in emailed tags with dash"
-msgstr ""
+msgstr "Thay thế khoảng trống trong thẻ email bằng dấu gạch ngang"
#: conf/email.py:277
msgid ""
"This setting applies to tags written in the subject line of questions asked "
"by email"
-msgstr ""
+msgstr "Thiết lập này áp dụng đối vá»›i thẻ ghi trong dòng chủ Ä‘á» của câu há»i qua email"
#: conf/email.py:288
msgid "Enable posting answers and comments by email"
-msgstr ""
+msgstr "Cho phép gá»­i câu trả lá»i và ý kiến ​​qua email"
#: conf/email.py:291
msgid "To enable this feature make sure lamson is running"
-msgstr ""
+msgstr "Äể kích hoạt tính năng này hãy chắc chắn lamson Ä‘ang chạy"
#: conf/email.py:302
msgid "Emailed post: when to notify author about publishing"
@@ -874,11 +878,11 @@ msgstr ""
#: conf/external_keys.py:11
msgid "Keys for external services"
-msgstr ""
+msgstr "Các chìa khóa cho các dịch vụ bên ngoài"
#: conf/external_keys.py:19
msgid "Google site verification key"
-msgstr ""
+msgstr "Chìa khóa xác minh Google site"
#: conf/external_keys.py:21
#, python-format
@@ -889,7 +893,7 @@ msgstr ""
#: conf/external_keys.py:36
msgid "Google Analytics key"
-msgstr ""
+msgstr "Chìa khóa Google Analytics "
#: conf/external_keys.py:38
#, python-format
@@ -900,7 +904,7 @@ msgstr ""
#: conf/external_keys.py:51
msgid "Enable recaptcha (keys below are required)"
-msgstr ""
+msgstr "Bật recaptcha (khóa bên dưới là bắt buộc)"
#: conf/external_keys.py:62
msgid "Recaptcha public key"
@@ -943,7 +947,7 @@ msgstr ""
msgid ""
"Please register your forum at <a href=\"%(url)s\">twitter applications "
"site</a>"
-msgstr ""
+msgstr "Xin vui lòng đăng ký diễn đàn của bạn tại <a href=\"%(url)s\"> ứng dụng trang web twitter</ a>"
#: conf/external_keys.py:120
msgid "Twitter consumer secret"
@@ -958,7 +962,7 @@ msgstr ""
msgid ""
"Please register your forum at <a href=\"%(url)s\">LinkedIn developer "
"site</a>"
-msgstr ""
+msgstr "Xin vui lòng đăng ký diễn đàn của bạn tại <a href=\"%(url)s\">trang developer LinkedIn </ a>"
#: conf/external_keys.py:141
msgid "LinkedIn consumer secret"
@@ -973,7 +977,7 @@ msgstr ""
msgid ""
"Please register your forum at <a href=\"%(url)s\">Identi.ca applications "
"site</a>"
-msgstr ""
+msgstr "Xin vui lòng đăng ký diễn đàn của bạn tại <a href=\"%(url)s\">Identi.ca applications site</a>"
#: conf/external_keys.py:162
msgid "ident.ca consumer secret"
@@ -981,7 +985,7 @@ msgstr ""
#: conf/flatpages.py:11
msgid "Messages and pages - about, privacy policy, etc."
-msgstr ""
+msgstr "Tin nhắn và các trang - vỠchính sách bảo mật, vv"
#: conf/flatpages.py:19
msgid "Text of the Q&A forum About page (html format)"
@@ -1005,7 +1009,7 @@ msgstr ""
#: conf/flatpages.py:45
msgid "Instructions on how to ask questions"
-msgstr ""
+msgstr "HÆ°á»›ng dẫn vá» cách đặt câu há»i"
#: conf/flatpages.py:48
msgid ""
@@ -1025,19 +1029,19 @@ msgstr ""
#: conf/flatpages.py:75
msgid "Do not edit this field manually!!!"
-msgstr ""
+msgstr "Không chỉnh sá»­a trÆ°á»ng này bằng tay!"
#: conf/forum_data_rules.py:12
msgid "Data entry and display rules"
-msgstr ""
+msgstr "Nhập dữ liệu và các quy tắc hiển thị"
#: conf/forum_data_rules.py:27
msgid "Editor for the posts"
-msgstr ""
+msgstr "Biên tập viên cho các bài viết"
#: conf/forum_data_rules.py:42
msgid "Editor for the comments"
-msgstr ""
+msgstr "Biên tập viên cho ý kiến"
#: conf/forum_data_rules.py:51
msgid "Enable big Ask button"
@@ -1047,11 +1051,11 @@ msgstr ""
msgid ""
"Disabling this button will reduce number of new questions. If this button is"
" disabled, the ask button in the search menu will still be available."
-msgstr ""
+msgstr "Vô hiệu hóa nút này sẽ làm giảm số câu há»i má»›i. Nếu nút này bị vô hiệu hóa, các nút ask trong menu tìm kiếm sẽ vẫn có sẵn."
#: conf/forum_data_rules.py:66
msgid "Enable embedding videos. "
-msgstr ""
+msgstr "Cho phép nhúng video."
#: conf/forum_data_rules.py:68
#, python-format
@@ -1060,11 +1064,11 @@ msgstr ""
#: conf/forum_data_rules.py:78
msgid "Check to enable community wiki feature"
-msgstr ""
+msgstr "chá»n để kích hoạt tính năng cá»™ng đồng wiki"
#: conf/forum_data_rules.py:87
msgid "Allow asking questions anonymously"
-msgstr ""
+msgstr "Cho phép đặt câu há»i ẩn danh"
#: conf/forum_data_rules.py:89
msgid ""
@@ -7243,11 +7247,11 @@ msgstr ""
#: templates/widgets/ask_form.html:22 templates/widgets/ask_form.html.py:24
msgid "Add details (optional)"
-msgstr ""
+msgstr "Thêm chi tiết (không bắt buộc)"
#: templates/widgets/ask_form.html:26
msgid "Add details"
-msgstr ""
+msgstr "Thêm chi tiết"
#: templates/widgets/ask_form.html:59
msgid "Select language"
@@ -7390,44 +7394,44 @@ msgstr ""
#: templates/widgets/markdown_help.html:6
msgid "*italic*"
-msgstr ""
+msgstr "*nghiêng*"
#: templates/widgets/markdown_help.html:9
msgid "**bold**"
-msgstr ""
+msgstr "**đậm**"
#: templates/widgets/markdown_help.html:13
msgid "*italic* or _italic_"
-msgstr ""
+msgstr "*nghiêng* hoặc _nghiêng_"
#: templates/widgets/markdown_help.html:16
msgid "**bold** or __bold__"
-msgstr ""
+msgstr "**đậm** hoặc __đậm_"
#: templates/widgets/markdown_help.html:20
#: templates/widgets/markdown_help.html:24
msgid "text"
-msgstr ""
+msgstr "chữ"
#: templates/widgets/markdown_help.html:24
msgid "image"
-msgstr ""
+msgstr "hình"
#: templates/widgets/markdown_help.html:28
msgid "numbered list:"
-msgstr ""
+msgstr "danh sách (số)"
#: templates/widgets/markdown_help.html:33
msgid "basic HTML tags are also supported"
-msgstr ""
+msgstr "các thẻ HTML cơ bản cũng được hỗ trợ"
#: templates/widgets/markdown_help.html:38
msgid "learn more about Markdown"
-msgstr ""
+msgstr "xem thêm vỠMarkdown"
#: templates/widgets/meta_nav.html:12
msgid "people & groups"
-msgstr ""
+msgstr "thành viên & nhóm"
#: templates/widgets/meta_nav.html:20
msgid "users"
@@ -7435,7 +7439,7 @@ msgstr "people"
#: templates/widgets/meta_nav.html:27
msgid "badges"
-msgstr ""
+msgstr "danh hiệu"
#: templates/widgets/question_edit_tips.html:5
msgid "ask a question interesting to this community"
@@ -7444,41 +7448,41 @@ msgstr ""
#: templates/widgets/question_summary.html:12
msgid "view"
msgid_plural "views"
-msgstr[0] ""
+msgstr[0] "xem"
#: templates/widgets/question_summary.html:30
msgid "answer"
msgid_plural "answers"
-msgstr[0] ""
+msgstr[0] "trả lá»i"
#: templates/widgets/question_summary.html:41
msgid "vote"
msgid_plural "votes"
-msgstr[0] ""
+msgstr[0] "đánh giá"
#: templates/widgets/scope_nav.html:17
msgid "ALL"
-msgstr ""
+msgstr "TẤT CẢ"
#: templates/widgets/scope_nav.html:22
msgid "see unanswered questions"
-msgstr ""
+msgstr "xem câu há»i chÆ°a có trả lá»i"
#: templates/widgets/scope_nav.html:22
msgid "UNANSWERED"
-msgstr ""
+msgstr "CHƯA TRẢ LỜI"
#: templates/widgets/scope_nav.html:27
msgid "see your followed questions"
-msgstr ""
+msgstr "xem câu há»i Ä‘ang theo dõi"
#: templates/widgets/scope_nav.html:27
msgid "FOLLOWED"
-msgstr ""
+msgstr "ÄANG THEO DÕI"
#: templates/widgets/scope_nav.html:30
msgid "Please ask your question here"
-msgstr ""
+msgstr "Hãy đặt câu há»i của bạn tại đây"
#: templates/widgets/tag_selector.html:4
msgid "Interesting tags"
@@ -7494,15 +7498,15 @@ msgstr ""
#: templates/widgets/tag_selector.html:59
msgid "Show only questions from"
-msgstr ""
+msgstr "Chỉ hiển thị câu há»i từ"
#: templates/widgets/tag_selector.html:70
msgid "Send me email alerts for"
-msgstr ""
+msgstr "Gửi email thông báo đên tôi khi"
#: templates/widgets/tag_selector.html:86
msgid "Change frequency of emails"
-msgstr ""
+msgstr "Thay đổi tần suất gửi email"
#: templates/widgets/three_column_category_selector.html:4
msgid ""
@@ -7527,15 +7531,15 @@ msgstr ""
#: templates/widgets/user_long_score_and_badge_summary.html:10
msgid "karma:"
-msgstr ""
+msgstr "điểm:"
#: templates/widgets/user_long_score_and_badge_summary.html:15
msgid "badges:"
-msgstr ""
+msgstr "danh hiệu:"
#: templates/widgets/user_navigation.html:17
msgid "sign out"
-msgstr ""
+msgstr "đăng xuất"
#: templates/widgets/user_navigation.html:20
msgid "Hi there! Please sign in"
@@ -7543,7 +7547,7 @@ msgstr ""
#: templates/widgets/user_navigation.html:23
msgid "settings"
-msgstr ""
+msgstr "thiết lập"
#: templates/widgets/user_navigation.html:24
msgid "widgets"
@@ -7552,7 +7556,7 @@ msgstr ""
#: templates/widgets/user_perms.html:1
#, python-format
msgid "Your karma is %(karma)s"
-msgstr ""
+msgstr "Số điểm của bạn là %(karma)s"
#: templates/widgets/user_perms.html:4
msgid "Karma reflects the value of your contribution to this community."
diff --git a/askbot/locale/vi/LC_MESSAGES/djangojs.mo b/askbot/locale/vi/LC_MESSAGES/djangojs.mo
index 8fd001ed..c79bd0a2 100644
--- a/askbot/locale/vi/LC_MESSAGES/djangojs.mo
+++ b/askbot/locale/vi/LC_MESSAGES/djangojs.mo
Binary files differ
diff --git a/askbot/locale/vi/LC_MESSAGES/djangojs.po b/askbot/locale/vi/LC_MESSAGES/djangojs.po
index d9c34724..2028781f 100644
--- a/askbot/locale/vi/LC_MESSAGES/djangojs.po
+++ b/askbot/locale/vi/LC_MESSAGES/djangojs.po
@@ -4,13 +4,16 @@
#
# Translators:
# linux <linux87s@gmail.com>, 2013
+# linux <linux87s@gmail.com>, 2013
+# Nguyen Long <gialacmail@gmail.com>, 2013
+# rgv151 <rgv151@gmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:07-0500\n"
-"PO-Revision-Date: 2013-08-21 02:48+0000\n"
-"Last-Translator: linux <linux87s@gmail.com>\n"
+"PO-Revision-Date: 2013-09-19 03:25+0000\n"
+"Last-Translator: evgeny <evgeny.fadeev@gmail.com>\n"
"Language-Team: Vietnamese (http://www.transifex.com/projects/p/askbot/language/vi/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -21,295 +24,295 @@ msgstr ""
#: media/jquery-openid/jquery.openid.js:73
#, c-format
msgid "Are you sure you want to remove your %s login?"
-msgstr ""
+msgstr "Bạn muốn loại bỠphương thức đăng nhập từ %s?"
#: media/jquery-openid/jquery.openid.js:90
msgid "Please add one or more login methods."
-msgstr ""
+msgstr "Hãy thêm một hoặc vài phương thức đăng nhập khác."
#: media/jquery-openid/jquery.openid.js:93
msgid ""
"You don't have a method to log in right now, please add one or more by "
"clicking any of the icons below."
-msgstr ""
+msgstr "Hiện tại bạn không có phương thức đăng nhập nào, hãy thêm bằng cách nhấn vào biểu tượng bất kì bên dưới."
#: media/jquery-openid/jquery.openid.js:135
msgid "passwords do not match"
-msgstr ""
+msgstr "mật khẩu không khớp"
#: media/jquery-openid/jquery.openid.js:162
msgid "Show/change current login methods"
-msgstr ""
+msgstr "Hiển thị/thay đổi các phương thức đăng nhập đang sử dụng"
#: media/jquery-openid/jquery.openid.js:227
#, c-format
msgid "Please enter your %s, then proceed"
-msgstr ""
+msgstr "Hãy nhâp %s của bạn và tiếp tục"
#: media/jquery-openid/jquery.openid.js:229
msgid "Connect your %(provider_name)s account to %(site)s"
-msgstr ""
+msgstr "Kết nối với tải khoản %(provider_name)s của bạn tới %(site)s"
#: media/jquery-openid/jquery.openid.js:323
#, c-format
msgid "Change your %s password"
-msgstr ""
+msgstr "Äổi mật khẩu %s của bạn"
#: media/jquery-openid/jquery.openid.js:324
msgid "Change password"
-msgstr ""
+msgstr "Äổi mật khẩu"
#: media/jquery-openid/jquery.openid.js:327
#, c-format
msgid "Create a password for %s"
-msgstr ""
+msgstr "Tạo mật khẩu mới cho %s"
#: media/jquery-openid/jquery.openid.js:328
msgid "Create password"
-msgstr ""
+msgstr "Tạo mật khẩu"
#: media/jquery-openid/jquery.openid.js:344
msgid "Create a password-protected account"
-msgstr ""
+msgstr "Tạo tài khoản mới"
#: media/js/group_messaging.js:102 media/js/group_messaging.js.c:293
msgid "required"
-msgstr ""
+msgstr "bắt buộc"
#: media/js/group_messaging.js:139
msgid "Your message:"
-msgstr ""
+msgstr "Thông điệp của bạn:"
#: media/js/group_messaging.js:152
msgid "send"
-msgstr ""
+msgstr "gá»­i"
#: media/js/group_messaging.js:164 media/js/post.js:1809
#: media/js/post.js.c:3081 media/js/post.js.c:4598 media/js/user.js:888
msgid "cancel"
-msgstr ""
+msgstr "hủy"
#: media/js/group_messaging.js:227
msgid "Reply"
-msgstr ""
+msgstr "Trả lá»i"
#: media/js/group_messaging.js:236 media/js/group_messaging.js.c:743
msgid "message sent"
-msgstr ""
+msgstr "đã gửi"
#: media/js/group_messaging.js:271
msgid "user {{str}} does not exist"
msgid_plural "users {{str}} do not exist"
-msgstr[0] ""
+msgstr[0] "thành viên {{str}} không tồn tại"
#: media/js/group_messaging.js:278
msgid "cannot send message to yourself"
-msgstr ""
+msgstr "không thể gửi tin nhắn đến chính bạn"
#: media/js/group_messaging.js:323
msgid "Recipient:"
-msgstr ""
+msgstr "NgÆ°á»i nhận:"
#: media/js/live_search.js:196
msgid "To see search results, 2 or more characters may be required"
-msgstr ""
+msgstr "Äể có kết quả tìm kiếm, vui lòng sá»­ dụng từ khóa dài hÆ¡n"
#: media/js/live_search.js:218
msgid "Ask Your Question"
-msgstr ""
+msgstr "Äặt câu há»i"
#: media/js/live_search.js:299
msgid "Sorry, this tag does not exist"
msgid_plural "Sorry, these tags do not exist"
-msgstr[0] ""
+msgstr[0] "Xin lỗi, những thẻ này không tồn tại"
#: media/js/live_search.js:313
msgid "search or ask your question"
-msgstr ""
+msgstr "tìm hoặc đặt câu há»i"
#: media/js/post.js:28
msgid "loading..."
-msgstr ""
+msgstr "đang tải..."
#: media/js/post.js:100
msgid "must be shorter than %(max_chars)s character"
msgid_plural "must be shorter than %(max_chars)s characters"
-msgstr[0] ""
+msgstr[0] "cần phải ngắn hơn %(max_chars)s kí tự"
#: media/js/post.js:154 media/js/post.js.c:1269
msgid "tags cannot be empty"
-msgstr ""
+msgstr "không thể dùng thẻ rỗng"
#: media/js/post.js:160
msgid "details are required"
-msgstr ""
+msgstr "thông tin chi tiết là bắt buộc"
#: media/js/post.js:163
#, c-format
msgid "details must have > %s character"
msgid_plural "details must have > %s characters"
-msgstr[0] ""
+msgstr[0] " chi tiết cần dài hơn %s kí tự"
#: media/js/post.js:171
msgid "enter your question"
-msgstr ""
+msgstr "nhập câu há»i của bạn"
#: media/js/post.js:174
#, c-format
msgid "question must have > %s character"
msgid_plural "question must have > %s characters"
-msgstr[0] ""
+msgstr[0] "câu há»i cần dài hÆ¡n %s kí tá»±"
#: media/js/post.js:193
msgid "content cannot be empty"
-msgstr ""
+msgstr "nội dung không thể rỗng"
#: media/js/post.js:196
#, c-format
msgid "answer must be > %s character"
msgid_plural "answer must be > %s characters"
-msgstr[0] ""
+msgstr[0] "câu trả lá»i cần phải dài hÆ¡n %s kí tá»±"
#: media/js/post.js:253
msgid "Back to the question"
-msgstr ""
+msgstr "Trở vá» câu há»i"
#: media/js/post.js:303
msgid "draft saved..."
-msgstr ""
+msgstr "đã lưu bản nháp..."
#: media/js/post.js:548
msgid "insufficient privilege"
-msgstr ""
+msgstr "không đủ quyá»n"
#: media/js/post.js:549
msgid "cannot pick own answer as best"
-msgstr ""
+msgstr "bạn không thể đánh giá cho câu trả lá»i của chính mình"
#: media/js/post.js:552 media/js/post.js.c:1416
msgid "please login"
-msgstr ""
+msgstr "vui lòng đăng nhập"
#: media/js/post.js:554
msgid "anonymous users cannot follow questions"
-msgstr ""
+msgstr "hãy đăng nhập để theo dõi câu há»i này"
#: media/js/post.js:555
msgid "anonymous users cannot subscribe to questions"
-msgstr ""
+msgstr "hãy đăng nhập để đăng ký theo dõi câu há»i này"
#: media/js/post.js:556 media/js/post.js.c:1426
msgid "anonymous users cannot vote"
-msgstr ""
+msgstr "hãy đăng nhập để đánh giá"
#: media/js/post.js:558
msgid "please confirm offensive"
-msgstr ""
+msgstr "vui lòng xác nhận thông báo vi phạm"
#: media/js/post.js:559
msgid "please confirm removal of offensive flag"
-msgstr ""
+msgstr "vui long xác nhận gỡ bỠthông báo vi phạm"
#: media/js/post.js:560
msgid "anonymous users cannot flag offensive posts"
-msgstr ""
+msgstr "ngÆ°á»i dùng nặc danh không thể thông báo vi phạm"
#: media/js/post.js:561
msgid "confirm delete"
-msgstr ""
+msgstr "xác nhận xóa"
#: media/js/post.js:562
msgid "anonymous users cannot delete/undelete"
-msgstr ""
+msgstr "ngÆ°á»i sá»­ dụng ẩn danh không thể xóa/phục hồi"
#: media/js/post.js:563
msgid "post recovered"
-msgstr ""
+msgstr "bài viết đã được khôi phục"
#: media/js/post.js:564
msgid "post deleted"
-msgstr ""
+msgstr "đã xóa bài viết"
#: media/js/post.js:831
msgid "Follow"
-msgstr ""
+msgstr "Theo sau"
#: media/js/post.js:840 media/js/post.js.c:849
#, c-format
msgid "%s follower"
msgid_plural "%s followers"
-msgstr[0] ""
+msgstr[0] "%s ngÆ°á»i theo"
#: media/js/post.js:845
msgid "<div>Following</div><div class=\"unfollow\">Unfollow</div>"
-msgstr ""
+msgstr "<div>Äang theo</div><div class=\"unfollow\">Ngừng theo</div>"
#: media/js/post.js:901
msgid "remove flag"
-msgstr ""
+msgstr "loại bá» cá»"
#: media/js/post.js:935 media/js/post.js.c:964
msgid "flag offensive"
-msgstr ""
+msgstr "thông báo vi phạm"
#: media/js/post.js:990 media/js/post.js.c:1497
msgid "undelete"
-msgstr ""
+msgstr "Khôi phục"
#: media/js/post.js:995 media/js/post.js.c:1501
msgid "delete"
-msgstr ""
+msgstr "xóa"
#: media/js/post.js:1218 media/js/post.js.c:1445
msgid "sorry, something is not right here"
-msgstr ""
+msgstr "xin lỗi, một cái gì đó không đúng ở đây"
#: media/js/post.js:1665
msgid "add comment"
-msgstr ""
+msgstr "Thêm ý kiến"
#: media/js/post.js:1671
msgid "save comment"
-msgstr ""
+msgstr "lưu ý kiến"
#: media/js/post.js:1711
#, c-format
msgid "enter at least %s characters"
-msgstr ""
+msgstr "nhập ít nhất %s ký tự"
#: media/js/post.js:1713
#, c-format
msgid "enter at least %s more characters"
-msgstr ""
+msgstr "nhập thêm ít nhất %s kí tự nữa"
#: media/js/post.js:1723
#, c-format
msgid "%s characters left"
-msgstr ""
+msgstr "còn lại %s ký tự"
#: media/js/post.js:1823
msgid "minor edit (don't send alerts)"
-msgstr ""
+msgstr "sửa đổi nhỠ(không gửi thông báo)"
#: media/js/post.js:1855
msgid "Are you sure you don't want to post this comment?"
-msgstr ""
+msgstr "Bạn có chắc là bạn không muốn gửi bình luận này?"
#: media/js/post.js:1890 media/js/utils.js:3360 media/js/utils.js.c:3515
msgid "just now"
-msgstr ""
+msgstr "chỉ bây giá»"
#: media/js/post.js:1956
msgid "delete this comment"
-msgstr ""
+msgstr "xóa ý kiến này"
#: media/js/post.js:2271
msgid "confirm delete comment"
-msgstr ""
+msgstr "xác nhận xóa ye kiến này"
#: media/js/post.js:2409
msgid "please sign in or register to post comments"
-msgstr ""
+msgstr "vui lòng đăng nhập hoặc đăng ký để gửi ý kiến"
#: media/js/post.js:2560
msgid "Please enter question title (>10 characters)"
@@ -317,82 +320,82 @@ msgstr "Làm Æ¡n nhập tiêu Ä‘á» của câu há»i (>10 ký tá»±)"
#: media/js/post.js:2612 media/js/post.js.c:4626
msgid "Sorry, you have only read access"
-msgstr ""
+msgstr "Xin lá»—i, bạn chỉ có quyá»n xem bài"
#: media/js/post.js:3075 media/js/post.js.c:3869 media/js/post.js.c:4058
msgid "save"
-msgstr ""
+msgstr "LÆ°u"
#: media/js/post.js:3199
msgid "Enter the logo url or upload an image"
-msgstr ""
+msgstr "Nhập địa chỉ logo hoặc tải lên một hình ảnh"
#: media/js/post.js:3225
msgid "Do you really want to remove the image?"
-msgstr ""
+msgstr "Bạn có thực sự muốn xóa hình này?"
#: media/js/post.js:3341
msgid "change logo"
-msgstr ""
+msgstr "đổi logo"
#: media/js/post.js:3342
msgid "add logo"
-msgstr ""
+msgstr "thêm logo"
#: media/js/post.js:3444
#, c-format
msgid "tag \"%s\" was already added, no need to repeat (press \"escape\" to delete)"
-msgstr ""
+msgstr "thẻ \"%s\" đã có, không cần phải thêm vào (nhấn phím \"escape\" để xóa)"
#: media/js/post.js:3453
#, c-format
msgid "a maximum of %s tag is allowed"
msgid_plural "a maximum of %s tags are allowed"
-msgstr[0] ""
+msgstr[0] "tối đa %s thẻ có thể sử dụng"
#: media/js/post.js:3799
msgid "Delete category?"
-msgstr ""
+msgstr "Xóa danh mục?"
#: media/js/post.js:3888 media/js/utils.js:881
msgid "edit"
-msgstr ""
+msgstr "sá»­a"
#: media/js/post.js:3975
msgid "category name cannot be empty"
-msgstr ""
+msgstr "tên danh mục không thể để trống"
#: media/js/post.js:4011
msgid "already exists at the current level!"
-msgstr ""
+msgstr "đã tồn tại ở cấp độ hiện tại!"
#: media/js/post.js:4047
msgid "add category"
-msgstr ""
+msgstr "thêm thể loại"
#: media/js/post.js:4594
msgid "save tags"
-msgstr ""
+msgstr "lưu thẻ đánh dấu"
#: media/js/post.js:4689 media/js/post.js.c:4723
msgid "User name:"
-msgstr ""
+msgstr "Tên đăng nhập:"
#: media/js/post.js:4710
msgid "Group name:"
-msgstr ""
+msgstr "Tên nhóm:"
#: media/js/post.js:4736
msgid "Shared with the following users:"
-msgstr ""
+msgstr "Chia sẻ vá»›i ngÆ°á»i dùng sau đây:"
#: media/js/post.js:4742
msgid "Shared with the following groups:"
-msgstr ""
+msgstr "Chia sẻ với các nhóm sau:"
#: media/js/tag_selector.js:14
msgid "Tag \"<span></span>\" matches:"
-msgstr ""
+msgstr "Thẻ đánh dấu \"<span></span>\" phù hợp:"
#: media/js/tag_selector.js:84
#, c-format
@@ -401,381 +404,381 @@ msgstr "và %s nhiá»u hÆ¡n, không được hiển thị..."
#: media/js/user.js:15
msgid "Please select at least one item"
-msgstr ""
+msgstr "Vui lòng chá»n ít nhất má»™t mục"
#: media/js/user.js:59
msgid "Delete this notification?"
msgid_plural "Delete these notifications?"
-msgstr[0] ""
+msgstr[0] "Xóa các thông báo này?"
#: media/js/user.js:66
msgid "Close this entry?"
msgid_plural "Close these entries?"
-msgstr[0] ""
+msgstr[0] "Äóng các mục?"
#: media/js/user.js:74
msgid "Remove all flags and approve this entry?"
msgid_plural "Remove all flags and approve these entries?"
-msgstr[0] ""
+msgstr[0] "Loại bỠtất cả các cỠvà phê duyệt những mục này?"
#: media/js/user.js:223
msgid "Post deleted"
-msgstr ""
+msgstr "đã xóa bài viết"
#: media/js/user.js:225
msgid "Post approved"
-msgstr ""
+msgstr "đã chấp thuận"
#: media/js/user.js:246
msgid "Accept"
-msgstr ""
+msgstr "Chấp nhận"
#: media/js/user.js:255
msgid "Reject"
-msgstr ""
+msgstr "Từ chối"
#: media/js/user.js:270
msgid "add new reject reason"
-msgstr ""
+msgstr "thêm lý do từ chối"
#: media/js/user.js:375
msgid "Looks there are some things to fix:"
-msgstr ""
+msgstr "Có vẻ có má»™t số Ä‘iá»u phải sá»­a chữa:"
#: media/js/user.js:443
msgid "Please provide description."
-msgstr ""
+msgstr "Vui lòng cung cấp mô tả."
#: media/js/user.js:446
msgid "Please provide details."
-msgstr ""
+msgstr "Vui lòng cung cấp chi tiết."
#: media/js/user.js:560
msgid "A reason must be selected to delete one."
-msgstr ""
+msgstr "Phải chá»n má»™t lý do để xóa 1."
#: media/js/user.js:659
msgid "A reason must be selected to reject post."
-msgstr ""
+msgstr "Phải chá»n má»™t lý do để từ chối bài viết"
#: media/js/user.js:708
msgid "Please <a href=\"%(signin_url)s\">signin</a> to follow %(username)s"
-msgstr ""
+msgstr "Hãy <a href=\"%(signin_url)s\">tạo tài khoản</a> để theo dõi %(username)s"
#: media/js/user.js:740
#, c-format
msgid "unfollow %s"
-msgstr ""
+msgstr "ngừng theo dõi %s"
#: media/js/user.js:743
#, c-format
msgid "following %s"
-msgstr ""
+msgstr "đang theo dõi %s"
#: media/js/user.js:749
#, c-format
msgid "follow %s"
-msgstr ""
+msgstr "theo dõi %s"
#: media/js/user.js:883
msgid "add group"
-msgstr ""
+msgstr "thêm nhóm"
#: media/js/user.js:963
msgid "add"
-msgstr ""
+msgstr "thêm"
#: media/js/utils.js:99
msgid "and"
-msgstr ""
+msgstr "và"
#: media/js/utils.js:117
msgid "click to close"
-msgstr ""
+msgstr "đóng"
#: media/js/utils.js:880
msgid "click to edit this comment"
-msgstr ""
+msgstr "sửa ý kiến này"
#: media/js/utils.js:905
msgid "convert to answer"
-msgstr ""
+msgstr "chuyển thành câu trả lá»i"
#: media/js/utils.js:958
msgid "Ok"
-msgstr ""
+msgstr "Äồng ý"
#: media/js/utils.js:959 media/js/utils.js.c:1407
msgid "Cancel"
-msgstr ""
+msgstr "hủy"
#: media/js/utils.js:1219
#, c-format
msgid "Uploaded file: %s"
-msgstr ""
+msgstr "Äã tải lên tập tin: %s"
#: media/js/utils.js:1234
msgid "Choose a different image"
-msgstr ""
+msgstr "Chá»n má»™t hình ảnh khác "
#: media/js/utils.js:1236
msgid "Choose a different file"
-msgstr ""
+msgstr "Chá»n má»™t tập tin khác"
#: media/js/utils.js:1250
msgid "Oops, looks like we had an error. Sorry."
-msgstr ""
+msgstr "Rất tiếc, có vẻ như chúng tôi đã có một lỗi. Xin lôi."
#: media/js/utils.js:1311
msgid "Choose an image to insert"
-msgstr ""
+msgstr "Chá»n hình để chèn vào"
#: media/js/utils.js:1313
msgid "Choose a file to insert"
-msgstr ""
+msgstr "Chá»n tập tin để chèn vào"
#: media/js/utils.js:1326
msgid "Allowed file types are:"
-msgstr ""
+msgstr "Các loại tập tin cho phép là:"
#: media/js/utils.js:1332
#: media/js/tinymce/plugins/askbot_attachment/editor_plugin.js:35
msgid "Or paste file url here"
-msgstr ""
+msgstr "Hoặc dán url tập tin ở đây"
#: media/js/utils.js:1406
msgid "Save"
-msgstr ""
+msgstr "LÆ°u"
#: media/js/utils.js:1478
msgid "saved"
-msgstr ""
+msgstr "Äã lÆ°u"
#: media/js/utils.js:1602
msgid "enabled"
-msgstr ""
+msgstr "đã bật"
#: media/js/utils.js:1604
msgid "disabled"
-msgstr ""
+msgstr "bị vô hiệu hóa"
#: media/js/utils.js:2038
msgid "group name"
-msgstr ""
+msgstr "tên nhóm"
#: media/js/utils.js:2046
msgid "add new group"
-msgstr ""
+msgstr "thêm nhóm mới"
#: media/js/utils.js:2138
msgid "Group %(name)s already exists. Group names are case-insensitive."
-msgstr ""
+msgstr "Nhóm %(name)s đã tồn tại. Tên nhóm có phân biệt dạng chữ"
#: media/js/utils.js:2311
#, c-format
msgid "see questions tagged '%s'"
-msgstr ""
+msgstr "xem các câu há»i được gắn thẻ '%s'"
#: media/js/utils.js:3358
msgid "ago"
-msgstr ""
+msgstr "trÆ°á»›c"
#: media/js/utils.js:3359
msgid "from now"
-msgstr ""
+msgstr "từ bây giá»"
#: media/js/utils.js:3361
msgid "about a minute"
-msgstr ""
+msgstr "khoảng một phút"
#: media/js/utils.js:3362
#, c-format
msgid "%d minutes"
-msgstr ""
+msgstr "%d phút"
#: media/js/utils.js:3363
msgid "about an hour"
-msgstr ""
+msgstr "Khoảng 1 giá»"
#: media/js/utils.js:3364
#, c-format
msgid "%d hours"
-msgstr ""
+msgstr "%d giá»"
#: media/js/utils.js:3365 media/js/utils.js.c:3493
msgid "yesterday"
-msgstr ""
+msgstr "ngày hôm qua"
#: media/js/utils.js:3366
#, c-format
msgid "%d days"
-msgstr ""
+msgstr "%d ngày"
#: media/js/utils.js:3367
msgid "about a month"
-msgstr ""
+msgstr "khoảng một tháng"
#: media/js/utils.js:3368
#, c-format
msgid "%d months"
-msgstr ""
+msgstr "%d tháng"
#: media/js/utils.js:3369
msgid "about a year"
-msgstr ""
+msgstr "khoảng một năm"
#: media/js/utils.js:3370
#, c-format
msgid "%d years"
-msgstr ""
+msgstr "%d năm"
#: media/js/utils.js:3468
msgid "Jan"
-msgstr ""
+msgstr "tháng giêng"
#: media/js/utils.js:3469
msgid "Feb"
-msgstr ""
+msgstr "tháng 2"
#: media/js/utils.js:3470
msgid "Mar"
-msgstr ""
+msgstr "tháng 3"
#: media/js/utils.js:3471
msgid "Apr"
-msgstr ""
+msgstr "tháng 4"
#: media/js/utils.js:3472
msgid "May"
-msgstr ""
+msgstr "tháng 5"
#: media/js/utils.js:3473
msgid "Jun"
-msgstr ""
+msgstr "tháng 6"
#: media/js/utils.js:3474
msgid "Jul"
-msgstr ""
+msgstr "tháng 7"
#: media/js/utils.js:3475
msgid "Aug"
-msgstr ""
+msgstr "tháng 8"
#: media/js/utils.js:3476
msgid "Sep"
-msgstr ""
+msgstr "tháng 9"
#: media/js/utils.js:3477
msgid "Oct"
-msgstr ""
+msgstr "tháng 10"
#: media/js/utils.js:3478
msgid "Nov"
-msgstr ""
+msgstr "tháng 11"
#: media/js/utils.js:3479
msgid "Dec"
-msgstr ""
+msgstr "tháng 12"
#: media/js/utils.js:3491
msgid "2 days ago"
-msgstr ""
+msgstr "2 ngày trước"
#: media/js/utils.js:3498
#, c-format
msgid "%s hour ago"
msgid_plural "%s hours ago"
-msgstr[0] ""
+msgstr[0] "%s giá» trÆ°á»›c"
#: media/js/utils.js:3508
#, c-format
msgid "%s min ago"
msgid_plural "%s mins ago"
-msgstr[0] ""
+msgstr[0] "%s phút trước"
#: media/js/tinymce/plugins/askbot_attachment/editor_plugin.js:71
msgid "Insert a file"
-msgstr ""
+msgstr "chèn 1 tập tin"
#: media/js/tinymce/plugins/askbot_imageuploader/editor_plugin.js:70
msgid "Insert image"
-msgstr ""
+msgstr "chèn hình"
#: media/js/wmd/wmd.js:31
msgid "bold"
-msgstr ""
+msgstr "đậm"
#: media/js/wmd/wmd.js:32
msgid "italic"
-msgstr ""
+msgstr "nghiêng"
#: media/js/wmd/wmd.js:33
msgid "link"
-msgstr ""
+msgstr "liên hết"
#: media/js/wmd/wmd.js:34
msgid "quote"
-msgstr ""
+msgstr "trích dẫn"
#: media/js/wmd/wmd.js:35
msgid "preformatted text"
-msgstr ""
+msgstr "nội dung đã được định dạng"
#: media/js/wmd/wmd.js:36
msgid "image"
-msgstr ""
+msgstr "hình"
#: media/js/wmd/wmd.js:37
msgid "attachment"
-msgstr ""
+msgstr "đính kèm"
#: media/js/wmd/wmd.js:38
msgid "numbered list"
-msgstr ""
+msgstr "danh sách số"
#: media/js/wmd/wmd.js:39
msgid "bulleted list"
-msgstr ""
+msgstr "danh sách liệt kê"
#: media/js/wmd/wmd.js:40
msgid "heading"
-msgstr ""
+msgstr "tiêu Ä‘á»"
#: media/js/wmd/wmd.js:41
msgid "horizontal bar"
-msgstr ""
+msgstr "thanh ngang"
#: media/js/wmd/wmd.js:42
msgid "undo"
-msgstr ""
+msgstr "lùi lại"
#: media/js/wmd/wmd.js:43 media/js/wmd/wmd.js.c:1169
msgid "redo"
-msgstr ""
+msgstr "làm lại"
#: media/js/wmd/wmd.js:54
msgid "enter image url"
-msgstr ""
+msgstr "nhập url hình"
#: media/js/wmd/wmd.js:55
msgid "enter url"
-msgstr ""
+msgstr "nhập url"
#: media/js/wmd/wmd.js:56
msgid "upload file attachment"
-msgstr ""
+msgstr "tải lên 1 tập tin đính kèm"
#: media/js/wmd/wmd.js:1836
msgid "image description"
-msgstr ""
+msgstr "mô tả hình ảnh"
#: media/js/wmd/wmd.js:1839
msgid "file name"
-msgstr ""
+msgstr "tên tập tin "
#: media/js/wmd/wmd.js:1843
msgid "link text"
-msgstr ""
+msgstr "liên kết văn bản"
#~ msgid "post a comment"
#~ msgstr "save comment"
diff --git a/askbot/locale/zh_CN/LC_MESSAGES/django.mo b/askbot/locale/zh_CN/LC_MESSAGES/django.mo
index 1a4d973b..8d468276 100644
--- a/askbot/locale/zh_CN/LC_MESSAGES/django.mo
+++ b/askbot/locale/zh_CN/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/zh_CN/LC_MESSAGES/django.po b/askbot/locale/zh_CN/LC_MESSAGES/django.po
index 2805dce5..8ed703d0 100644
--- a/askbot/locale/zh_CN/LC_MESSAGES/django.po
+++ b/askbot/locale/zh_CN/LC_MESSAGES/django.po
@@ -16,8 +16,8 @@ msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:06-0500\n"
-"PO-Revision-Date: 2013-08-16 03:20+0000\n"
-"Last-Translator: ianwu <ian.wu@163.com>\n"
+"PO-Revision-Date: 2013-08-27 23:19+0000\n"
+"Last-Translator: daisy.ycguo <daisy.ycguo@gmail.com>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/askbot/language/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -104,7 +104,7 @@ msgstr[0] "标签最多åªèƒ½æœ‰%(max_chars)d个字符"
msgid ""
"We ran out of space for recording the tags. Please shorten or delete some of"
" them."
-msgstr ""
+msgstr "å·²ç»æ²¡æœ‰ç©ºé—´å­˜å‚¨æ ‡è®°ã€‚请缩短或者删除部分标记。"
#: forms.py:410 forms.py:1006 models/widgets.py:27
#: templates/widgets/edit_post.html:32 templates/widgets/meta_nav.html:6
@@ -150,7 +150,7 @@ msgstr "更新概è¦ï¼š"
msgid ""
"enter a brief summary of your revision (e.g. fixed spelling, grammar, "
"improved style, this field is optional)"
-msgstr "输入本次修改的简å•æ¦‚述(如:修改了别字,修正了语法,改进了样å¼ç­‰ã€‚éžå¿…填项。)"
+msgstr "输入本次修改的简å•æ¦‚è¿°(如:修改了错别字,修正了语法,改进了样å¼ç­‰ã€‚éžå¿…填项。)"
#: forms.py:585
msgid "Enter number of points to add or subtract"
@@ -241,7 +241,7 @@ msgstr "请标记“我ä¸æƒ³ç»™å‡ºé‚®ç®±åœ°å€â€å­—段。"
#: forms.py:791
msgid "keep private within your groups"
-msgstr ""
+msgstr "åªæœ‰ä½ çš„组æˆå‘˜å¯ä»¥è®¿é—®"
#: forms.py:830
msgid "User name:"
@@ -275,7 +275,7 @@ msgstr "若您ä¸æƒ³åœ¨æ问此问题时公布自己的å字,请选中本项
msgid ""
"Subject line is expected in the format: [tag1, tag2, tag3,...] question "
"title"
-msgstr ""
+msgstr "标题行è¦æ»¡è¶³å¦‚下格å¼ï¼š[tag1, tag2, tag2, ...] 问题标题"
#: forms.py:1213
msgid ""
@@ -390,7 +390,7 @@ msgstr "æè¿°"
#: templates/widgets/edit_post.html:26 templates/widgets/related_tags.html:3
#: templates/widgets/tag_category_selector.html:2
msgid "Tags"
-msgstr "个标签"
+msgstr "标签"
#: tasks.py:98
msgid "An edit for my answer"
@@ -598,55 +598,55 @@ msgstr "设置"
#: conf/badges.py:23
msgid "Disciplined: minimum upvotes for deleted post"
-msgstr "å—罚:达到删除帖å­çš„最低åŒæ„票数"
+msgstr "自律:删除帖å­çš„最低赞æˆç¥¨æ•°"
#: conf/badges.py:32
msgid "Peer Pressure: minimum downvotes for deleted post"
-msgstr "用户压力:达到删除帖å­çš„最低å¦å†³ç¥¨æ•°"
+msgstr "他律:删除帖å­çš„最低å对票数"
#: conf/badges.py:41
msgid "Teacher: minimum upvotes for the answer"
-msgstr "è€å¸ˆ:答案的最å°æŽ¨è票数"
+msgstr "è€å¸ˆ:答案的最å°èµžæˆç¥¨æ•°"
#: conf/badges.py:50
msgid "Nice Answer: minimum upvotes for the answer"
-msgstr "好答案:答案的最å°æŽ¨è票数"
+msgstr "好答案:答案的最å°èµžæˆç¥¨æ•°"
#: conf/badges.py:59
msgid "Good Answer: minimum upvotes for the answer"
-msgstr "良好的答案:答案的最å°æŽ¨è票数"
+msgstr "优秀答案:答案的最å°èµžæˆç¥¨æ•°"
#: conf/badges.py:68
msgid "Great Answer: minimum upvotes for the answer"
-msgstr "æžå¥½çš„答案:答案的最å°æŽ¨è票数"
+msgstr "完美答案:答案的最å°èµžæˆç¥¨æ•°"
#: conf/badges.py:77
msgid "Nice Question: minimum upvotes for the question"
-msgstr "好问题:问题的最å°æŽ¨è票数"
+msgstr "好问题:问题的最å°èµžæˆç¥¨æ•°"
#: conf/badges.py:86
msgid "Good Question: minimum upvotes for the question"
-msgstr "良好的问题:问题的最å°æŽ¨è票数"
+msgstr "优秀问题:问题的最å°èµžæˆç¥¨æ•°"
#: conf/badges.py:95
msgid "Great Question: minimum upvotes for the question"
-msgstr "优秀的问题:问题的最å°æŽ¨è票数"
+msgstr "完美问题:问题的最å°èµžæˆç¥¨æ•°"
#: conf/badges.py:104
msgid "Popular Question: minimum views"
-msgstr "å—欢迎问题:最å°æµè§ˆæ¬¡æ•°"
+msgstr "å—欢迎的问题:最å°æµè§ˆæ¬¡æ•°"
#: conf/badges.py:113
msgid "Notable Question: minimum views"
-msgstr "关注的问题:最å°æµè§ˆæ¬¡æ•°"
+msgstr "热门的问题:最å°æµè§ˆæ¬¡æ•°"
#: conf/badges.py:122
msgid "Famous Question: minimum views"
-msgstr "æžå¥½çš„问题:最å°æµè§ˆæ¬¡æ•°"
+msgstr "è‘—å的问题:最å°æµè§ˆæ¬¡æ•°"
#: conf/badges.py:131
msgid "Self-Learner: minimum answer upvotes"
-msgstr "自学者:答案最少推è票数"
+msgstr "自学者:答案最少赞æˆç¥¨æ•°"
#: conf/badges.py:140
msgid "Civic Duty: minimum votes"
@@ -654,35 +654,35 @@ msgstr "居民义务:最少投票数"
#: conf/badges.py:149
msgid "Enlightened Duty: minimum upvotes"
-msgstr "优良义务:最低åŒæ„票数"
+msgstr "å¯å‘责任:最低赞æˆç¥¨æ•°"
#: conf/badges.py:158
msgid "Guru: minimum upvotes"
-msgstr "专家:最少推è票数"
+msgstr "专家:最少赞æˆç¥¨æ•°"
#: conf/badges.py:167
msgid "Necromancer: minimum upvotes"
-msgstr "亡çµï¼šæœ€ä½ŽåŒæ„票数"
+msgstr "å¤å…´çš„问题:最低赞æˆç¥¨æ•°"
#: conf/badges.py:176
msgid "Necromancer: minimum delay in days"
-msgstr "亡çµï¼šæœ€ä½Žå»¶è¿Ÿå¤©æ•°"
+msgstr "å¤å…´çš„问题:最低延迟天数"
#: conf/badges.py:185
msgid "Associate Editor: minimum number of edits"
-msgstr "è”åˆç¼–辑:最å°ç¼–辑数"
+msgstr "主编:最å°ç¼–辑数"
#: conf/badges.py:194
msgid "Favorite Question: minimum stars"
-msgstr "收è—问题:最少星数"
+msgstr "收è—问题:最少关注数"
#: conf/badges.py:203
msgid "Stellar Question: minimum stars"
-msgstr "é‡è¦é—®é¢˜:最少星数"
+msgstr "é‡è¦é—®é¢˜:最少关注数"
#: conf/badges.py:212
msgid "Commentator: minimum comments"
-msgstr "评论家:最低评论数"
+msgstr "评论员:最低评论数"
#: conf/badges.py:221
msgid "Taxonomist: minimum tag use count"
@@ -858,11 +858,11 @@ msgstr "This setting applies to tags written in the subject line of questions as
#: conf/email.py:288
msgid "Enable posting answers and comments by email"
-msgstr ""
+msgstr "å…许通过电å­é‚®ä»¶å‘布答案和评论"
#: conf/email.py:291
msgid "To enable this feature make sure lamson is running"
-msgstr ""
+msgstr "为了å¯ç”¨è¿™é¡¹åŠŸèƒ½ï¼Œè¯·ç¡®ä¿lamson正在è¿è¡Œ"
#: conf/email.py:302
msgid "Emailed post: when to notify author about publishing"
@@ -870,13 +870,13 @@ msgstr ""
#: conf/email.py:327
msgid "Reply by email hostname"
-msgstr ""
+msgstr "通过电å­é‚®ä»¶çš„主机å回å¤ã€‚"
#: conf/email.py:338
msgid ""
"Email replies having fewer words than this number will be posted as comments"
" instead of answers"
-msgstr ""
+msgstr "如果电å­é‚®ä»¶çš„回å¤å­—数少于该数字,将会被å‘布为注释,而ä¸æ˜¯ç­”案。"
#: conf/external_keys.py:11
msgid "Keys for external services"
@@ -1057,12 +1057,12 @@ msgstr ""
#: conf/forum_data_rules.py:66
msgid "Enable embedding videos. "
-msgstr ""
+msgstr "å¯ç”¨è¿å…¥è§†é¢‘"
#: conf/forum_data_rules.py:68
#, python-format
msgid "<em>Note: please read <a href=\"%(url)s\">read this</a> first.</em>"
-msgstr ""
+msgstr "<em>注æ„: 请先阅读 <a href=\"%(url)s\">读这里</a> </em>"
#: conf/forum_data_rules.py:78
msgid "Check to enable community wiki feature"
@@ -1353,7 +1353,7 @@ msgstr ""
#: conf/ldap.py:9
msgid "LDAP login configuration"
-msgstr ""
+msgstr "LDAP登录é…ç½®"
#: conf/ldap.py:17
msgid "Use LDAP authentication for the password login"
@@ -1475,7 +1475,7 @@ msgstr "姓"
#: conf/ldap.py:178
msgid "LDAP Server EMAIL field name"
-msgstr ""
+msgstr "LDAPæœåŠ¡å™¨EMAIL的字段åå­—"
#: conf/ldap.py:180
msgid "This field is required"
@@ -1502,7 +1502,7 @@ msgstr ""
#: conf/license.py:13
msgid "Content License"
-msgstr ""
+msgstr "内容版æƒ"
#: conf/license.py:21
msgid "Show license clause in the site footer"
@@ -1695,15 +1695,15 @@ msgstr "接å—答案"
#: conf/minimum_reputation.py:67
msgid "Flag offensive"
-msgstr "垃圾帖"
+msgstr "标记垃圾帖"
#: conf/minimum_reputation.py:88
msgid "Delete comments posted by others"
-msgstr "删除其他人的留言"
+msgstr "删除其他人的评论"
#: conf/minimum_reputation.py:97
msgid "Delete questions and answers posted by others"
-msgstr "删除任何一个问题或答案,åŠå…¶ä»–管ç†åŠŸèƒ½"
+msgstr "删除其他人的问题或答案"
#: conf/minimum_reputation.py:106
msgid "Upload files"
@@ -1729,23 +1729,23 @@ msgstr "关闭自己的问题"
#: conf/minimum_reputation.py:146
msgid "Retag questions posted by other people"
-msgstr "为其他人å‘布的问题é‡æ–°è®¾ç½®æ ‡ç­¾"
+msgstr "为其他人的问题é‡æ–°è®¾ç½®æ ‡ç­¾"
#: conf/minimum_reputation.py:155
msgid "Reopen own questions"
-msgstr "é‡è®¾é—®é¢˜"
+msgstr "é‡æ–°æ‰“开自己的问题"
#: conf/minimum_reputation.py:164
msgid "Edit community wiki posts"
-msgstr "编辑wiki类问题"
+msgstr "编辑社区维基文章"
#: conf/minimum_reputation.py:173
msgid "Edit posts authored by other people"
-msgstr "编辑其他人的å‘布æƒé™"
+msgstr "编辑其他人的帖å­"
#: conf/minimum_reputation.py:182
msgid "View offensive flags"
-msgstr "查看标记垃圾帖"
+msgstr "查看垃圾帖的标记"
#: conf/minimum_reputation.py:191
msgid "Close questions asked by others"
@@ -1818,7 +1818,7 @@ msgstr ""
#: conf/question_lists.py:53 conf/question_lists.py:70
msgid "All Questions"
-msgstr ""
+msgstr "所有问题"
#: conf/question_lists.py:54 conf/question_lists.py:71
msgid "Unanswered Questions"
@@ -1846,55 +1846,55 @@ msgstr "用户æ¯æ—¥èŽ·å–积分上é™"
#: conf/reputation_changes.py:32
msgid "Gain for receiving an upvote"
-msgstr "标记接收的推è票"
+msgstr "收到赞æˆç¥¨å¯ä»¥èŽ·å¾—积分"
#: conf/reputation_changes.py:41
msgid "Gain for the author of accepted answer"
-msgstr "标记接å—回答的作者"
+msgstr "被接å—答案的作者å¯ä»¥èŽ·å¾—积分"
#: conf/reputation_changes.py:50
msgid "Gain for accepting best answer"
-msgstr "标记最佳答案"
+msgstr "接å—最佳答案å¯ä»¥èŽ·å¾—积分"
#: conf/reputation_changes.py:59
msgid "Gain for post owner on canceled downvote"
-msgstr "标记å‘布者å–消å对票"
+msgstr "被å–消å对票的帖å­ä½œè€…å¯ä»¥èŽ·å¾—积分"
#: conf/reputation_changes.py:68
msgid "Gain for voter on canceling downvote"
-msgstr "标记投票者å–消å对票"
+msgstr "å–消å对票的投票者å¯ä»¥èŽ·å¾—积分"
#: conf/reputation_changes.py:78
msgid "Loss for voter for canceling of answer acceptance"
-msgstr "å‡å°‘投票者积分当å–消回答的接å—æ—¶"
+msgstr "投票者å–消了接å—的回答积分将å‡å°‘"
#: conf/reputation_changes.py:88
msgid "Loss for author whose answer was \"un-accepted\""
-msgstr "å‡å°‘å‘布者积分当回答为ä¸å¯æŽ¥å—æ—¶"
+msgstr "ä¸è¢«æŽ¥å—答案的作者积分å‡å°‘"
#: conf/reputation_changes.py:98
msgid "Loss for giving a downvote"
-msgstr "å‡å°‘å‘布者积分当获得å对票时"
+msgstr "投å对票者积分å‡å°‘"
#: conf/reputation_changes.py:108
msgid "Loss for owner of post that was flagged offensive"
-msgstr "å‡å°‘å‘布者积分当问题被标记为垃圾贴时"
+msgstr "被标记为垃圾贴的作者积分å‡å°‘"
#: conf/reputation_changes.py:118
msgid "Loss for owner of post that was downvoted"
-msgstr "å‡å°‘å‘布者积分当问题被投å对票时"
+msgstr "被投å对票的作者积分å‡å°‘"
#: conf/reputation_changes.py:128
msgid "Loss for owner of post that was flagged 3 times per same revision"
-msgstr "å‡å°‘å‘布者积分当问题被3次åŒæ ·çš„修改标记时"
+msgstr "åŒä¸€ä¸ªå¸–å­è¢«æ ‡è®°3次垃圾贴的作者积分å‡å°‘"
#: conf/reputation_changes.py:138
msgid "Loss for owner of post that was flagged 5 times per same revision"
-msgstr "å‡å°‘å‘布者积分当问题被5次åŒæ ·çš„修改标记时"
+msgstr "åŒä¸€ä¸ªå¸–å­è¢«æ ‡è®°5次垃圾贴的作者积分å‡å°‘"
#: conf/reputation_changes.py:148
msgid "Loss for post owner when upvote is canceled"
-msgstr "å‡å°‘å‘布者积分当推è票å–消时"
+msgstr "帖å­èµžæˆç¥¨è¢«å–消的作者积分å‡å°‘"
#: conf/sidebar_main.py:12
msgid "Main page sidebar"
@@ -2463,7 +2463,7 @@ msgstr ""
#: conf/user_settings.py:60
msgid "Allow users change own email addresses"
-msgstr ""
+msgstr "å…许用户改å˜è‡ªå·±çš„电å­é‚®ä»¶åœ°å€"
#: conf/user_settings.py:69
msgid "Allow email address in user name"
@@ -2483,16 +2483,16 @@ msgstr "用户昵称å…许的最å°é•¿åº¦"
#: conf/user_settings.py:105
msgid "Default avatar for users"
-msgstr ""
+msgstr "用户的缺çœå¤´åƒ"
#: conf/user_settings.py:107
msgid ""
"To change the avatar image, select new file, then submit this whole form."
-msgstr ""
+msgstr "è¦æ”¹å˜å¤´åƒï¼Œè¯·é€‰æ‹©æ–°æ–‡ä»¶ï¼Œç„¶åŽæ交整张表å•ã€‚"
#: conf/user_settings.py:120
msgid "Use automatic avatars from gravatar.com"
-msgstr ""
+msgstr "使用æ¥è‡ªgravatar.com的自动头åƒ"
#: conf/user_settings.py:122
msgid ""
@@ -2501,7 +2501,7 @@ msgid ""
"effective. You will have to enable uploaded avatars as well. For more "
"information, please visit <a href=\"http://askbot.org/doc/optional-"
"modules.html#uploaded-avatars\">this page</a>."
-msgstr ""
+msgstr "如果你想è¦å…许使用gravatar.com中的头åƒï¼Œè¯·é€‰æ‹©è¿™ä¸ªé€‰é¡¹ã€‚请注æ„这个功能å¯èƒ½éœ€è¦å¤§çº¦10分钟æ‰èƒ½å®Œå…¨ç”Ÿæ•ˆã€‚你还需è¦å¯ç”¨ä¸Šä¼ å¤´åƒã€‚想è¦å¾—到更多信æ¯ï¼Œè¯·é˜…读<a href=\"http://askbot.org/doc/optional-modules.html#uploaded-avatars\">这一页</a>."
#: conf/user_settings.py:134
msgid "Default Gravatar icon type"
@@ -2524,11 +2524,11 @@ msgstr "投票与标记é™åˆ¶"
#: conf/vote_rules.py:24
msgid "Number of votes a user can cast per day"
-msgstr "æ¯ç”¨æˆ·æ¯å¤©å…许的投票数"
+msgstr "用户æ¯å¤©å…许的投票数"
#: conf/vote_rules.py:33
msgid "Maximum number of flags per user per day"
-msgstr "æ¯ç”¨æˆ·æ¯å¤©çš„最多标记"
+msgstr "用户æ¯å¤©å…许的标记数"
#: conf/vote_rules.py:42
msgid "Threshold for warning about remaining daily votes"
@@ -2544,17 +2544,17 @@ msgstr "回答自己的æ问之å‰å…许的天数"
#: conf/vote_rules.py:69
msgid "Number of flags required to automatically hide posts"
-msgstr "è¦æ±‚自动éšè—标志数"
+msgstr "帖å­è‡ªåŠ¨éšè—的标志数"
#: conf/vote_rules.py:78
msgid "Number of flags required to automatically delete posts"
-msgstr "è¦æ±‚自动删除的标志数"
+msgstr "帖å­è‡ªåŠ¨åˆ é™¤çš„标志数"
#: conf/vote_rules.py:87
msgid ""
"Minimum days to accept an answer, if it has not been accepted by the "
"question poster"
-msgstr "Minimum days to accept an answer, if it has not been accepted by the question poster"
+msgstr "接å—一个答案的最少天数,如果它没有被问题å‘起者接å—。"
#: const/__init__.py:11
msgid "duplicate question"
@@ -2594,19 +2594,19 @@ msgstr "太地域化"
#: const/__init__.py:29
msgid "disable sharing"
-msgstr ""
+msgstr "撤销共享"
#: const/__init__.py:30
#: templates/user_profile/twitter_sharing_controls.html:13
#: templates/user_profile/twitter_sharing_controls.html:17
msgid "my posts"
-msgstr ""
+msgstr "我的帖å­"
#: const/__init__.py:31
#: templates/user_profile/twitter_sharing_controls.html:14
#: templates/user_profile/twitter_sharing_controls.html:16
msgid "all posts"
-msgstr ""
+msgstr "所有帖å­"
#: const/__init__.py:54 templates/question/answer_tab_bar.html:18
msgid "newest"
@@ -2722,7 +2722,7 @@ msgstr "获了奖牌"
#: const/__init__.py:202
msgid "marked best answer"
-msgstr "标记最佳答案"
+msgstr "作最佳回答"
#: const/__init__.py:203
msgid "upvoted"
@@ -2830,7 +2830,7 @@ msgstr "更新了标签"
#: const/__init__.py:311
msgid "[private]"
-msgstr ""
+msgstr "[ç§æœ‰]"
#: const/__init__.py:320
msgid "show all tags"
@@ -2851,7 +2851,7 @@ msgstr "åªè¦è®¢é˜…标签"
#: const/__init__.py:329 const/__init__.py:335 const/__init__.py:341
msgid "email for all tags"
-msgstr ""
+msgstr "所有标签的邮件"
#: const/__init__.py:348
msgid "instantly"
@@ -2915,35 +2915,35 @@ msgstr "已上传头åƒ"
#: const/__init__.py:429
msgid "date descendant"
-msgstr ""
+msgstr "日期å‡å°‘"
#: const/__init__.py:430
msgid "date ascendant"
-msgstr ""
+msgstr "日期增加"
#: const/__init__.py:431
msgid "activity descendant"
-msgstr ""
+msgstr "活跃人数下é™"
#: const/__init__.py:432
msgid "activity ascendant"
-msgstr ""
+msgstr "活跃人数上å‡"
#: const/__init__.py:433
msgid "answers descendant"
-msgstr ""
+msgstr "回答人数下é™"
#: const/__init__.py:434
msgid "answers ascendant"
-msgstr ""
+msgstr "回答人数上å‡"
#: const/__init__.py:435
msgid "votes descendant"
-msgstr ""
+msgstr "选票下é™"
#: const/__init__.py:436
msgid "votes ascendant"
-msgstr ""
+msgstr "选票上å‡"
#: const/message_keys.py:21
msgid "most relevant questions"
@@ -3011,7 +3011,7 @@ msgstr "感兴趣"
#: const/message_keys.py:37 models/tag.py:312
msgid "ignored"
-msgstr "有趣的"
+msgstr "ä¸æ„Ÿå…´è¶£çš„"
#: const/message_keys.py:38 models/tag.py:313
msgid "subscribed"
@@ -3030,14 +3030,14 @@ msgid ""
"Sorry, your account appears to be blocked and you cannot make new posts "
"until this issue is resolved. Please contact the forum administrator to "
"reach a resolution."
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œä½ çš„å¸æˆ·è¢«å†»ç»“,该问题解决之å‰ï¼Œä½ ä¸èƒ½å‘布新帖å­ã€‚请è”系论å›ç®¡ç†å‘˜å¯»æ±‚解决方案。"
#: const/message_keys.py:52 models/__init__.py:1136
msgid ""
"Sorry, your account appears to be suspended and you cannot make new posts "
"until this issue is resolved. You can, however edit your existing posts. "
"Please contact the forum administrator to reach a resolution."
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œä½ çš„å¸æˆ·è¢«ç¦ç”¨ï¼Œè¯¥é—®é¢˜è§£å†³ä¹‹å‰ï¼Œä½ ä¸èƒ½å‘布新帖å­ã€‚请è”系论å›ç®¡ç†å‘˜å¯»æ±‚解决方案。"
#: deps/django_authopenid/backends.py:99
msgid ""
@@ -3095,7 +3095,7 @@ msgstr "用户å是必需项"
#: deps/django_authopenid/forms.py:455
msgid "sorry, there is no such user name"
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œæ²¡æœ‰è¿™ä¸ªç”¨æˆ·å"
#: deps/django_authopenid/urls.py:14 deps/django_authopenid/urls.py:20
#: deps/django_authopenid/urls.py:23 setup_templates/settings.py:229
@@ -3351,15 +3351,15 @@ msgstr "æ­å–œæ‚¨ï¼Œç¤¾åŒºç»™æ‚¨é¢å‘了奖牌"
#: mail/__init__.py:183
msgid "<p>To ask by email, please:</p>"
-msgstr ""
+msgstr "<p>请使用邮件å‘问:</p>"
#: mail/__init__.py:185
msgid "<li>Type title in the subject line</li>"
-msgstr ""
+msgstr "<li>在主题行写标题</li>"
#: mail/__init__.py:188
msgid "<li>Type details of your question into the email body</li>"
-msgstr ""
+msgstr "<li>问题的详细æ述应该放入邮件正文中去</li>"
#: mail/__init__.py:191
msgid ""
@@ -3377,7 +3377,7 @@ msgstr ""
msgid ""
"<p>Note that a tag may consist of more than one word, to separate\n"
"the tags, use a semicolon or a comma, for example, [One tag; Other tag]</p>"
-msgstr ""
+msgstr "<p>\n注æ„,一个标签包å«ä¸€ä¸ªä»¥ä¸Šçš„字,使用空格æ¥åˆ†éš”标签,例如[标签1 标签2]\n</p>"
#: mail/__init__.py:214
#, python-format
@@ -3460,7 +3460,7 @@ msgstr "对ä¸èµ·ï¼Œä½ åªæœ‰è®¿é—®çš„æƒé™"
#: models/__init__.py:573
msgid "Sorry, this operation is not allowed"
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œè¿™ä¸ªæ“作ä¸å…许"
#: models/__init__.py:623
msgid ""
@@ -3527,15 +3527,15 @@ msgstr "对ä¸èµ·,æš‚åœä½¿ç”¨ç”¨æˆ·ä¸èƒ½ä¸Šä¼ æ–‡ä»¶"
#: models/__init__.py:740
#, python-format
msgid "sorry, file uploading requires karma >%(min_rep)s"
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œä¸Šä¼ æ–‡ä»¶éœ€è¦karma大于%(min_rep)s"
#: models/__init__.py:759
msgid "Could not post, because your karma is insufficient to publish links"
-msgstr ""
+msgstr "无法å‘表,因为你的声望ä¸è¶³ä»¥å‘布链接"
#: models/__init__.py:785
msgid "Sorry, you already gave an answer, please edit it instead."
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œä½ å·²æœ‰ä¸€ä¸ªç­”案,请编辑它。"
#: models/__init__.py:809
#, python-format
@@ -3620,7 +3620,7 @@ msgstr "对ä¸èµ·ï¼Œä½ åªèƒ½åˆ é™¤ä½ è‡ªå·±å‘布的信æ¯å› ä¸ºä½ çš„账户被
msgid ""
"Sorry, to delete other people's posts, a minimum reputation of %(min_rep)s "
"is required"
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œè¦åˆ é™¤åˆ«äººçš„帖å­ï¼Œå£°æœ›è‡³å°‘为%(min_rep)s "
#: models/__init__.py:1040
msgid "Sorry, since your account is blocked you cannot close questions"
@@ -3659,20 +3659,20 @@ msgstr "对ä¸èµ·ï¼Œä½ å¿…须有%(min_rep)s积分æ‰èƒ½é‡å¼€è‡ªå·±å‘布的问é
#: models/__init__.py:1095
msgid "Sorry, you cannot reopen questions because your account is blocked"
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œå› ä¸ºæ‚¨çš„å¸æˆ·è¢«å°é”,所以你ä¸èƒ½é‡æ–°æ‰“开问题"
#: models/__init__.py:1100
msgid "Sorry, you cannot reopen questions because your account is suspended"
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œå› ä¸ºä½ çš„å¸æˆ·è¢«æš‚åœï¼Œæ‰€ä»¥ä½ ä¸èƒ½é‡æ–°æ‰“开问题。"
#: models/__init__.py:1123
msgid "You have flagged this question before and cannot do it more than once"
-msgstr ""
+msgstr "ä½ å·²ç»æ ‡è®°è¿‡è¿™ä¸ªé—®é¢˜ï¼Œä¸èƒ½å†æ¬¡æ ‡è®°"
#: models/__init__.py:1131
msgid ""
"Sorry, since your account is blocked you cannot flag posts as offensive"
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œä½ çš„å¸æˆ·è¢«å†»ç»“,你ä¸å…许标记帖å­ä¸ºæ”»å‡»çš„"
#: models/__init__.py:1142
#, python-format
@@ -3686,7 +3686,7 @@ msgstr ""
msgid ""
"Sorry, you have exhausted the maximum number of %(max_flags_per_day)s "
"offensive flags per day."
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œä½ å·²ç»ç”¨å®Œäº†æ¯å¤©çš„攻击性标记的最大数目%(max_flags_per_day)s "
#: models/__init__.py:1175
msgid "cannot remove non-existing flag"
@@ -3694,20 +3694,20 @@ msgstr "无法移除ä¸å­˜åœ¨çš„标记"
#: models/__init__.py:1181
msgid "Sorry, since your account is blocked you cannot remove flags"
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œä½ çš„å¸æˆ·è¢«å†»ç»“,你ä¸èƒ½åˆ é™¤æ ‡è®°"
#: models/__init__.py:1185
msgid ""
"Sorry, your account appears to be suspended and you cannot remove flags. "
"Please contact the forum administrator to reach a resolution."
-msgstr ""
+msgstr "对ä¸èµ·ï¼Œä½ çš„å¸æˆ·è¢«æš‚åœä½¿ç”¨ï¼Œä½ ä¸èƒ½åˆ é™¤æ ‡è®°ã€‚请è”系论å›ç®¡ç†å‘˜å¯»æ±‚解决方法。"
#: models/__init__.py:1191
#, python-format
msgid "Sorry, to flag posts a minimum reputation of %(min_rep)d is required"
msgid_plural ""
"Sorry, to flag posts a minimum reputation of %(min_rep)d is required"
-msgstr[0] ""
+msgstr[0] "需è¦å¤§äºŽ%(min_rep)d积分值æ‰èƒ½æ ‡è®°ä¿¡æ¯"
#: models/__init__.py:1210
msgid "you don't have the permission to remove all flags"
@@ -3754,7 +3754,7 @@ msgstr "对ä¸èµ·ï¼Œåˆ é™¤ç•™è¨€å¿…须有%(min_rep)s积分值"
#: models/__init__.py:1303
msgid "sorry, but older votes cannot be revoked"
-msgstr ""
+msgstr "这个投票已ç»è¿‡æ—¶ï¼Œä¸èƒ½æ’¤é”€ã€‚"
#: models/__init__.py:1995 utils/functions.py:98
#, python-format
@@ -3863,41 +3863,41 @@ msgstr "%(user)s 有 %(badges)s"
#, python-format
msgid "At least %d karma point is required to post links"
msgid_plural "At least %d karma points is required to post links"
-msgstr[0] ""
+msgstr[0] "必须至少有%d声望值æ‰èƒ½å‘表链接"
#: models/__init__.py:3159
#, python-format
msgid "%(user)s shared a %(post_link)s."
-msgstr ""
+msgstr "%(user)s 共享了 %(post_link)s."
#: models/__init__.py:3162 models/__init__.py:3172
#, python-format
msgid "%(user)s edited a %(post_link)s."
-msgstr ""
+msgstr "%(user)s 修改了 %(post_link)s."
#: models/__init__.py:3164
#, python-format
msgid "%(user)s posted a %(post_link)s"
-msgstr ""
+msgstr "%(user)s å‘表了 %(post_link)s"
#: models/__init__.py:3167
#, python-format
msgid "%(user)s edited an %(post_link)s."
-msgstr ""
+msgstr "%(user)s 修改了 %(post_link)s."
#: models/__init__.py:3169
#, python-format
msgid "%(user)s posted an %(post_link)s."
-msgstr ""
+msgstr "%(user)s å‘表了 %(post_link)s."
#: models/__init__.py:3174
#, python-format
msgid "%(user)s posted a %(post_link)s."
-msgstr ""
+msgstr "%(user)s å‘表了 %(post_link)s."
#: models/__init__.py:3190
msgid "To reply, PLEASE WRITE ABOVE THIS LINE."
-msgstr ""
+msgstr "回å¤ï¼Œè¯·å†™åœ¨è¿™æ¡çº¿ã€‚"
#: models/__init__.py:3232
#, python-format
@@ -3923,25 +3923,25 @@ msgstr "您的标签订阅已ä¿å­˜ï¼Œéžå¸¸æ„Ÿè°¢!"
#: models/badges.py:129
#, python-format
msgid "Deleted own post with %(votes)s or more upvotes"
-msgstr "删除自己å‘布的有%(votes)s或更多推è票的问题"
+msgstr "删除自己一个%(votes)s张赞æˆç¥¨ä»¥ä¸Šçš„帖å­"
#: models/badges.py:133
msgid "Disciplined"
-msgstr "规则"
+msgstr "自律"
#: models/badges.py:151
#, python-format
msgid "Deleted own post with %(votes)s or more downvotes"
-msgstr "删除自己å‘布的%(votes)s或更多å对票的信æ¯"
+msgstr "删除自己一个%(votes)så¼ å对票以上的帖å­"
#: models/badges.py:155
msgid "Peer Pressure"
-msgstr "åŒç­‰åŽ‹åŠ›"
+msgstr "他律"
#: models/badges.py:174
#, python-format
msgid "Received at least %(votes)s upvote for an answer for the first time"
-msgstr "获å–至少有%(votes)s推è票的问题"
+msgstr "第一次回答且获得至少%(votes)s张赞æˆç¥¨"
#: models/badges.py:178
msgid "Teacher"
@@ -3957,7 +3957,7 @@ msgstr "第一个赞æˆç¥¨"
#: models/badges.py:227
msgid "Critic"
-msgstr "评论家"
+msgstr "批评家"
#: models/badges.py:228
msgid "First downvote"
@@ -3975,7 +3975,7 @@ msgstr "已投票%(num)s次"
#: models/badges.py:252
#, python-format
msgid "Answered own question with at least %(num)s up votes"
-msgstr "自己回答的至少有%(num)s次推è票的问题"
+msgstr "回答自己的问题至少有%(num)s次赞æˆç¥¨"
#: models/badges.py:256
msgid "Self-Learner"
@@ -3988,11 +3988,11 @@ msgstr "好回答"
#: models/badges.py:309 models/badges.py:321 models/badges.py:333
#, python-format
msgid "Answer voted up %(num)s times"
-msgstr "该用户投的赞æˆç¥¨å›žç­”总数%(num)s"
+msgstr "赞æˆæ•°ç¥¨ä¸º%(num)s张的回答"
#: models/badges.py:316
msgid "Good Answer"
-msgstr "好回答"
+msgstr "优秀回答"
#: models/badges.py:328
msgid "Great Answer"
@@ -4005,15 +4005,15 @@ msgstr "好问题"
#: models/badges.py:345 models/badges.py:357 models/badges.py:369
#, python-format
msgid "Question voted up %(num)s times"
-msgstr "该用户投的赞æˆç¥¨é—®é¢˜æ€»æ•°%(num)s"
+msgstr "赞æˆæ•°ç¥¨ä¸º%(num)s票的问题"
#: models/badges.py:352
msgid "Good Question"
-msgstr "好问题"
+msgstr "优秀问题"
#: models/badges.py:364
msgid "Great Question"
-msgstr "完美的问题"
+msgstr "完美问题"
#: models/badges.py:376
msgid "Student"
@@ -4021,7 +4021,7 @@ msgstr "学生"
#: models/badges.py:381
msgid "Asked first question with at least one up vote"
-msgstr "得到至少一个赞æˆç¥¨çš„问题"
+msgstr "第一次æ问且至少有一个赞æˆç¥¨"
#: models/badges.py:414
msgid "Popular Question"
@@ -4034,7 +4034,7 @@ msgstr "被查看 %(views)s次的问题"
#: models/badges.py:425
msgid "Notable Question"
-msgstr "关注的问题"
+msgstr "热门的问题"
#: models/badges.py:436
msgid "Famous Question"
@@ -4042,7 +4042,7 @@ msgstr "è‘—å问题"
#: models/badges.py:450
msgid "Asked a question and accepted an answer"
-msgstr "æ问的有正确答案的问题"
+msgstr "问了一个问题且接å—了一个答案"
#: models/badges.py:453
msgid "Scholar"
@@ -4050,12 +4050,12 @@ msgstr "学者"
#: models/badges.py:495
msgid "Enlightened"
-msgstr "文明的"
+msgstr "å¯å‘"
#: models/badges.py:499
#, python-format
msgid "First answer was accepted with %(num)s or more votes"
-msgstr "第一个正确且被投了%(num)s或更多票的答案"
+msgstr "被æ问者接å—且被投了%(num)s或更多票的答案"
#: models/badges.py:507
msgid "Guru"
@@ -4064,42 +4064,42 @@ msgstr "专家"
#: models/badges.py:510
#, python-format
msgid "Answer accepted with %(num)s or more votes"
-msgstr "被接å—的且被投了%(num)s或更多此的回答"
+msgstr "回答被接å—,且被投了%(num)s或更多的赞æˆç¥¨"
#: models/badges.py:518
#, python-format
msgid ""
"Answered a question more than %(days)s days later with at least %(votes)s "
"votes"
-msgstr "问了一个超过%(days)s天且至少有%(votes)s投票的问题"
+msgstr "在一个问题出现%(days)s天åŽæ‰è¢«å›žç­”且票数至少为%(votes)s票"
#: models/badges.py:525
msgid "Necromancer"
-msgstr "亡çµ"
+msgstr "å¤å…´çš„问题"
#: models/badges.py:548
msgid "Citizen Patrol"
-msgstr "社区居民"
+msgstr "市民侦察兵"
#: models/badges.py:551
msgid "First flagged post"
-msgstr "第一次标记"
+msgstr "第一次举报帖å­"
#: models/badges.py:563
msgid "Cleanup"
-msgstr "清除"
+msgstr "清扫工作"
#: models/badges.py:566
msgid "First rollback"
-msgstr "第一次回滚"
+msgstr "第一次回滚æ“作"
#: models/badges.py:577
msgid "Pundit"
-msgstr "学者"
+msgstr "åšå­¦è€…"
#: models/badges.py:580
msgid "Left 10 comments with score of 10 or more"
-msgstr "留言超过10且得分上10的问题"
+msgstr "评论超过10æ¡ä¸”得分上10的问题"
#: models/badges.py:612
msgid "Editor"
@@ -4111,12 +4111,12 @@ msgstr "第一次编辑"
#: models/badges.py:623
msgid "Associate Editor"
-msgstr "è”åˆç¼–辑"
+msgstr "主编"
#: models/badges.py:627
#, python-format
msgid "Edited %(num)s entries"
-msgstr "编辑了%(num)sæ¡ç›®"
+msgstr "编辑了%(num)s个帖å­"
#: models/badges.py:634
msgid "Organizer"
@@ -4128,7 +4128,7 @@ msgstr "第一次修改标签"
#: models/badges.py:644
msgid "Autobiographer"
-msgstr "完善个人资料者"
+msgstr "自传作者"
#: models/badges.py:647
msgid "Completed all user profile fields"
@@ -4137,7 +4137,7 @@ msgstr "完善个人所有资料"
#: models/badges.py:663
#, python-format
msgid "Question favorited by %(num)s users"
-msgstr "被%(num)s用户收è—的问题"
+msgstr "被%(num)s个用户关注的问题"
#: models/badges.py:689
msgid "Stellar Question"
@@ -4149,7 +4149,7 @@ msgstr "收è—问题"
#: models/badges.py:710
msgid "Enthusiast"
-msgstr "热心人"
+msgstr "粉ä¸"
#: models/badges.py:714
#, python-format
@@ -4172,15 +4172,15 @@ msgstr "分类学者"
#: models/badges.py:756
#, python-format
msgid "Created a tag used by %(num)s questions"
-msgstr "创建一个%(num)s个问题都用到的标签"
+msgstr "创建一个标签,且被%(num)s个问题使用过"
#: models/badges.py:774
msgid "Expert"
-msgstr "专家"
+msgstr "达人"
#: models/badges.py:777
msgid "Very active in one tag"
-msgstr "éžå¸¸æ´»è·ƒçš„标签"
+msgstr "在一个标签里éžå¸¸æ´»è·ƒçš„人"
#: models/message.py:16
msgid "message"
@@ -4302,7 +4302,7 @@ msgstr ""
#: models/reply_by_email.py:109
msgid "edited by email"
-msgstr ""
+msgstr "通过电å­é‚®ä»¶ç¼–辑"
#: models/repute.py:207
#, python-format
@@ -4607,7 +4607,7 @@ msgstr "铜牌:时常授予之特殊è£èª‰"
#: templates/base.html:23
#, python-format
msgid "RSS feed from %(site_title)s"
-msgstr ""
+msgstr "èšåˆå†…容æ¥è‡ª %(site_title)s"
#: templates/close.html:3 templates/close.html.py:5
msgid "Close question"
@@ -4653,11 +4653,11 @@ msgstr "应该é¿å…什么样的问题?"
msgid ""
"Please avoid asking questions that are not relevant to this community, too "
"subjective and argumentative."
-msgstr "请é¿å…æ出无关ã€è¿‡äºŽä¸»è§‚性或易造æˆäº‰åµçš„问题。"
+msgstr "请é¿å…å«æœ‰æžç«¯æƒ…绪化ã€æžç«¯ä¸»è§‚的个人判断的问题。å«æœ‰æžç«¯æƒ…绪化的æ问往往ä¸æ˜¯ä¸ºäº†å¯»æ‰¾ç­”案,而是通过æé—®æ¥è¡¨è¾¾ã€å‘泄个人行情绪。å«æœ‰æžç«¯ä¸»è§‚个人判断的问题,问题中的判断å¯èƒ½ä¸Žäº‹å®žä¸ç›¸ç¬¦ã€‚"
#: templates/faq_static.html:13
msgid "What should I avoid in my answers?"
-msgstr "什么样的回答是ä¸å—欢迎的?"
+msgstr "应该é¿å…什么样的回答?"
#: templates/faq_static.html:14
msgid ""
@@ -4665,7 +4665,7 @@ msgid ""
"discussion group</strong>. Please avoid holding debates in your answers as "
"they tend to dilute the essense of questions and answers. For the brief "
"discussions please use commenting facility."
-msgstr "是一个<strong>问答社区</strong>-而ä¸æ˜¯ä¸€ä¸ª<strong>çŒæ°´è®ºå›</strong>。请é¿å…在你的问题和答案中æŒæœ‰è¾©è®ºçš„观点,他们倾å‘于使事情å¤æ‚化。如果你有建议,请使用评论。"
+msgstr "是一个<strong>问答社区</strong>-而ä¸æ˜¯ä¸€ä¸ª<strong>çŒæ°´è®ºå›</strong>。请é¿å…与问题本身无关或没有æ„义的回答。"
#: templates/faq_static.html:15
msgid "Who moderates this community?"
@@ -4729,7 +4729,7 @@ msgstr " 自己的æ问接å—自己的回答"
#: templates/faq_static.html:49
msgid "open and close own questions"
-msgstr "打开关闭任何人的问题"
+msgstr "打开和关闭自己的问题"
#: templates/faq_static.html:53
msgid "retag other's questions"
@@ -4737,7 +4737,7 @@ msgstr "æ•´ç†æ ‡ç­¾"
#: templates/faq_static.html:58
msgid "edit community wiki questions"
-msgstr "编辑wiki类问题"
+msgstr "编辑社区维基里的问题"
#: templates/faq_static.html:63
msgid "edit any answer"
@@ -4796,7 +4796,7 @@ msgid ""
"So questions and answers can be edited like wiki pages by experienced users "
"of this site and this improves the overall quality of the knowledge base "
"content."
-msgstr "所以问题和答案都是如 Wiki 一样å¯ç¼–辑的,我们希望社区能帮助用户沉淀ã€ç§¯ç´¯æ›´å¤šæœ‰ç”¨çš„知识和ç»éªŒã€‚"
+msgstr "所有问题和答案都如维基百科一样å¯å…±åŒç¼–辑的,我们希望社区æˆå‘˜çš„å…±åŒå作å¯ä»¥è®©æ¯ä¸€ä¸ªé—®é¢˜å’Œç­”案å˜å¾—更有价值,就åƒä¸€æ¡æµåŠ¨çš„æ²³æµï¼ŒçŸ¥è¯†åœ¨è¿™é‡Œå¯ä»¥éšæ—¶é—´ä¸æ–­æ›´æ–°ï¼Œå¾—到æŒç»­ä¼˜åŒ–和改进。"
#: templates/faq_static.html:79
msgid "If this approach is not for you, we respect your choice."
@@ -4916,19 +4916,19 @@ msgstr "如何æ问,回答和评论。"
msgid ""
"This site is for asking and answering questions, not for open-ended "
"discussions."
-msgstr "这个网站的目的是为了å‘起和回答问题,而ä¸æ˜¯çŒæ°´ã€‚"
+msgstr "这个网站的目的是为了æ供高质é‡çš„答案,而ä¸æ˜¯çŒæ°´ã€‚"
#: templates/help.html:19
msgid ""
"We encourage everyone to use “question†space for asking and “answer†for "
"answering."
-msgstr "我们鼓励大家“å‘èµ·ä½ ä¸çŸ¥é“,别人知é“的问题;回答你知é“,别人ä¸çŸ¥é“的答案â€ã€‚"
+msgstr "我们鼓励大家“å‘èµ·ä½ ä¸çŸ¥é“,别人知é“的问题;回答你知é“,别人ä¸çŸ¥é“的答案â€ã€‚æ问应éµå¾ªâ€œçœŸå®žã€å®¢è§‚ã€ç®€æ´ã€æ˜Žç¡®ã€è§„范â€çš„原则。回答应éµå¾ªâ€œå°½å¯èƒ½æ供详细的解释和说明â€çš„原则。"
#: templates/help.html:22
msgid ""
"Despite that, each question and answer can be commented – \n"
" the comments are good for the limited discussions."
-msgstr "对问题和答案有什么完善的æ„è§ï¼Œè¯·ä½¿ç”¨è¯„论。"
+msgstr "如果你对问题本身或别人的答案有自己的看法,你å¯ä»¥é€šè¿‡ã€Œè¯„论ã€æ¥è¿›è¡Œï¼Œä¸è¦æŠŠè¯„论当作答案æ¥å‘布。那样的è¯ï¼Œè¯¥é—®é¢˜ä¼šè¢«å…¶ä»–用户点击「å对票ã€è€Œæ‰£é™¤ä½œè€…的声望值,å而起ä¸åˆ°å®žé™…效果,也无助于æ供高质é‡çš„答案。"
#: templates/help.html:26
msgid "Please search before asking your questions"
@@ -4938,7 +4938,7 @@ msgstr "在你æ问之å‰ï¼Œè¯·å…ˆæœç´¢ä¸€ä¸‹ã€‚"
msgid ""
"Type your question in the search bar and see whether a similar question has "
"been asked before"
-msgstr "在æœç´¢æ ä¸­è¾“入您的问题,看是å¦æœ‰ç±»ä¼¼çš„问题已ç»é—®è¿‡äº†ã€‚"
+msgstr "在æœç´¢æ¡†ä¸­è¾“入您的问题,看是å¦æœ‰ç±»ä¼¼çš„问题已ç»é—®è¿‡ã€‚"
#: templates/help.html:29
msgid "Search has advanced capabilities:"
@@ -5000,7 +5000,7 @@ msgstr "其它æ示"
msgid ""
"You can @mention users anywhere in the text to point their attention,\n"
" follow users and conversations and report inappropriate content by flagging it."
-msgstr "ä½ å¯ä»¥ä¿®æ”¹ä»–人的问题和答案,åªåœ¨ä½ ç›¸ä¿¡è‡ªå·±çš„修改能够帮助改进这个问题时æ‰è¿›è¡Œä¿®æ”¹ã€‚(当然,在你的积分达到æŸä¸ªç¨‹åº¦æ—¶æ‰èƒ½ä¿®æ”¹ï¼‰"
+msgstr "虽然å…许你修改他人æ出的问题,但当你在修改他人æ出的问题时,ä»ç„¶åº”该慎é‡ã€‚有些问题有明显的错误或ä¸å¦¥ï¼Œä½ å¯ä»¥å¤§èƒ†åœ°æ”¹è¿›å®ƒä»¬ï¼›ä½†æœ‰äº›é—®é¢˜ç»†å¾®çš„文字修改就会带æ¥é—®é¢˜æœ¬èº«çš„差别,这时候更应该慎é‡ã€‚无论何时,åªåœ¨ä½ ç›¸ä¿¡è‡ªå·±çš„修改能够帮助改进这个问题时æ‰è¿›è¡Œä¿®æ”¹ã€‚请ä¸è¦æ¶æ„修改问题。如果出现æ¶æ„ç ´å行为,社区系统会记录æ“作者的身份,我们会酌情予以警告或åœæ­¢å¸å·ç­‰å¤„ç†ã€‚"
#: templates/help.html:56
msgid "Enjoy."
@@ -5128,20 +5128,20 @@ msgstr ""
#: templates/macros.html:263 templates/macros.html.py:268
#: templates/macros.html:278
msgid "You are a member"
-msgstr ""
+msgstr "您是会员"
#: templates/macros.html:270
msgid "Cancel application"
-msgstr ""
+msgstr "å–消应用"
#: templates/macros.html:271 templates/macros.html.py:280
msgid "Waiting approval"
-msgstr ""
+msgstr "等待审核"
#: templates/macros.html:273 templates/macros.html.py:274
#: templates/macros.html:285
msgid "Ask to join"
-msgstr ""
+msgstr "请加入"
#: templates/macros.html:314
#, python-format
@@ -5164,7 +5164,7 @@ msgstr "编辑"
#: templates/macros.html:452
msgid "convert to answer"
-msgstr ""
+msgstr "转为答案"
#: templates/macros.html:579
#, python-format
@@ -5306,7 +5306,7 @@ msgstr "最多5个标签,æ¯ä¸ªæ ‡ç­¾é•¿åº¦å°äºŽ20个字符。"
#: templates/reopen.html:4 templates/reopen.html.py:6
msgid "Reopen question"
-msgstr "é‡è®¾é—®é¢˜"
+msgstr "é‡æ–°æ‰“开问题"
#: templates/reopen.html:12
#, python-format
@@ -5544,7 +5544,7 @@ msgid ""
"If you believe that this message was sent in mistake - \n"
"no further action is needed. Just ignore this email, we apologize\n"
"for any inconvenience"
-msgstr ""
+msgstr "如果你认为此消æ¯è¢«é”™è¯¯çš„å‘é€,ä¸è¦è¿›è¡Œæ›´è¿›ä¸€æ­¥çš„动作.仅仅忽略这å°é‚®ä»¶,为给您带æ¥çš„ä¸ä¾¿é“æ­‰."
#: templates/authopenid/email_validation.txt:1
msgid "Greetings from the Q&A forum"
@@ -5789,7 +5789,7 @@ msgstr ""
#: templates/authopenid/widget_signin.html:94
msgid "or enter your <span>user name and password</span>, then sign in"
-msgstr ""
+msgstr "或者输入你的<span>用户å和密ç </span>, 然åŽç™»é™†"
#: templates/avatar/add.html:3
msgid "add avatar"
@@ -5934,7 +5934,7 @@ msgstr ""
#: templates/email/macros.html:19
#, python-format
msgid "Question by %(author)s:"
-msgstr ""
+msgstr "%(author)s å‘起问题:"
#: templates/email/macros.html:21
#, python-format
@@ -5942,7 +5942,7 @@ msgid ""
"\n"
" In reply to %(author)s's question:\n"
" "
-msgstr ""
+msgstr "\n在回答%(author)s的问题:"
#: templates/email/macros.html:26
msgid "Question :"
@@ -5984,7 +5984,7 @@ msgid ""
"\n"
" %(author)s's comment:\n"
" "
-msgstr ""
+msgstr "\n%(author)s的评论:"
#: templates/email/macros.html:68
#, python-format
@@ -6000,7 +6000,7 @@ msgid ""
"\n"
" Commented by %(author)s:\n"
" "
-msgstr ""
+msgstr "\n%(author)s的评论:"
#: templates/email/notify_author_about_approved_post.html:21
msgid "Below is a copy of your post:"
@@ -6066,7 +6066,7 @@ msgstr ""
msgid ""
"\n"
"<p>The system was unable to process your message successfully, the reason being:<p>\n"
-msgstr ""
+msgstr "\n<p>系统ä¸èƒ½æ­£ç¡®å¤„ç†ä½ çš„ä¿¡æ¯ï¼ŒåŽŸå› å¦‚下:<p>\n"
#: templates/email/welcome_lamson_off.html:6
#: templates/email/welcome_lamson_off.html:7
@@ -6155,7 +6155,7 @@ msgstr ""
#: templates/group_messaging/macros.html:5
#, python-format
msgid "You wrote on %(date)s:"
-msgstr ""
+msgstr "你写于%(date)s:"
#: templates/group_messaging/senders_list.html:3
msgid "Messages by sender:"
@@ -6398,7 +6398,7 @@ msgstr "检举该帖为垃“水帖â€ï¼ˆå«å¹¿å‘Šã€äººèº«æ”»å‡»ã€æ¶æ„言论
#: templates/question/question_controls.html:18
#: templates/question/question_controls.html:25
msgid "flag offensive"
-msgstr "垃圾帖?"
+msgstr "垃圾帖"
#: templates/question/answer_controls.html:33
#: templates/question/question_controls.html:36
@@ -6520,7 +6520,7 @@ msgid ""
"<strong>use comments for discussions</strong> and <strong>please don't "
"forget to vote :)</strong> for the answers that you liked (or perhaps did "
"not like)!"
-msgstr "<span class='big strong'>欢迎你æ¥å›žç­”自己的问题</span>,但请务必给一个<strong>答案</strong>。记ä½ï¼Œä½ å¯ä»¥éšæ—¶<strong>修改你原æ¥çš„问题</strong>。请使用评论功能æ¥è®¨è®ºé—®é¢˜ï¼Œè¯·ä¸è¦å¿˜è®°ç»™â€œæ‰€æœ‰çš„答案â€<strong>投票</strong>(赞或踩)"
+msgstr "<span class='big strong'>欢迎你æ¥å›žç­”自己的问题</span>,但请务必给一个<strong>答案</strong>。记ä½ï¼Œä½ å¯ä»¥éšæ—¶<strong>修改你原æ¥çš„问题</strong>。请使用评论功能æ¥è®¨è®ºé—®é¢˜ï¼Œè¯·ä¸è¦å¿˜è®°ç»™â€œæ‰€æœ‰çš„答案â€<strong>投票:)</strong>(赞或踩)!"
#: templates/question/new_answer_form.html:34
msgid ""
@@ -6724,7 +6724,7 @@ msgstr ""
#: templates/user_inbox/base.html:14
msgid "Sections:"
-msgstr "段"
+msgstr "部分:"
#: templates/user_inbox/base.html:19
msgid "messages"
@@ -6738,7 +6738,7 @@ msgstr "论å›å›žåº” (%(re_count)s)"
#: templates/user_inbox/base.html:31
#, python-format
msgid "flagged items (%(flags_count)s)"
-msgstr ""
+msgstr "已标记的标签 (%(flags_count)s)"
#: templates/user_inbox/base.html:38
msgid "group join requests"
@@ -6770,11 +6770,11 @@ msgstr "选择:"
#: templates/user_inbox/responses_and_flags.html:10
msgid "seen"
-msgstr "查看"
+msgstr "已看"
#: templates/user_inbox/responses_and_flags.html:11
msgid "new"
-msgstr "æ–°"
+msgstr "未看"
#: templates/user_inbox/responses_and_flags.html:12
msgid "none"
@@ -6782,11 +6782,11 @@ msgstr "æ— "
#: templates/user_inbox/responses_and_flags.html:15
msgid "mark as seen"
-msgstr "已看标记"
+msgstr "标记为已看"
#: templates/user_inbox/responses_and_flags.html:16
msgid "mark as new"
-msgstr "新标记"
+msgstr "标记为未看"
#: templates/user_inbox/responses_and_flags.html:17
msgid "dismiss"
@@ -6802,56 +6802,56 @@ msgstr "删除文章"
#: templates/user_profile/reject_post_dialog.html:4
msgid "Reject the post(s)?"
-msgstr ""
+msgstr "æ‹’ç»å¸–å­ï¼Ÿ"
#: templates/user_profile/reject_post_dialog.html:11
msgid "1) Enter a brief description of why you are rejecting the post."
-msgstr ""
+msgstr "1)简è¦è¯´æ˜Žä½ æ‹’ç»çš„ç†ç”±ã€‚"
#: templates/user_profile/reject_post_dialog.html:14
msgid "2) Please enter details here. This text will be sent to the user."
-msgstr ""
+msgstr "2)请在这里输入的细节。本文将被å‘é€åˆ°ç”¨æˆ·ã€‚"
#: templates/user_profile/reject_post_dialog.html:20
#: templates/user_profile/reject_post_dialog.html:88
msgid "Use this reason &amp; reject"
-msgstr ""
+msgstr "使用这个ç†ç”± &amp; æ‹’ç»"
#: templates/user_profile/reject_post_dialog.html:27
#: templates/user_profile/reject_post_dialog.html:95
msgid "Use other reason"
-msgstr ""
+msgstr "使用其它的ç†ç”±"
#: templates/user_profile/reject_post_dialog.html:33
msgid "Save reason, but do not reject"
-msgstr ""
+msgstr "ä¿å­˜ä¸€ä¸ªç†ç”±ï¼Œä½†ç”¨ä¸ä½¿ç”¨"
#: templates/user_profile/reject_post_dialog.html:43
msgid "Please, choose a reason for the rejection."
-msgstr ""
+msgstr "请选择一个ç†ç”±ï¼Œæ‹’ç»ã€‚"
#: templates/user_profile/reject_post_dialog.html:58
msgid "Select this reason"
-msgstr ""
+msgstr "选择这个ç†ç”±"
#: templates/user_profile/reject_post_dialog.html:65
msgid "Delete this reason"
-msgstr ""
+msgstr "删除这个ç†ç”±"
#: templates/user_profile/reject_post_dialog.html:71
msgid "Add a new reason"
-msgstr ""
+msgstr "添加一个新的ç†ç”±"
#: templates/user_profile/reject_post_dialog.html:81
msgid ""
"You have selected reason for the rejection <strong>\"<span class=\"selected-"
"reason-title\"></span>\"</strong>. The text below will be sent to the user "
"and the post(s) will be deleted:"
-msgstr ""
+msgstr "ä½ å·²ç»é€‰æ‹©äº†ä¸€ä¸ªç†ç”±æ¥æ‹’ç»<strong>\"<span class=\"selected-reason-title\"></span>\"</strong>. 下é¢çš„文字(ç†ç”±)将在删除åŽå‘é€ç»™ç”¨æˆ·ï¼š"
#: templates/user_profile/reject_post_dialog.html:101
msgid "Edit this reason"
-msgstr ""
+msgstr "修改这个ç†ç”±"
#: templates/user_profile/twitter_sharing_controls.html:8
#, python-format
@@ -6991,7 +6991,7 @@ msgstr "上次活动时间"
#: templates/user_profile/user_info.html:88
msgid "website"
-msgstr ""
+msgstr "个人网站"
#: templates/user_profile/user_info.html:101
msgid "location"
@@ -7099,7 +7099,7 @@ msgstr ""
#: templates/user_profile/user_network.html:5
#: templates/user_profile/user_tabs.html:18
msgid "network"
-msgstr "网络"
+msgstr "朋å‹åœˆ"
#: templates/user_profile/user_network.html:10
#, python-format
@@ -7117,7 +7117,7 @@ msgstr[0] "关注 %(count)s å用户"
msgid ""
"Your network is empty. Would you like to follow someone? - Just visit their "
"profiles and click \"follow\""
-msgstr "网络为空。是å¦å¸Œæœ›å…³æ³¨ä¸€äº›ç”¨æˆ·? - åªéœ€è®¿é—®å…¶ä¸ªäººæ¡£æ¡ˆå¹¶ç‚¹å‡»â€œå…³æ³¨â€"
+msgstr "朋å‹åœˆä¸ºç©ºã€‚是å¦å¸Œæœ›å…³æ³¨ä¸€äº›ç”¨æˆ·? - åªéœ€è®¿é—®å…¶ä¸ªäººæ¡£æ¡ˆå¹¶ç‚¹å‡»â€œå…³æ³¨â€"
#: templates/user_profile/user_network.html:33
#, python-format
@@ -7196,7 +7196,7 @@ msgstr "粉ä¸åŠå·²å…³æ³¨ç”¨æˆ·"
#: templates/user_profile/user_tabs.html:22
msgid "Graph of user karma"
-msgstr ""
+msgstr "用户的社区积分历å²"
#: templates/user_profile/user_tabs.html:27
msgid "questions that user is following"
@@ -7265,7 +7265,7 @@ msgstr "贡献者"
#: templates/widgets/edit_post.html:33
msgid ", one of these is required"
-msgstr ""
+msgstr "这些中的一个为必填项"
#: templates/widgets/edit_post.html:42 templates/widgets/edit_post.html:47
msgid "tags:"
@@ -7492,7 +7492,7 @@ msgstr "感兴趣的标签"
#: templates/widgets/tag_selector.html:22
msgid "Ignored tags"
-msgstr "忽略标签"
+msgstr "ä¸æ„Ÿå…´è¶£çš„标签"
#: templates/widgets/tag_selector.html:40
msgid "Subscribed tags"
@@ -7585,7 +7585,7 @@ msgstr "å‘起问题,答案和评论。"
#: templatetags/extra_filters_jinja.py:332
msgid "no"
-msgstr ""
+msgstr "æ— "
#: utils/decorators.py:104 views/commands.py:146
msgid "Oops, apologies - there was some error"
@@ -7775,7 +7775,7 @@ msgstr "请登录åŽæŠ•ç¥¨"
#: views/commands.py:980
msgid "Please sign in to delete/restore posts"
-msgstr ""
+msgstr "请登录åŽçš„删除/æ¢å¤å¸–å­"
#: views/commands.py:1042
#, python-format
@@ -7891,7 +7891,7 @@ msgstr "用户资料 - 投票"
#: views/users.py:883
msgid "user karma"
-msgstr ""
+msgstr "用户社区积分"
#: views/users.py:884
msgid "Profile - User's Karma"
diff --git a/askbot/locale/zh_HK/LC_MESSAGES/django.mo b/askbot/locale/zh_HK/LC_MESSAGES/django.mo
index 432ba792..37fff89a 100644
--- a/askbot/locale/zh_HK/LC_MESSAGES/django.mo
+++ b/askbot/locale/zh_HK/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/zh_HK/LC_MESSAGES/django.po b/askbot/locale/zh_HK/LC_MESSAGES/django.po
index 35944848..96beb4a5 100644
--- a/askbot/locale/zh_HK/LC_MESSAGES/django.po
+++ b/askbot/locale/zh_HK/LC_MESSAGES/django.po
@@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:06-0500\n"
-"PO-Revision-Date: 2013-07-15 02:23+0000\n"
+"PO-Revision-Date: 2013-08-28 05:48+0000\n"
"Last-Translator: brucelok\n"
"Language-Team: Chinese (Hong Kong) (http://www.transifex.com/projects/p/askbot/language/zh_HK/)\n"
"MIME-Version: 1.0\n"
@@ -163,7 +163,7 @@ msgstr "已暫åœ"
#: forms.py:603 const/__init__.py:378
msgid "blocked"
-msgstr ""
+msgstr "阻止"
#: forms.py:605
msgid "administrator"
@@ -171,11 +171,11 @@ msgstr "管ç†å“¡"
#: forms.py:606 const/__init__.py:374
msgid "moderator"
-msgstr ""
+msgstr "å”調人"
#: forms.py:625
msgid "Change status to"
-msgstr ""
+msgstr "將狀態更改為"
#: forms.py:652
msgid "which one?"
@@ -183,7 +183,7 @@ msgstr "哪一個?"
#: forms.py:673
msgid "Cannot change own status"
-msgstr ""
+msgstr "ä¸èƒ½æ›´æ”¹è‡ªå·±çš„狀態"
#: forms.py:679
msgid "Cannot turn other user to moderator"
diff --git a/askbot/locale/zh_TW/LC_MESSAGES/django.mo b/askbot/locale/zh_TW/LC_MESSAGES/django.mo
index af1956a7..270aa57c 100644
--- a/askbot/locale/zh_TW/LC_MESSAGES/django.mo
+++ b/askbot/locale/zh_TW/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/zh_TW/LC_MESSAGES/django.po b/askbot/locale/zh_TW/LC_MESSAGES/django.po
index ed8cb429..a3aee812 100644
--- a/askbot/locale/zh_TW/LC_MESSAGES/django.po
+++ b/askbot/locale/zh_TW/LC_MESSAGES/django.po
@@ -3,8 +3,11 @@
# This file is distributed under the same license as the CNPROG package.
#
# Translators:
+# carl_tw, 2013
+# carl_tw, 2013
# evgeny <evgeny.fadeev@gmail.com>, 2009
# evgeny <evgeny.fadeev@gmail.com>, 2009
+# floydsoft <floydsoft@gmail.com>, 2013
# whisky <whisky@ystaiwan.org.tw>, 2013
# whisky <whisky@ystaiwan.org.tw>, 2013
msgid ""
@@ -12,8 +15,8 @@ msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:06-0500\n"
-"PO-Revision-Date: 2013-08-02 06:30+0000\n"
-"Last-Translator: evgeny <evgeny.fadeev@gmail.com>\n"
+"PO-Revision-Date: 2013-09-02 17:31+0000\n"
+"Last-Translator: carl_tw\n"
"Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/askbot/language/zh_TW/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -23,7 +26,7 @@ msgstr ""
#: exceptions.py:13
msgid "Sorry, but anonymous visitors cannot access this function"
-msgstr ""
+msgstr "抱歉,匿å訪å•è€…無法存å–此功能"
#: feed.py:34 feed.py:108
msgid " - "
@@ -43,7 +46,7 @@ msgstr "國家"
#: forms.py:158
msgid "Country field is required"
-msgstr ""
+msgstr "國家欄ä½å¿…å¡«"
#: forms.py:188
#, python-format
@@ -162,11 +165,11 @@ msgstr ""
#: forms.py:602 const/__init__.py:377
msgid "suspended"
-msgstr ""
+msgstr "å·²åœæ¬Š"
#: forms.py:603 const/__init__.py:378
msgid "blocked"
-msgstr ""
+msgstr "å·²å°éŽ–"
#: forms.py:605
msgid "administrator"
@@ -174,11 +177,11 @@ msgstr "管ç†å“¡"
#: forms.py:606 const/__init__.py:374
msgid "moderator"
-msgstr ""
+msgstr "å”調人"
#: forms.py:625
msgid "Change status to"
-msgstr ""
+msgstr "改變狀態至"
#: forms.py:652
msgid "which one?"
@@ -198,7 +201,7 @@ msgstr ""
#: forms.py:692
msgid "Cannot change status to admin"
-msgstr ""
+msgstr "無法將狀態改為管ç†å“¡"
#: forms.py:698
#, python-format
@@ -221,11 +224,11 @@ msgstr ""
#: forms.py:728
msgid "Email:"
-msgstr ""
+msgstr "é›»å­ä¿¡ç®±ï¼š"
#: forms.py:730
msgid "Your message:"
-msgstr "訊æ¯å…§å®¹ï¼š"
+msgstr "您的訊æ¯ï¼š"
#: forms.py:735
msgid "I don't want to give my email or receive a response:"
@@ -261,7 +264,7 @@ msgstr ""
#: forms.py:914 forms.py:957
msgid "ask anonymously"
-msgstr ""
+msgstr "匿åæå•"
#: forms.py:916 forms.py:959
msgid "Check if you do not want to reveal your name when asking this question"
@@ -310,7 +313,7 @@ msgstr "城市"
#: forms.py:1396
msgid "Show country"
-msgstr ""
+msgstr "顯示國家"
#: forms.py:1401
msgid "Show tag choices"
@@ -330,7 +333,7 @@ msgstr "個人簡介"
#: forms.py:1425
msgid "Screen name"
-msgstr ""
+msgstr "顯示å稱"
#: forms.py:1457 forms.py:1461
msgid "this email has already been registered, please use another one"
@@ -407,150 +410,150 @@ msgstr "å•é¡Œ"
#: urls.py:56
msgid "question/"
-msgstr ""
+msgstr "question/"
#: urls.py:61
msgid "tags/"
-msgstr ""
+msgstr "tags/"
#: urls.py:66 urls.py:71 urls.py:78 urls.py:84 urls.py:93 urls.py:100
msgid "users/"
-msgstr ""
+msgstr "users/"
#: urls.py:71
msgid "by-group/"
-msgstr ""
+msgstr "by-group/"
#: urls.py:78 urls.py:159 urls.py:226 urls.py:520
msgid "edit/"
-msgstr "編輯/"
+msgstr "edit/"
#: urls.py:85
msgid "subscriptions/"
-msgstr ""
+msgstr "subscriptions/"
#: urls.py:94
msgid "select_languages/"
-msgstr ""
+msgstr "select_languages/"
#: urls.py:105
msgid "groups/"
-msgstr ""
+msgstr "groups/"
#: urls.py:110
msgid "users/update_has_custom_avatar/"
-msgstr ""
+msgstr "users/update_has_custom_avatar/"
#: urls.py:115 urls.py:120
msgid "badges/"
-msgstr "徽章/"
+msgstr "badges/"
#: urls.py:133
msgid "feedback/"
-msgstr ""
+msgstr "feedback/"
#: urls.py:154
msgid "about/"
-msgstr "關於/"
+msgstr "about/"
#: urls.py:155
msgid "faq/"
-msgstr ""
+msgstr "faq/"
#: urls.py:156
msgid "privacy/"
-msgstr ""
+msgstr "privacy/"
#: urls.py:157
msgid "help/"
-msgstr ""
+msgstr "help/"
#: urls.py:159 urls.py:164
msgid "answers/"
-msgstr ""
+msgstr "answers/"
#: urls.py:164 urls.py:256
msgid "revisions/"
-msgstr "版本/"
+msgstr "revisions/"
#: urls.py:221 urls.py:226 urls.py:231 urls.py:236 urls.py:241 urls.py:246
#: urls.py:256
msgid "questions/"
-msgstr "å•é¡Œ/"
+msgstr "questions/"
#: urls.py:221 urls.py:495 urls.py:500 urls.py:505 urls.py:510
msgid "ask/"
-msgstr "æå•/"
+msgstr "ask/"
#: urls.py:231
msgid "retag/"
-msgstr ""
+msgstr "retag/"
#: urls.py:236
msgid "close/"
-msgstr ""
+msgstr "close/"
#: urls.py:241
msgid "reopen/"
-msgstr ""
+msgstr "reopen/"
#: urls.py:246
msgid "answer/"
-msgstr ""
+msgstr "answer/"
#: urls.py:314
msgid "tags/subscriptions/"
-msgstr ""
+msgstr "tags/subscriptions/"
#: urls.py:319
msgid "tags/subscriptions/delete/"
-msgstr ""
+msgstr "tags/subscriptions/delete/"
#: urls.py:324
msgid "tags/subscriptions/create/"
-msgstr ""
+msgstr "tags/subscriptions/create/"
#: urls.py:329
msgid "tags/subscriptions/edit/"
-msgstr ""
+msgstr "tags/subscriptions/edit/"
#: urls.py:334
msgid "suggested-tags/"
-msgstr ""
+msgstr "suggested-tags/"
#: urls.py:459
msgid "messages/"
-msgstr ""
+msgstr "messages/"
#: urls.py:459
msgid "markread/"
-msgstr ""
+msgstr "markread/"
#: urls.py:490 urls.py:495 urls.py:500 urls.py:505 urls.py:510 urls.py:515
#: urls.py:520 urls.py:525 urls.py:530
msgid "widgets/"
-msgstr ""
+msgstr "widgets/"
#: urls.py:510 deps/django_authopenid/urls.py:20
msgid "complete/"
-msgstr ""
+msgstr "complete/"
#: urls.py:515
msgid "create/"
-msgstr ""
+msgstr "create/"
#: urls.py:525
msgid "delete/"
-msgstr ""
+msgstr "delete/"
#: urls.py:560
msgid "upload/"
-msgstr ""
+msgstr "upload/"
#: urls.py:585 setup_templates/settings.py:229
#: templates/authopenid/providers_javascript.html:7
msgid "account/"
-msgstr ""
+msgstr "account/"
#: conf/access_control.py:8
msgid "Access control settings"
@@ -590,7 +593,7 @@ msgstr ""
#: conf/badges.py:13
msgid "Badge settings"
-msgstr ""
+msgstr "徽章設定"
#: conf/badges.py:23
msgid "Disciplined: minimum upvotes for deleted post"
@@ -690,7 +693,7 @@ msgstr ""
#: conf/email.py:15
msgid "Email and email alert settings"
-msgstr ""
+msgstr "é›»å­ä¿¡ç®±ä»¥åŠä¿¡ç®±é€šçŸ¥è¨­å®š"
#: conf/email.py:24
msgid "Prefix for the email subject line"
@@ -880,7 +883,7 @@ msgstr ""
#: conf/external_keys.py:19
msgid "Google site verification key"
-msgstr ""
+msgstr "Google å”作平å°é©—證金鑰"
#: conf/external_keys.py:21
#, python-format
@@ -922,7 +925,7 @@ msgstr ""
#: conf/external_keys.py:84
msgid "Facebook public API key"
-msgstr ""
+msgstr "Facebook 公開 API 金鑰"
#: conf/external_keys.py:86
#, python-format
@@ -934,7 +937,7 @@ msgstr ""
#: conf/external_keys.py:99
msgid "Facebook secret key"
-msgstr ""
+msgstr "Facebook ç§é‘°"
#: conf/external_keys.py:107
msgid "Twitter consumer key"
@@ -1345,7 +1348,7 @@ msgstr ""
#: conf/karma_and_badges_visibility.py:47
msgid "Badges can be either publicly shown or completely hidden"
-msgstr ""
+msgstr "徽章å¯ä»¥å…¬é–‹å±•ç¤ºï¼Œä¹Ÿå¯ä»¥å®Œå…¨éš±è—"
#: conf/ldap.py:9
msgid "LDAP login configuration"
@@ -1572,7 +1575,7 @@ msgstr ""
#: conf/login_providers.py:60
msgid "Upload your icon"
-msgstr ""
+msgstr "上傳您的圖示"
#: conf/login_providers.py:93
msgid "local password"
@@ -1894,7 +1897,7 @@ msgstr ""
#: conf/sidebar_main.py:12
msgid "Main page sidebar"
-msgstr ""
+msgstr "首é è³‡è¨Šçœ‹æ¿"
#: conf/sidebar_main.py:20 conf/sidebar_question.py:67
msgid "Custom sidebar header"
@@ -1959,7 +1962,7 @@ msgstr ""
#: conf/sidebar_profile.py:12
msgid "User profile sidebar"
-msgstr ""
+msgstr "使用者資料資訊看æ¿"
#: conf/sidebar_profile.py:20
msgid "Custom sidebar"
@@ -2000,11 +2003,11 @@ msgstr ""
#: conf/sidebar_question.py:92
msgid "Show tag list in sidebar"
-msgstr ""
+msgstr "資訊看æ¿é¡¯ç¤ºæ¨™ç±¤æ¸…å–®"
#: conf/sidebar_question.py:94
msgid "Uncheck this if you want to hide the tag list from the sidebar "
-msgstr ""
+msgstr "若您想在資訊看æ¿éš±è—標籤清單,請å–消勾é¸æ­¤é …"
#: conf/sidebar_question.py:105
msgid "Show meta information in sidebar"
@@ -2297,7 +2300,7 @@ msgstr ""
#: conf/skin_general_settings.py:234
msgid "Apply custom style sheet (CSS)"
-msgstr ""
+msgstr "套用自訂樣å¼è¡¨ (CSS)"
#: conf/skin_general_settings.py:236
msgid ""
@@ -2307,7 +2310,7 @@ msgstr ""
#: conf/skin_general_settings.py:248
msgid "Custom style sheet (CSS)"
-msgstr ""
+msgstr "自訂樣å¼è¡¨ (CSS)"
#: conf/skin_general_settings.py:250
msgid ""
@@ -2320,7 +2323,7 @@ msgstr ""
#: conf/skin_general_settings.py:266
msgid "Add custom javascript"
-msgstr ""
+msgstr "加入自訂 JavaScript"
#: conf/skin_general_settings.py:269
msgid "Check to enable javascript that you can enter in the next field"
@@ -2501,7 +2504,7 @@ msgstr ""
#: conf/user_settings.py:134
msgid "Default Gravatar icon type"
-msgstr ""
+msgstr "é è¨­ Gravatar 圖示類型"
#: conf/user_settings.py:136
msgid ""
@@ -2714,7 +2717,7 @@ msgstr "修改回答"
#: const/__init__.py:201
msgid "received badge"
-msgstr ""
+msgstr "收到的徽章"
#: const/__init__.py:202
msgid "marked best answer"
@@ -2903,7 +2906,7 @@ msgstr ""
#: const/__init__.py:424
msgid "Gravatar"
-msgstr ""
+msgstr "Gravatar"
#: const/__init__.py:425
msgid "Uploaded Avatar"
@@ -3096,39 +3099,39 @@ msgstr ""
#: deps/django_authopenid/urls.py:14 deps/django_authopenid/urls.py:20
#: deps/django_authopenid/urls.py:23 setup_templates/settings.py:229
msgid "signin/"
-msgstr ""
+msgstr "signin/"
#: deps/django_authopenid/urls.py:15
msgid "widget/signin/"
-msgstr ""
+msgstr "widget/signin/"
#: deps/django_authopenid/urls.py:18
msgid "signout/"
-msgstr ""
+msgstr "signout/"
#: deps/django_authopenid/urls.py:23
msgid "complete-oauth/"
-msgstr ""
+msgstr "complete-oauth/"
#: deps/django_authopenid/urls.py:32
msgid "register/"
-msgstr ""
+msgstr "register/"
#: deps/django_authopenid/urls.py:34
msgid "signup/"
-msgstr ""
+msgstr "signup/"
#: deps/django_authopenid/urls.py:38
msgid "logout/"
-msgstr ""
+msgstr "logout/"
#: deps/django_authopenid/urls.py:43
msgid "recover/"
-msgstr ""
+msgstr "recover/"
#: deps/django_authopenid/urls.py:45
msgid "verify-email/"
-msgstr ""
+msgstr "verify-email/"
#: deps/django_authopenid/util.py:379
#, python-format
@@ -3146,7 +3149,7 @@ msgstr ""
#: deps/django_authopenid/util.py:486
msgid "Sign in with Yahoo"
-msgstr ""
+msgstr "使用 Yahoo 帳號登入"
#: deps/django_authopenid/util.py:493
msgid "AOL screen name"
@@ -3329,12 +3332,12 @@ msgstr ""
#: deps/livesettings/values.py:251
msgid "Default value: "
-msgstr ""
+msgstr "é è¨­å€¼ï¼š"
#: deps/livesettings/values.py:254
#, python-format
msgid "Default value: %s"
-msgstr ""
+msgstr "é è¨­å€¼ï¼š%s"
#: deps/livesettings/values.py:641
#, python-format
@@ -3578,7 +3581,7 @@ msgstr ""
#: models/__init__.py:921
msgid ""
"Sorry, since your account is suspended you can edit only your own posts"
-msgstr ""
+msgstr "很抱歉,由於您的帳號已被åœæ¬Šï¼Œå› æ­¤åªèƒ½ç·¨è¼¯è‡ªå·±çš„貼文。"
#: models/__init__.py:926
#, python-format
@@ -3620,7 +3623,7 @@ msgstr ""
#: models/__init__.py:1040
msgid "Sorry, since your account is blocked you cannot close questions"
-msgstr ""
+msgstr "很抱歉,由於您的帳號已é­å°éŽ–,因此無法關閉å•é¡Œã€‚"
#: models/__init__.py:1044
msgid "Sorry, since your account is suspended you cannot close questions"
@@ -3741,7 +3744,7 @@ msgstr ""
#: models/__init__.py:1274
msgid ""
"Sorry, since your account is suspended you can delete only your own comments"
-msgstr ""
+msgstr "很抱歉,由於您的帳號已被åœæ¬Šï¼Œå› æ­¤åªèƒ½åˆªé™¤è‡ªå·±çš„留言"
#: models/__init__.py:1278
#, python-format
@@ -3769,13 +3772,13 @@ msgstr ""
#, python-format
msgid "in %(hr)d hour"
msgid_plural "in %(hr)d hours"
-msgstr[0] ""
+msgstr[0] "æ–¼ %(hr)d å°æ™‚å‰"
#: models/__init__.py:2003
#, python-format
msgid "in %(min)d min"
msgid_plural "in %(min)d mins"
-msgstr[0] ""
+msgstr[0] "æ–¼ %(min)d 分é˜å‰"
#: models/__init__.py:2004
#, python-format
@@ -3804,7 +3807,7 @@ msgstr ""
#: models/__init__.py:2302
msgid "Suspended User"
-msgstr ""
+msgstr "åœæ¬Šçš„使用者"
#: models/__init__.py:2304
msgid "Blocked User"
@@ -3831,19 +3834,19 @@ msgstr ""
#, python-format
msgid "one gold badge"
msgid_plural "%(count)d gold badges"
-msgstr[0] ""
+msgstr[0] "%(count)d 個金牌"
#: models/__init__.py:2515
#, python-format
msgid "one silver badge"
msgid_plural "%(count)d silver badges"
-msgstr[0] ""
+msgstr[0] "%(count)d 個銀牌"
#: models/__init__.py:2522
#, python-format
msgid "one bronze badge"
msgid_plural "%(count)d bronze badges"
-msgstr[0] ""
+msgstr[0] "%(count)d 個銅牌"
#: models/__init__.py:2533
#, python-format
@@ -4545,12 +4548,12 @@ msgstr ""
#: templates/badge.html:5
msgid "Badge"
-msgstr "çŽç‰Œ"
+msgstr "徽章"
#: templates/badge.html:7
#, python-format
msgid "Badge \"%(name)s\""
-msgstr ""
+msgstr "「%(name)sã€å¾½ç« "
#: templates/badge.html:9 templates/user_profile/user_recent.html:16
#: templates/user_profile/user_stats.html:71
@@ -4561,11 +4564,11 @@ msgstr ""
#: templates/badge.html:14
msgid "user received this badge:"
msgid_plural "users received this badge:"
-msgstr[0] ""
+msgstr[0] "使用者收到此徽章:"
#: templates/badges.html:3 templates/badges.html.py:5
msgid "Badges"
-msgstr "çŽå‹µ"
+msgstr "徽章"
#: templates/badges.html:7
msgid "Community gives you awards for your questions, answers and votes."
@@ -4579,7 +4582,7 @@ msgstr ""
#: templates/badges.html:31
msgid "Community badges"
-msgstr "社群çŽå‹µ"
+msgstr "徽章等級"
#: templates/badges.html:33
msgid "gold badge: the highest honor and is very rare"
@@ -5350,7 +5353,7 @@ msgstr ""
#: templates/subscribe_for_tags.html:15
msgid "Subscribe"
-msgstr ""
+msgstr "訂閱"
#: templates/tags.html:17
msgid "search for tags"
@@ -5552,7 +5555,7 @@ msgstr "登出"
#: templates/authopenid/logout.html:5
msgid "You have successfully logged out"
-msgstr ""
+msgstr "您已æˆåŠŸç™»å‡º"
#: templates/authopenid/logout.html:7
msgid ""
@@ -5651,12 +5654,12 @@ msgstr ""
#: templates/authopenid/signin.html:126
#: templates/authopenid/widget_signin.html:129
msgid "New password"
-msgstr ""
+msgstr "新的密碼"
#: templates/authopenid/signin.html:135
#: templates/authopenid/widget_signin.html:138
msgid "Please, retype"
-msgstr ""
+msgstr "è«‹é‡æ–°è¼¸å…¥"
#: templates/authopenid/signin.html:145
#: templates/authopenid/widget_signin.html:148
@@ -6489,7 +6492,7 @@ msgstr ""
#: templates/question/new_answer_form.html:12
msgid "Login/Signup to Answer"
-msgstr ""
+msgstr "登入或註冊回答å•é¡Œ"
#: templates/question/new_answer_form.html:20
msgid "Your answer"
@@ -7084,7 +7087,7 @@ msgstr ""
#: templates/user_profile/user_moderate.html:83
msgid "Suspended users can only edit or delete their own posts."
-msgstr ""
+msgstr "é­åˆ°åœæ¬Šçš„使用者åªèƒ½ç·¨è¼¯æˆ–刪除自己的貼文。"
#: templates/user_profile/user_moderate.html:86
msgid ""
@@ -7437,7 +7440,7 @@ msgstr "用戶"
#: templates/widgets/meta_nav.html:27
msgid "badges"
-msgstr "çŽå‹µæ¦œ"
+msgstr "徽章"
#: templates/widgets/question_edit_tips.html:5
msgid "ask a question interesting to this community"
@@ -7533,7 +7536,7 @@ msgstr ""
#: templates/widgets/user_long_score_and_badge_summary.html:15
msgid "badges:"
-msgstr ""
+msgstr "徽章:"
#: templates/widgets/user_navigation.html:17
msgid "sign out"
diff --git a/askbot/locale/zh_TW/LC_MESSAGES/djangojs.mo b/askbot/locale/zh_TW/LC_MESSAGES/djangojs.mo
index e66fa4e9..534b2ac4 100644
--- a/askbot/locale/zh_TW/LC_MESSAGES/djangojs.mo
+++ b/askbot/locale/zh_TW/LC_MESSAGES/djangojs.mo
Binary files differ
diff --git a/askbot/locale/zh_TW/LC_MESSAGES/djangojs.po b/askbot/locale/zh_TW/LC_MESSAGES/djangojs.po
index aecd2bcf..1132bf48 100644
--- a/askbot/locale/zh_TW/LC_MESSAGES/djangojs.po
+++ b/askbot/locale/zh_TW/LC_MESSAGES/djangojs.po
@@ -3,13 +3,14 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
+# carl_tw, 2013
msgid ""
msgstr ""
"Project-Id-Version: askbot\n"
"Report-Msgid-Bugs-To: http://askbot.org/\n"
"POT-Creation-Date: 2013-07-13 14:07-0500\n"
-"PO-Revision-Date: 2013-08-02 06:31+0000\n"
-"Last-Translator: evgeny <evgeny.fadeev@gmail.com>\n"
+"PO-Revision-Date: 2013-09-02 17:13+0000\n"
+"Last-Translator: carl_tw\n"
"Language-Team: Chinese (Taiwan) (http://www.transifex.com/projects/p/askbot/language/zh_TW/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -77,7 +78,7 @@ msgstr ""
#: media/js/group_messaging.js:139
msgid "Your message:"
-msgstr ""
+msgstr "您的訊æ¯ï¼š"
#: media/js/group_messaging.js:152
msgid "send"
@@ -90,7 +91,7 @@ msgstr "å–消"
#: media/js/group_messaging.js:227
msgid "Reply"
-msgstr ""
+msgstr "回覆"
#: media/js/group_messaging.js:236 media/js/group_messaging.js.c:743
msgid "message sent"
@@ -316,7 +317,7 @@ msgstr "請輸入å•é¡Œæ¨™é¡Œ (>10 個字元)"
#: media/js/post.js:2612 media/js/post.js.c:4626
msgid "Sorry, you have only read access"
-msgstr ""
+msgstr "很抱歉,您åªæ“有讀å–權é™"
#: media/js/post.js:3075 media/js/post.js.c:3869 media/js/post.js.c:4058
msgid "save"
@@ -351,7 +352,7 @@ msgstr[0] ""
#: media/js/post.js:3799
msgid "Delete category?"
-msgstr ""
+msgstr "是å¦åˆªé™¤åˆ†é¡žï¼Ÿ"
#: media/js/post.js:3888 media/js/utils.js:881
msgid "edit"
@@ -379,15 +380,15 @@ msgstr ""
#: media/js/post.js:4710
msgid "Group name:"
-msgstr ""
+msgstr "群組å稱:"
#: media/js/post.js:4736
msgid "Shared with the following users:"
-msgstr ""
+msgstr "與這些使用者共享:"
#: media/js/post.js:4742
msgid "Shared with the following groups:"
-msgstr ""
+msgstr "與這些群組共享:"
#: media/js/tag_selector.js:14
msgid "Tag \"<span></span>\" matches:"
@@ -410,7 +411,7 @@ msgstr[0] "是å¦è¦åˆªé™¤é€™äº›é€šçŸ¥ï¼Ÿ"
#: media/js/user.js:66
msgid "Close this entry?"
msgid_plural "Close these entries?"
-msgstr[0] ""
+msgstr[0] "是å¦é—œé–‰é€™äº›é …目?"
#: media/js/user.js:74
msgid "Remove all flags and approve this entry?"
@@ -419,23 +420,23 @@ msgstr[0] ""
#: media/js/user.js:223
msgid "Post deleted"
-msgstr ""
+msgstr "您的貼文已經刪除"
#: media/js/user.js:225
msgid "Post approved"
-msgstr ""
+msgstr "您的貼文已經æ¢å¾©äº†ï¼"
#: media/js/user.js:246
msgid "Accept"
-msgstr ""
+msgstr "接å—"
#: media/js/user.js:255
msgid "Reject"
-msgstr ""
+msgstr "拒絕"
#: media/js/user.js:270
msgid "add new reject reason"
-msgstr ""
+msgstr "新增拒絕原因"
#: media/js/user.js:375
msgid "Looks there are some things to fix:"
@@ -478,11 +479,11 @@ msgstr "跟隨 %s"
#: media/js/user.js:883
msgid "add group"
-msgstr ""
+msgstr "加入群組"
#: media/js/user.js:963
msgid "add"
-msgstr ""
+msgstr "加入"
#: media/js/utils.js:99
msgid "and"
@@ -502,16 +503,16 @@ msgstr ""
#: media/js/utils.js:958
msgid "Ok"
-msgstr ""
+msgstr "確定"
#: media/js/utils.js:959 media/js/utils.js.c:1407
msgid "Cancel"
-msgstr ""
+msgstr "å–消"
#: media/js/utils.js:1219
#, c-format
msgid "Uploaded file: %s"
-msgstr ""
+msgstr "已上傳檔案:%s"
#: media/js/utils.js:1234
msgid "Choose a different image"
@@ -544,27 +545,27 @@ msgstr ""
#: media/js/utils.js:1406
msgid "Save"
-msgstr ""
+msgstr "儲存"
#: media/js/utils.js:1478
msgid "saved"
-msgstr ""
+msgstr "已儲存"
#: media/js/utils.js:1602
msgid "enabled"
-msgstr ""
+msgstr "已啟用"
#: media/js/utils.js:1604
msgid "disabled"
-msgstr ""
+msgstr "å·²åœç”¨"
#: media/js/utils.js:2038
msgid "group name"
-msgstr ""
+msgstr "群組å稱"
#: media/js/utils.js:2046
msgid "add new group"
-msgstr ""
+msgstr "加入新的群組"
#: media/js/utils.js:2138
msgid "Group %(name)s already exists. Group names are case-insensitive."
@@ -577,7 +578,7 @@ msgstr "查看標有「%sã€çš„å•é¡Œ"
#: media/js/utils.js:3358
msgid "ago"
-msgstr ""
+msgstr "å‰"
#: media/js/utils.js:3359
msgid "from now"
@@ -585,48 +586,48 @@ msgstr ""
#: media/js/utils.js:3361
msgid "about a minute"
-msgstr ""
+msgstr "約一分é˜"
#: media/js/utils.js:3362
#, c-format
msgid "%d minutes"
-msgstr ""
+msgstr "%d 分é˜"
#: media/js/utils.js:3363
msgid "about an hour"
-msgstr ""
+msgstr "約一個å°æ™‚"
#: media/js/utils.js:3364
#, c-format
msgid "%d hours"
-msgstr ""
+msgstr "%d å°æ™‚"
#: media/js/utils.js:3365 media/js/utils.js.c:3493
msgid "yesterday"
-msgstr ""
+msgstr "昨天"
#: media/js/utils.js:3366
#, c-format
msgid "%d days"
-msgstr ""
+msgstr "%d 天"
#: media/js/utils.js:3367
msgid "about a month"
-msgstr ""
+msgstr "約一個月"
#: media/js/utils.js:3368
#, c-format
msgid "%d months"
-msgstr ""
+msgstr "%d 個月"
#: media/js/utils.js:3369
msgid "about a year"
-msgstr ""
+msgstr "約一年"
#: media/js/utils.js:3370
#, c-format
msgid "%d years"
-msgstr ""
+msgstr "%d å¹´"
#: media/js/utils.js:3468
msgid "Jan"
@@ -678,23 +679,23 @@ msgstr ""
#: media/js/utils.js:3491
msgid "2 days ago"
-msgstr ""
+msgstr "2 天å‰"
#: media/js/utils.js:3498
#, c-format
msgid "%s hour ago"
msgid_plural "%s hours ago"
-msgstr[0] ""
+msgstr[0] "%s å°æ™‚å‰"
#: media/js/utils.js:3508
#, c-format
msgid "%s min ago"
msgid_plural "%s mins ago"
-msgstr[0] ""
+msgstr[0] "%s 分é˜å‰"
#: media/js/tinymce/plugins/askbot_attachment/editor_plugin.js:71
msgid "Insert a file"
-msgstr ""
+msgstr "æ’入檔案"
#: media/js/tinymce/plugins/askbot_imageuploader/editor_plugin.js:70
msgid "Insert image"
diff --git a/askbot/mail/__init__.py b/askbot/mail/__init__.py
index 6fb88443..cb6f86a0 100644
--- a/askbot/mail/__init__.py
+++ b/askbot/mail/__init__.py
@@ -109,14 +109,14 @@ def _send_mail(subject_line, body_text, sender_email, recipient_list, headers=No
msg.send()
def send_mail(
- subject_line = None,
- body_text = None,
- from_email = django_settings.DEFAULT_FROM_EMAIL,
- recipient_list = None,
- activity_type = None,
- related_object = None,
- headers = None,
- raise_on_failure = False,
+ subject_line=None,
+ body_text=None,
+ from_email=None,
+ recipient_list=None,
+ activity_type=None,
+ related_object=None,
+ headers=None,
+ raise_on_failure=False,
):
"""
todo: remove parameters not relevant to the function
@@ -131,6 +131,8 @@ def send_mail(
if raise_on_failure is True, exceptions.EmailNotSent is raised
"""
+ from_email = from_email or askbot_settings.ADMIN_EMAIL or \
+ django_settings.DEFAULT_FROM_EMAIL
body_text = absolutize_urls(body_text)
try:
assert(subject_line is not None)
@@ -178,12 +180,12 @@ def mail_moderators(
)
-INSTRUCTIONS_PREAMBLE = ugettext_lazy('<p>To ask by email, please:</p>')
+INSTRUCTIONS_PREAMBLE = ugettext_lazy('<p>To post by email, please:</p>')
QUESTION_TITLE_INSTRUCTION = ugettext_lazy(
'<li>Type title in the subject line</li>'
)
QUESTION_DETAILS_INSTRUCTION = ugettext_lazy(
- '<li>Type details of your question into the email body</li>'
+ '<li>Type details into the email body</li>'
)
OPTIONAL_TAGS_INSTRUCTION = ugettext_lazy(
"""<li>The beginning of the subject line can contain tags,
@@ -209,7 +211,7 @@ def bounce_email(
"""
if reason == 'problem_posting':
error_message = _(
- '<p>Sorry, there was an error posting your question '
+ '<p>Sorry, there was an error while processing your message '
'please contact the %(site)s administrator</p>'
) % {'site': askbot_settings.APP_SHORT_NAME}
@@ -236,7 +238,7 @@ def bounce_email(
elif reason == 'unknown_user':
error_message = _(
- '<p>Sorry, in order to post questions on %(site)s '
+ '<p>Sorry, in order to make posts to %(site)s '
'by email, please <a href="%(url)s">register first</a></p>'
) % {
'site': askbot_settings.APP_SHORT_NAME,
@@ -244,7 +246,7 @@ def bounce_email(
}
elif reason == 'permission_denied' and body_text is None:
error_message = _(
- '<p>Sorry, your question could not be posted '
+ '<p>Sorry, your post could not be made by email '
'due to insufficient privileges of your user account</p>'
)
elif body_text:
diff --git a/askbot/management/commands/askbot_add_osqa_content.py b/askbot/management/commands/askbot_add_osqa_content.py
new file mode 100644
index 00000000..6820a036
--- /dev/null
+++ b/askbot/management/commands/askbot_add_osqa_content.py
@@ -0,0 +1,481 @@
+from askbot.deps.django_authopenid.models import UserAssociation
+from askbot.management.commands.base import BaseImportXMLCommand
+from askbot.models import Award
+from askbot.models import BadgeData
+from askbot.models import Post
+from askbot.models import PostRevision
+from askbot.models import Thread
+from askbot.models import Tag
+from askbot.models import User
+from askbot.utils.slug import slugify_camelcase
+from bs4 import BeautifulSoup
+from datetime import datetime
+from django.db.models import Q
+from django.utils import translation
+from django.conf import settings as django_settings
+from django.utils.http import urlquote as django_urlquote
+from django.template.defaultfilters import slugify
+from HTMLParser import HTMLParser
+
+def decode_datetime(data):
+ """Decodes formats:
+ * '2013-10-25 09:46:34'
+ * '2013-10-25'
+ """
+ if data:
+ try:
+ return datetime.strptime(data, '%Y-%m-%d %H:%M:%S')
+ except ValueError:
+ return datetime.strptime(data, '%Y-%m-%d')
+ return None
+
+class DataObject(object):
+ def __init__(self, soup):
+ """Initializes object based on the values passed
+ via BeautifulSoup instance for that object"""
+ self.soup = soup
+ self.data = dict()
+
+ def decode_typed_value(self, field):
+ field_type = field['type']
+ value = field.text.strip()
+ if field_type == 'BooleanField':
+ if value == 'False':
+ return False
+ else:
+ return True
+ elif field_type in ('CharField', 'TextField'):
+ return value
+ elif 'Integer' in field_type:
+ return int(value)
+ elif field_type in ('DateField', 'DateTimeField'):
+ return decode_datetime(value)
+ else:
+ raise ValueError('unknown field type: %s' % field_type)
+
+ def decode_rel_value(self, field):
+ rel_type = field['rel']
+ if rel_type in ('ManyToOneRel', 'OneToOneRel'):
+ try:
+ return int(field.text)
+ except:
+ return None
+ elif rel_type == 'ManyToManyRel':
+ items = field.find_all('object')
+ return [item['pk'] for item in items]
+ else:
+ raise ValueError('unknown relation type %s' % rel_type)
+
+ def decode_value(self, key):
+ """
+ type="DateField">
+ type="DateTimeField">
+ """
+ if key in ('pk', 'id'):
+ return int(self.soup['pk'])
+ field = self.soup.find('field', attrs={'name': key})
+ if field is None:
+ raise ValueError('could not find field %s' % key)
+ if field.get('type') != None:
+ return self.decode_typed_value(field)
+ elif field.get('rel') != None:
+ return self.decode_rel_value(field)
+ else:
+ raise ValueError('unknown field class %s - neither data nor relation')
+
+
+ def __getattr__(self, key):
+ """Returns value of property, if decoded
+ or decodes the property first from the bs4 soup"""
+ if key not in self.data:
+ value = self.decode_value(key)
+ self.data[key] = value
+ return self.data[key]
+
+
+class Command(BaseImportXMLCommand):
+ args = '<xml file>'
+ help = 'Adds XML OSQA data produced by the "dumpdata" command'
+
+ def handle(self, *args, **options):
+ translation.activate(django_settings.LANGUAGE_CODE)
+
+ self.setup_run()
+ self.redirect_format = self.get_redirect_format(options['redirect_format'])
+
+ dump_file_name = args[0]
+ xml = open(dump_file_name, 'r').read()
+ self.soup = BeautifulSoup(xml, ['lxml', 'xml'])
+
+ #site settings
+ #forum.keyvalue
+ self.import_users()
+ self.import_user_logins()
+ #model="forum.tag"
+ self.import_tags()
+
+ #model="forum.question"/answer/comment - derivatives of the Node model
+ self.import_threads()
+ self.import_posts('question', True)
+ #inside we also mark accepted answer, b/c it's more convenient that way
+ self.import_posts('answer')
+ self.import_posts('comment')
+ #model="forum.noderevision"
+ self.import_post_revisions()
+
+ self.fix_answer_counts()
+ self.fix_comment_counts()
+
+ #model="forum.subscriptionsettings"
+ #this model has no correspondence in Askbot
+
+ #model="forum.actionrepute"
+ #model="forum.award"
+
+ #model="forum.nodestate"
+
+ #model="forum.question"
+ #model="forum.questionsubscription"
+ #model="forum.userproperty"
+ #model="forum.validationhash"
+ #model="forum.vote"
+
+ #self.import_marked_tags()
+
+ #self.apply_groups_to_threads()
+
+ #self.apply_question_followers()
+ self.import_votes()
+
+ self.import_badges()
+ #self.import_badge_awards()
+
+ def get_objects_for_model(self, model):
+ objects_soup = self.soup.find_all(attrs={'model': model})
+ for item_soup in objects_soup:
+ yield DataObject(item_soup)
+
+ def import_users(self):
+ """import OSQA users to Askbot users"""
+ #in OSQA user profile is split in two models
+ #auth.user
+ #forum.user
+ for from_user in self.get_objects_for_model('auth.user'):
+ try:
+ to_user = User.objects.get(email=from_user.email)
+ except User.DoesNotExist:
+ username = self.get_safe_username(from_user.username)
+ to_user = User.objects.create_user(username, from_user.email)
+
+ self.copy_string_parameter(from_user, to_user, 'first_name')
+ self.copy_string_parameter(from_user, to_user, 'last_name')
+ self.copy_string_parameter(from_user, to_user, 'password')
+ self.copy_bool_parameter(from_user, to_user, 'is_staff')
+ self.copy_bool_parameter(from_user, to_user, 'is_active')
+ self.copy_bool_parameter(from_user, to_user, 'is_superuser')
+ self.copy_numeric_parameter(from_user, to_user, 'last_login', operator='max')
+ self.copy_numeric_parameter(from_user, to_user, 'date_joined', operator='min')
+ to_user.save()
+
+ self.log_action(from_user, to_user)
+
+ for profile in self.get_objects_for_model('forum.user'):
+ user = self.get_imported_object_by_old_id(User, profile.id)
+ self.copy_bool_parameter(profile, user, 'email_isvalid')
+ user.reputation = max(user.reputation + profile.reputation - 1, 1)
+ user.gold += profile.gold
+ user.silver += profile.silver
+ user.bronze += profile.bronze
+ self.copy_string_parameter(profile, user, 'real_name')
+ self.copy_numeric_parameter(profile, user, 'last_seen', operator='max')
+ self.copy_string_parameter(profile, user, 'website')
+ self.copy_string_parameter(profile, user, 'location')
+ self.copy_numeric_parameter(profile, user, 'date_of_birth')
+ self.copy_string_parameter(profile, user, 'about')
+ user.save()
+
+ def import_user_logins(self):
+ """import user's login methods from OSQA to Askbot"""
+ for user_login in self.get_objects_for_model('forum.authkeyuserassociation'):
+ assoc = UserAssociation()
+ assoc.openid_url = user_login.key
+ assoc.user = self.get_imported_object_by_old_id(User, user_login.user)
+ assoc.provider_name = user_login.provider
+ assoc.last_used_timestamp = user_login.added_at
+ assoc.save()
+
+ def import_tags(self):
+ """imports OSQA tags to Askbot tags"""
+ """
+ <object model="forum.tag" pk="2">
+ <field name="name" type="CharField">
+ pro
+ </field>
+ <field name="created_by" rel="ManyToOneRel" to="forum.user">
+ 1
+ </field>
+ <field name="created_at" type="DateTimeField">
+ 2012-06-09 18:34:13
+ </field>
+ <field name="used_count" type="PositiveIntegerField">
+ 259
+ </field>
+ </object>
+ """
+ for osqa_tag in self.get_objects_for_model('forum.tag'):
+ tag = Tag()
+ tag.name = osqa_tag.name
+ tag.created_by = self.get_imported_object_by_old_id(User, osqa_tag.created_by)
+ tag.used_count = osqa_tag.used_count
+ tag.save()
+
+ def import_badges(self):
+ """remembers relation of OSQA badges with Askbot badges"""
+ #model="forum.badge"
+ for osqa_badge in self.get_objects_for_model('forum.badge'):
+ badge_slug = slugify_camelcase(osqa_badge.cls)
+ try:
+ askbot_badge = BadgeData.objects.get(slug=badge_slug)
+ except BadgeData.DoesNotExist:
+ print 'Could not find an equivalent to badge %s in Askbot' % osqa_badge.cls
+ continue
+ self.log_action(osqa_badge, askbot_badge)
+ """
+ <object model="forum.badge" pk="1">
+ <field name="type" type="SmallIntegerField">
+ 3
+ </field>
+ <field name="cls" type="CharField">
+ PopularQuestion
+ </field>
+ <field name="awarded_count" type="PositiveIntegerField">
+ 0
+ </field>
+ </object>
+ """
+ """
+ slug = models.SlugField(max_length=50, unique=True)
+ awarded_count = models.PositiveIntegerField(default=0)
+ awarded_to = models.ManyToManyField(
+ User, through='Award', related_name='badges'
+ )
+ """
+
+ def import_badge_awards(self):
+ """Makes sure that users are re-awarded all previously
+ awarded OSQA badges"""
+ for osqa_award in self.get_objects_for_model('forum.award'):
+ user = self.get_imported_object_by_old_id(User, osqa_award.user)
+ badge = self.get_imported_object_by_old_id(BadgeData, osqa_award.badge)
+ if badge is None:
+ continue
+ print 'awarding badge %s' % badge.slug
+ #if multiple or user does not have this badge, then award
+ if badge.is_multiple() or (not user.has_badge(badge)):
+ award = Award()
+ award.badge = badge
+ award.user = user
+ award.notified = True
+ #todo: here we need to map to the node object
+ #content_type = self.get_content_type_by_old_id(award.content_type_id)
+ #obj_class = content_type.model_class()
+ #award.object_id = self.get_imported_object_id_by_old_id(obj_class, award.object_id)
+ #award.content_type = content_type
+ award.save()
+ """
+ <object model="forum.award" pk="1">
+ <field name="user" rel="ManyToOneRel" to="forum.user">
+ 1
+ </field>
+ <field name="badge" rel="ManyToOneRel" to="forum.badge">
+ 32
+ </field>
+ <field name="node" rel="ManyToOneRel" to="forum.node">
+ <None/>
+ </field>
+ <field name="awarded_at" type="DateTimeField">
+ 2012-06-08 17:49:15
+ </field>
+ <field name="trigger" rel="ManyToOneRel" to="forum.action">
+ 4
+ </field>
+ <field name="action" rel="OneToOneRel" to="forum.action">
+ 6
+ </field>
+ </object>
+ """
+
+ def import_threads(self):
+ """import thread objects"""
+ count = 0
+ for osqa_thread in self.get_objects_for_model('forum.question'):
+ count += 1
+ #todo: there must be code lated to set the commented values
+ thread = Thread(
+ title=osqa_thread.title,
+ tagnames=osqa_thread.tagnames,
+ view_count=osqa_thread.extra_count,
+ #favourite_count=thread.favourite_count,
+ #answer_count=thread.answer_count,
+ last_activity_at=osqa_thread.last_activity_at,
+ last_activity_by=self.get_imported_object_by_old_id(User, osqa_thread.last_activity_by),
+ language_code=django_settings.LANGUAGE_CODE,
+ #"closed" data is stored differently in OSQA
+ #closed_by=self.get_imported_object_by_old_id(User, thread.closed_by_id),
+ #closed=thread.closed,
+ #closed_at=thread.closed_at,
+ #close_reason=thread.close_reason,
+ #deleted=False,
+ approved=True, #no equivalent in OSQA
+ #must be done later, after importing answers
+ #answer_accepted_at=thread.answer_accepted_at,
+ added_at=osqa_thread.added_at,
+ )
+
+ #apply tags to threads
+ tag_names = thread.get_tag_names()
+ if tag_names:
+
+ tag_filter = Q(name__iexact=tag_names[0])
+ for tag_name in tag_names[1:]:
+ tag_filter |= Q(name__iexact=tag_name)
+ tags = Tag.objects.filter(tag_filter)
+
+ thread.tagnames = ' '.join([tag.name for tag in tags])
+
+ thread.save()
+ for tag in tags:
+ thread.tags.add(tag)
+ tag.used_count += 1
+ tag.save()
+
+ else:
+ thread.save()
+
+ self.log_action(osqa_thread, thread)
+
+ def import_posts(self, post_type, save_redirects=False):
+ """imports osqa Nodes to askbot Post objects"""
+ if save_redirects:
+ redirects_file = self.open_unique_file('question_redirects')
+
+ models_map = {
+ 'question': 'forum.question',
+ 'answer': 'forum.answer',
+ 'comment': 'forum.comment'
+ }
+
+ model_name = models_map[post_type]
+
+ for osqa_node in self.get_objects_for_model(model_name):
+ #we iterate through all nodes, but pick only the ones we need
+ if osqa_node.node_type != post_type:
+ continue
+
+ #cheat: do not import deleted content
+ if '(deleted)' in osqa_node.state_string:
+ continue
+
+ post = Post()
+
+ #this line is a bit risky, but should work if we import things in correct order
+ if osqa_node.parent:
+ post.parent = self.get_imported_object_by_old_id(Post, osqa_node.parent)
+ if post.parent is None:
+ continue #deleted parent
+ post.thread = post.parent.thread
+ else:
+ post.thread = self.get_imported_object_by_old_id(Thread, osqa_node.id)
+ if post.thread is None:
+ continue #deleted thread
+
+ post.post_type = osqa_node.node_type
+ post.added_at = osqa_node.added_at
+
+ if save_redirects:
+ slug = django_urlquote(slugify(osqa_node.title))
+ #todo: add i18n to the old url
+ old_url = '/questions/%d/%s/' % (osqa_node.id, slug)
+
+ post.author = self.get_imported_object_by_old_id(User, osqa_node.author)
+ #html will de added with the revisions
+ #post.html = HTMLParser().unescape(osqa_node.body)
+ post.summary = post.get_snippet()
+
+ #these don't have direct equivalent in the OSQA Node object
+ #post.deleted_by - deleted nodes are not imported
+ #post.locked_by
+ #post.last_edited_by
+
+ #these are to be set later with the real values
+ post.points = 0
+ post.vote_up_count = 0
+ post.vote_down_count = 0
+ post.offensive_flag_count = 0
+
+ post.save()
+
+ #mark accepted answer
+ if osqa_node.node_type == 'answer':
+ if '(accepted)' in osqa_node.state_string:
+ post.thread.accepted_answer = post
+ post.thread.save()
+
+
+ if save_redirects:
+ new_url = post.get_absolute_url()
+ self.write_redirect(old_url, new_url, redirects_file)
+
+ self.log_action_with_old_id(osqa_node.id, post)
+
+ if save_redirects:
+ redirects_file.close()
+
+ def import_post_revisions(self):
+ """Imports OSQA revisions to Askbot revisions"""
+ for osqa_revision in self.get_objects_for_model('forum.noderevision'):
+ post = self.get_imported_object_by_old_id(Post, osqa_revision.node)
+ if post is None:
+ continue #deleted post
+ user = self.get_imported_object_by_old_id(User, osqa_revision.author)
+ revision = PostRevision(
+ post=post,
+ author=user,
+ text=osqa_revision.body,
+ title=osqa_revision.title,
+ tagnames=osqa_revision.tagnames,
+ revised_at=osqa_revision.revised_at,
+ summary=osqa_revision.summary,
+ revision=osqa_revision.revision
+ )
+ post.text = osqa_revision.body
+ if osqa_revision == 1:
+ post.added_at = osqa_revision.revised_at
+ else:
+ post.last_edited_at = osqa_revision.revised_at
+ post.last_edited_by = user
+
+ post.parse_and_save(author=user)
+ revision.save()
+
+ def import_votes(self):
+ """Imports OSQA votes to Askbot votes"""
+ for osqa_vote in self.get_objects_for_model('forum.vote'):
+ post = self.get_imported_object_by_old_id(Post, osqa_vote.node)
+ if post is None:
+ continue #deleted post
+ user = self.get_imported_object_by_old_id(User, osqa_vote.user)
+ if osqa_vote.value > 0:
+ user.upvote(post, timestamp=osqa_vote.voted_at, force=True)
+ elif osqa_vote.value < 0:
+ user.downvote(post, timestamp=osqa_vote.voted_at, force=True)
+
+ def fix_answer_counts(self):
+ for thread in Thread.objects.all():
+ thread.answer_count = thread.get_answers().count()
+ thread.save()
+
+ def fix_comment_counts(self):
+ for post in Post.objects.filter(post_type__in=('question', 'answer')):
+ post.comment_count = Post.objects.filter(post_type='comment', parent=post).count()
+ post.save()
diff --git a/askbot/management/commands/askbot_add_xml_content.py b/askbot/management/commands/askbot_add_xml_content.py
new file mode 100644
index 00000000..307a0d76
--- /dev/null
+++ b/askbot/management/commands/askbot_add_xml_content.py
@@ -0,0 +1,558 @@
+from askbot.models import BadgeData
+from askbot.models import FavoriteQuestion
+from askbot.models import Group
+from askbot.models import ImportedObjectInfo
+from askbot.models import Post
+from askbot.models import Tag
+from askbot.models import Thread
+from askbot.models import User
+from askbot.management.commands.base import BaseImportXMLCommand
+from django.conf import settings as django_settings
+from django.contrib.auth.models import Group as AuthGroup
+from django.contrib.contenttypes.models import ContentType
+from django.db import transaction
+from django.db.models import Q
+
+if 'avatar' in django_settings.INSTALLED_APPS:
+ from avatar.models import Avatar
+
+def get_status_rank(status):
+ """returns integer rank of user account status,
+ the larger is the number the higher is the status"""
+ if len(status) != 1:
+ #default status - approved user
+ status = 'a'
+ try:
+ return 'bswamd'.index(status)
+ except ValueError:
+ return 0
+
+class Command(BaseImportXMLCommand):
+ help = 'Adds XML askbot data produced by the "dumpdata" command'
+
+ def handle_import(self):
+ self.read_content_types()
+
+ self.import_groups()
+ self.import_users()
+ #we don't import subscriptions
+ if 'avatar' in django_settings.INSTALLED_APPS:
+ self.import_avatars()
+
+ #we need this to link old user ids to
+ #new users' personal groups
+ #self.record_personal_groups()
+
+ self.import_user_logins()
+ self.import_tags()
+ self.import_marked_tags()
+
+ self.import_threads()
+ self.apply_groups_to_threads()
+
+ #model="askbot.posttogroup">
+ self.import_posts('question', save_redirects=True)
+ self.import_posts('answer')
+ self.import_posts('comment')
+ self.import_post_revisions()
+ self.apply_groups_to_posts()
+ self.apply_question_followers()
+ self.import_votes()
+
+ self.import_badges()
+ self.import_badge_awards()
+ self.delete_new_messages()
+ #we'll try to ignore importing this
+ #model="askbot.activity"
+
+ def log_personal_group(self, group):
+ info = ImportedObjectInfo()
+ info.old_id = group.id
+ info.new_id = int(group.name.split('_')[-1])
+ info.model = 'personal_group'
+ info.run = self.run
+ info.save()
+
+ def get_group_by_old_id(self, old_id):
+ normal_group = self.get_imported_object_by_old_id(AuthGroup, old_id)
+ if normal_group:
+ return Group.objects.get(group_ptr=normal_group)
+
+ log = ImportedObjectInfo.objects.get(
+ model='personal_group',
+ old_id=old_id,
+ run=self.run
+ )
+ old_user_id = log.new_id
+ new_user = self.get_imported_object_by_old_id(User, old_user_id)
+ return new_user.get_personal_group()
+
+ def read_content_types(self):
+ """reads content types from the data dump and makes
+ dictionary with keys of old content type ids and
+ values - active content type objects"""
+ ctypes_map = dict()
+ for old_ctype in self.get_objects_for_model('contenttypes.contenttype'):
+ try:
+ new_ctype = ContentType.objects.get(
+ app_label=old_ctype.app_label,
+ model=old_ctype.model
+ )
+ except ContentType.DoesNotExist:
+ continue
+ ctypes_map[old_ctype.id] = new_ctype
+
+ self.content_types_map = ctypes_map
+ """
+ <object pk="38" model="contenttypes.contenttype">
+ <field type="CharField" name="name">activity</field>
+ <field type="CharField" name="app_label">askbot</field>
+ <field type="CharField" name="model">activity</field>
+ </object>
+ """
+
+ def get_content_type_by_old_id(self, old_ctype_id):
+ return self.content_types_map[old_ctype_id]
+
+ @transaction.commit_manually
+ def import_groups(self):
+ """imports askbot group profiles"""
+
+ #redirects_file = self.open_unique_file('group_redirects')
+
+ #1) we import auth groups
+ for group in self.get_objects_for_model('auth.group'):
+
+ #old_url = group.get_absolute_url()
+ if group.name.startswith('_personal'):
+ #we don't import these groups, but log
+ #associations between old user ids and old personal
+ #group ids, because we create the personal groups
+ #anew and so need to have a connection
+ #old personal group id --> old user id --> new user id
+ # --> new pers. group id
+ self.log_personal_group(group)
+ continue
+ old_group_id = group.id
+ try:
+ group = AuthGroup.objects.get(name=group.name)
+ except AuthGroup.DoesNotExist:
+ group.id = None
+ group.save()
+
+ transaction.commit()
+
+ #new_url = group.get_absolute_url()
+
+ #if old_url != new_url:
+ # redirects_file.write('%s %s\n' % (old_url, new_url))
+
+ #we will later populate memberships only in these groups
+ self.log_action_with_old_id(old_group_id, group)
+
+ if transaction.is_dirty():
+ transaction.commit()
+
+ #redirects_file.close()
+
+ #2) we import askbot group profiles only for groups
+ for profile in self.get_objects_for_model('askbot.group'):
+ auth_group = self.get_imported_object_by_old_id(AuthGroup, profile.group_ptr_id)
+ if auth_group is None or auth_group.name.startswith('_personal'):
+ continue
+
+ #if profile for this group does not exist, then create new profile and save
+ try:
+ existing_profile = Group.objects.get(group_ptr__id=auth_group.id)
+ self.copy_string_parameter(profile, existing_profile, 'logo_url')
+ self.merge_words_parameter(profile, existing_profile, 'preapproved_emails')
+ self.merge_words_parameter(profile, existing_profile, 'preapproved_email_domains')
+ existing_profile.save()
+ except Group.DoesNotExist:
+ new_profile = Group.objects.create(
+ name=auth_group.name,
+ logo_url=profile.logo_url,
+ preapproved_emails=profile.preapproved_emails,
+ preapproved_email_domains=profile.preapproved_email_domains
+ )
+ new_profile.save()
+
+ transaction.commit()
+
+ if transaction.is_dirty():
+ transaction.commit()
+
+ def import_users(self):
+ redirects_file = self.open_unique_file('user_redirects')
+
+ model_path = str(User._meta)
+ dupes = 0
+ for from_user in self.get_objects_for_model('auth.user'):
+ log_info = dict()
+ log_info['notify_user'] = list()
+
+ old_url = from_user.get_absolute_url()
+
+ try:
+ to_user = User.objects.get(email=from_user.email)
+ dupes += 1
+ except User.DoesNotExist:
+ username = self.get_safe_username(from_user.username)
+ if username != from_user.username:
+ template = 'Your user name was changed from %s to %s'
+ log_info['notify_user'].append(template % (from_user.username, username))
+ to_user = User.objects.create_user(username, from_user.email)
+
+ #copy the data
+ if from_user.username != to_user.username:
+ names = (from_user.username, to_user.username)
+ log_info['notify_user'].append('Your user name has changed from %s to %s' % names)
+
+ self.copy_string_parameter(from_user, to_user, 'first_name')
+ self.copy_string_parameter(from_user, to_user, 'last_name')
+ self.copy_string_parameter(from_user, to_user, 'real_name')
+ self.copy_string_parameter(from_user, to_user, 'website')
+ self.copy_string_parameter(from_user, to_user, 'location')
+
+ to_user.country = from_user.country
+
+ self.copy_string_parameter(from_user, to_user, 'about')
+ self.copy_string_parameter(from_user, to_user, 'email_signature')
+ self.copy_string_parameter(from_user, to_user, 'twitter_access_token')
+ self.copy_string_parameter(from_user, to_user, 'twitter_handle')
+
+ self.merge_words_parameter(from_user, to_user, 'interesting_tags')
+ self.merge_words_parameter(from_user, to_user, 'ignored_tags')
+ self.merge_words_parameter(from_user, to_user, 'subscribed_tags')
+ self.merge_words_parameter(from_user, to_user, 'languages')
+
+ if to_user.password == '!' and from_user.password != '!':
+ to_user.password = from_user.password
+ self.copy_bool_parameter(from_user, to_user, 'is_staff')
+ self.copy_bool_parameter(from_user, to_user, 'is_active')
+ self.copy_bool_parameter(from_user, to_user, 'is_superuser')
+ self.copy_bool_parameter(from_user, to_user, 'is_fake', operator='and')
+ self.copy_bool_parameter(from_user, to_user, 'email_isvalid', operator='and')
+ self.copy_bool_parameter(from_user, to_user, 'show_country')
+ self.copy_bool_parameter(from_user, to_user, 'show_marked_tags')
+
+ self.copy_numeric_parameter(from_user, to_user, 'last_login')
+ self.copy_numeric_parameter(from_user, to_user, 'last_seen')
+ self.copy_numeric_parameter(from_user, to_user, 'date_joined', operator='min')
+ self.copy_numeric_parameter(from_user, to_user, 'email_tag_filter_strategy')
+ self.copy_numeric_parameter(from_user, to_user, 'display_tag_filter_strategy')
+ self.copy_numeric_parameter(
+ from_user,
+ to_user,
+ 'consecutive_days_visit_count',
+ operator='sum'
+ )
+ self.copy_numeric_parameter(from_user, to_user, 'social_sharing_mode')
+
+ #position of character in this string == rank of status
+ if get_status_rank(from_user.status) > get_status_rank(to_user.status):
+ to_user.status = from_user.status
+
+ to_user.save()
+
+ new_url = to_user.get_absolute_url()
+ self.write_redirect(old_url, new_url, redirects_file)
+
+ group_ids = self.get_m2m_ids_for_field(from_user, 'groups')
+ for group_id in group_ids:
+ #get group by old id,
+ #if group is private - skip,
+ #otherwise join this group
+ group = self.get_imported_object_by_old_id(Group, int(group_id))
+ if group is None or group.name.startswith('_personal'):
+ continue
+ #unfortunately, xml dump does not allow us to know of the membership status
+ #as m2m user -> group does not contain id of the m2m bridge relation, but
+ #only id of the group itself
+ to_user.join_group(group, force=True)
+
+ """
+ these were not imported:
+ <field type="CharField" name="email_key"><None></None></field>
+ <field type="PositiveIntegerField" name="reputation">1</field>
+ <field type="SmallIntegerField" name="gold">0</field>
+ <field type="SmallIntegerField" name="silver">0</field>
+ <field type="SmallIntegerField" name="bronze">0</field>
+ <field type="IntegerField" name="new_response_count">0</field>
+ <field type="IntegerField" name="seen_response_count">0</field>
+ """
+ self.log_action(from_user, to_user, extra_info=log_info)
+
+ redirects_file.close()
+
+ def import_avatars(self):
+ """imports user avatar, chooses later uploaded primary avatar"""
+ for avatar in self.get_objects_for_model('avatar.avatar'):
+ user = self.get_imported_object_by_old_id(User, avatar.user_id)
+
+ if avatar.primary:
+ #get other primary avatar and make the later one as primary
+ try:
+ existing_avatar = Avatar.objects.get(user=user, primary=True)
+ if existing_avatar.date_uploaded > avatar.date_uploaded:
+ avatar.primary = False
+ else:
+ existing_avatar.primary = False
+ existing_avatar.save()
+ except Avatar.DoesNotExist:
+ pass
+
+ avatar.user = user
+ avatar.id = None
+ avatar.save()
+ """
+ <object pk="9" model="avatar.avatar">
+ <field to="auth.user" name="user" rel="ManyToOneRel">33</field>
+ <field type="BooleanField" name="primary">True</field>
+ <field type="FileField" name="avatar">avatars/Valdir Barbosa/ValdirBarbosa.png</field>
+ <field type="DateTimeField" name="date_uploaded">2013-08-22T16:45:01.517315</field>
+ </object>
+ """
+
+ def import_marked_tags(self):
+ #model="askbot.markedtag">
+ for mark in self.get_objects_for_model('askbot.markedtag'):
+ tag = self.get_imported_object_by_old_id(Tag, mark.tag_id)
+ user = self.get_imported_object_by_old_id(User, mark.user_id)
+ user.mark_tags(tagnames=tag.name, reason=mark.reason, action='add')
+ """
+ <object pk="1" model="askbot.markedtag">
+ <field to="askbot.tag" name="tag" rel="ManyToOneRel">13</field>
+ <field to="auth.user" name="user" rel="ManyToOneRel">205</field>
+ <field type="CharField" name="reason">good</field>
+ </object>
+ """
+
+ @transaction.commit_manually
+ def import_user_logins(self):
+ #logins_soup = self.soup.find_all('object', {'model': 'django_authopenid.userassociation'})
+ #for login_info in self.get_objects_for_model('django_authopenid.userassociation'):
+ #for login_
+ for association in self.get_objects_for_model('django_authopenid.userassociation'):
+ #where possible, we should copy the login, but respecting the
+ #uniqueness constraints: ('user','provider_name'), ('openid_url', 'provider_name')
+ #1) get new user by old id
+ user = self.get_imported_object_by_old_id(User, association.user_id)
+ try:
+ association.id = None
+ association.user = user
+ association.save()
+ transaction.commit()
+ except:
+ transaction.rollback()
+
+ def import_tags(self):
+ """imports tag objects"""
+ for tag in self.get_objects_for_model('askbot.tag'):
+ old_tag_id = tag.id
+ try:
+ #try to get existing tag with this name
+ tag = Tag.objects.get(name__iexact=tag.name)
+ except Tag.DoesNotExist:
+ tag.id = None
+ tag.tag_wiki = None
+ tag.created_by = self.get_imported_object_by_old_id(User, tag.created_by_id)
+ tag.deleted_by = self.get_imported_object_by_old_id(User, tag.deleted_by_id)
+ tag.save()
+ self.log_action_with_old_id(old_tag_id, tag)
+
+ def import_threads(self):
+ """import thread objects"""
+ count = 0
+ for thread in self.get_objects_for_model('askbot.thread'):
+ count += 1
+ new_thread = Thread(
+ title=thread.title,
+ tagnames=thread.tagnames,
+ view_count=thread.view_count,
+ favourite_count=thread.favourite_count,
+ answer_count=thread.answer_count,
+ last_activity_at=thread.last_activity_at,
+ last_activity_by=self.get_imported_object_by_old_id(User, thread.last_activity_by_id),
+ language_code=thread.language_code,
+ closed_by=self.get_imported_object_by_old_id(User, thread.closed_by_id),
+ closed=thread.closed,
+ closed_at=thread.closed_at,
+ close_reason=thread.close_reason,
+ deleted=thread.deleted,
+ approved=thread.approved,
+ answer_accepted_at=thread.answer_accepted_at,
+ added_at=thread.added_at,
+ )
+
+ #apply tags to threads
+ tag_names = thread.get_tag_names()
+ if tag_names:
+
+ tag_filter = Q(name__iexact=tag_names[0])
+ for tag_name in tag_names[1:]:
+ tag_filter |= Q(name__iexact=tag_name)
+ tags = Tag.objects.filter(tag_filter)
+
+ new_thread.tagnames = ' '.join([tag.name for tag in tags])
+
+ new_thread.save()
+ for tag in tags:
+ new_thread.tags.add(tag)
+ tag.used_count += 1
+ tag.save()
+
+ else:
+ new_thread.save()
+
+ self.log_action(thread, new_thread)
+ """
+ these are not handled here
+ <object pk="155" model="askbot.thread">
+ <field to="askbot.post" name="accepted_answer" rel="ManyToOneRel"><None></None></field>
+ <field type="IntegerField" name="points">0</field>
+ <field to="auth.user" name="followed_by" rel="ManyToManyRel"></field>
+ </object>
+ """
+
+ def apply_question_followers(self):
+ """mark followed questions"""
+ for fave in self.get_objects_for_model('askbot.favoritequestion'):
+ #askbot.favoritequestion
+ user = self.get_imported_object_by_old_id(User, fave.user_id)
+ thread = self.get_imported_object_by_old_id(Thread, fave.thread_id)
+ user.toggle_favorite_question(thread._question_post(), timestamp=fave.added_at)
+ """
+ <object pk="1" model="askbot.favoritequestion">
+ <field to="askbot.thread" name="thread" rel="ManyToOneRel">8</field>
+ <field to="auth.user" name="user" rel="ManyToOneRel">32</field>
+ <field type="DateTimeField" name="added_at">2012-12-28T17:34:17.289056</field>
+ </object>
+ """
+
+ def apply_groups_to_threads(self):
+ for link in self.get_objects_for_model('askbot.threadtogroup'):
+ thread = self.get_imported_object_by_old_id(Thread, link.thread_id)
+ group = self.get_group_by_old_id(link.group_id)
+ thread.add_to_groups([group,], visibility=link.visibility)
+
+ def import_posts(self, post_type, save_redirects=False):
+ """imports posts of specific post_type"""
+ if save_redirects:
+ redirects_file = self.open_unique_file('question_redirects')
+ for post in self.get_objects_for_model('askbot.post'):
+ if post.post_type != post_type:
+ continue
+
+ #this line is a bit risky, but should work if we import things in correct order
+ post.parent = self.get_imported_object_by_old_id(Post, post.parent_id)
+
+ post.thread = self.get_imported_object_by_old_id(Thread, post.thread_id)
+
+ if save_redirects:
+ old_url = post.get_absolute_url(thread=post.thread)
+
+ post.author = self.get_imported_object_by_old_id(User, post.author_id)
+ post.deleted_by = self.get_imported_object_by_old_id(User, post.deleted_by_id)
+ post.locked_by = self.get_imported_object_by_old_id(User, post.locked_by_id)
+ post.last_edited_by = self.get_imported_object_by_old_id(User, post.last_edited_by_id)
+ post.points = 0
+ post.vote_up_count = 0
+ post.vote_down_count = 0
+ post.offensive_flag_count = 0
+
+ old_post_id = post.id
+ post.id = None
+ post.save()
+
+ if save_redirects:
+ new_url = post.get_absolute_url()
+ self.write_redirect(old_url, new_url, redirects_file)
+
+ self.log_action_with_old_id(old_post_id, post)
+
+ if save_redirects:
+ redirects_file.close()
+
+ """
+ these were not imported
+ votes
+ <field type="PositiveIntegerField" name="comment_count">0</field>
+ <field type="SmallIntegerField" name="offensive_flag_count">0</field>
+ """
+
+ def apply_groups_to_posts(self):
+ for link in self.get_objects_for_model('askbot.posttogroup'):
+ post = self.get_imported_object_by_old_id(Post, link.post_id)
+ group = self.get_group_by_old_id(link.group_id)
+ post.add_to_groups([group,])
+
+ def import_post_revisions(self):
+ for revision in self.get_objects_for_model('askbot.postrevision'):
+ revision.post = self.get_imported_object_by_old_id(Post, revision.post_id)
+ revision.author = self.get_imported_object_by_old_id(User, revision.author_id)
+ revision.approved_by = self.get_imported_object_by_old_id(User, revision.approved_by_id)
+ revision.id = None
+ revision.save()
+
+ def import_badges(self):
+ """imports badgedata objects"""
+ for badge in self.get_objects_for_model('askbot.badgedata'):
+ #here we need to make sure that we don't create duplicate badges
+ old_badge_id = badge.id
+ try:
+ new_badge = BadgeData.objects.get(slug=badge.slug)
+ except BadgeData.DoesNotExist:
+ new_badge = badge
+ new_badge.id = None
+ new_badge.awarded_count = 0 #we will re-award this, restart count
+ new_badge.save()
+
+ self.log_action_with_old_id(old_badge_id, new_badge)
+ """
+ <object pk="36" model="askbot.badgedata">
+ <field type="SlugField" name="slug">taxonomist</field>
+ <field type="PositiveIntegerField" name="awarded_count">9</field>
+ </object>
+ """
+
+ def import_badge_awards(self):
+ for award in self.get_objects_for_model('askbot.award'):
+ award.user = self.get_imported_object_by_old_id(User, award.user_id)
+ badge = self.get_imported_object_by_old_id(BadgeData, award.badge_id)
+ #if multiple or user does not have this badge, then award
+ if badge.is_multiple() or (not award.user.has_badge(badge)):
+ award.badge = badge
+ content_type = self.get_content_type_by_old_id(award.content_type_id)
+ obj_class = content_type.model_class()
+ award.object_id = self.get_imported_object_id_by_old_id(obj_class, award.object_id)
+ award.content_type = content_type
+ award.id = None
+ award.save()
+ """
+ <object pk="1" model="askbot.award">
+ <field to="auth.user" name="user" rel="ManyToOneRel">2</field>
+ <field to="askbot.badgedata" name="badge" rel="ManyToOneRel">10</field>
+ <field to="contenttypes.contenttype" name="content_type" rel="ManyToOneRel">30</field>
+ <field type="PositiveIntegerField" name="object_id">1</field>
+ <field type="DateTimeField" name="awarded_at">2012-10-22T18:09:13.527031</field>
+ <field type="BooleanField" name="notified">False</field>
+ </object>
+ """
+
+ def import_votes(self):
+ for vote in self.get_objects_for_model('askbot.vote'):
+ post = self.get_imported_object_by_old_id(Post, vote.voted_post_id)
+ user = self.get_imported_object_by_old_id(User, vote.user_id)
+ if vote.vote == 1:
+ user.upvote(post, timestamp=vote.voted_at)
+ else:
+ user.downvote(post, timestamp=vote.voted_at)
+ """
+ <object pk="1" model="askbot.vote">
+ <field to="auth.user" name="user" rel="ManyToOneRel">8</field>
+ <field to="askbot.post" name="voted_post" rel="ManyToOneRel">20</field>
+ <field type="SmallIntegerField" name="vote">1</field>
+ <field type="DateTimeField" name="voted_at">2012-12-26T19:10:08.334818</field>
+ </object>
+ """
diff --git a/askbot/management/commands/base.py b/askbot/management/commands/base.py
new file mode 100644
index 00000000..dce02e20
--- /dev/null
+++ b/askbot/management/commands/base.py
@@ -0,0 +1,240 @@
+from askbot.models import Message
+from askbot.models import User
+from askbot.models import ImportedObjectInfo
+from askbot.models import ImportRun
+from django.core.management.base import BaseCommand, CommandError
+from django.conf import settings as django_settings
+from bs4 import BeautifulSoup
+from collections import defaultdict
+from django.core import serializers
+from django.utils.encoding import smart_str
+from django.utils.translation import activate as activate_language
+from optparse import make_option
+import os
+import sys
+from tempfile import mkstemp
+
+class BaseImportXMLCommand(BaseCommand):
+ help = 'Base command for adding XML data from other forums to Askbot'
+
+ option_list = BaseCommand.option_list + (
+ make_option('--redirect-format',
+ action = 'store',
+ dest = 'redirect_format',
+ default = 'none',
+ help = 'Format for the redirect files (apache|nginx|none)'
+ ),
+ )
+
+ def handle(self, *args, **kwargs):
+
+ activate_language(django_settings.LANGUAGE_CODE)
+
+ #init the redirects file format table
+ self.redirect_format = self.get_redirect_format(kwargs['redirect_format'])
+
+ self.setup_run()
+ self.read_xml_file(args[0])
+
+ self.remember_message_ids()
+ self.handle_import()
+ self.delete_new_messages()
+
+ def handle_import(self):
+ """this method should contain the actual work of importing data
+
+ If necessary, create redirect files using methods
+ redirects_file = self.open_unique_file('user_redirects')
+ self.write_redirect(old_url, new_url, redirects_file)
+ redirects_file.close()
+ where old_url and new_url are urls of the corresponding objects
+ before and after importation
+ """
+ raise NotImplementedError('Implement this method to import data')
+
+
+ def get_redirect_format(self, format_setting):
+ format_table = {
+ 'nginx': 'rewrite ^%s$ %s break;\n',
+ 'apache': 'Redirect permanent %s %s\n',
+ }
+ format_table = defaultdict(lambda: '%s %s\n', format_table)
+ return format_table[format_setting]
+
+ def setup_run(self):
+ """remembers the run information,
+ for the logging purposes
+ """
+ command = ' '.join(sys.argv)
+ run = ImportRun.objects.create(command=command)
+ self.run = run
+
+ def read_xml_file(self, filename):
+ """reads xml data int BeautifulSoup instance"""
+ if not os.path.isfile(filename):
+ raise CommandError('File %s does not exist') % filename
+ xml = open(filename, 'r').read()
+ self.soup = BeautifulSoup(xml, ['lxml', 'xml'])
+
+ def remember_message_ids(self):
+ """remembers messages ids of existing messages - we use these
+ to delete any messages added automatically during the import"""
+ self.message_ids = list(Message.objects.values_list('id', flat=True))
+
+ def log_action_with_old_id(self, from_object_id, to_object, extra_info=None):
+ info = ImportedObjectInfo()
+ info.old_id = from_object_id
+ info.new_id = to_object.id
+ info.model = str(to_object._meta)
+ info.run = self.run
+ info.extra_info = extra_info or dict()
+ info.save()
+
+ def log_action(self, from_object, to_object, extra_info=None):
+ self.log_action_with_old_id(from_object.id, to_object, extra_info=extra_info)
+
+ def get_imported_object_id_by_old_id(self, model_class, old_id):
+ """Returts id of imported object by old id"""
+ if old_id is None:
+ return None
+ try:
+ log = ImportedObjectInfo.objects.get(
+ model=str(model_class._meta),
+ old_id=old_id,
+ run=self.run
+ )
+ return log.new_id
+ except ImportedObjectInfo.DoesNotExist:
+ return None
+
+ def get_imported_object_by_old_id(self, model_class, old_id):
+ """Returns new imported object by id of corresponding old object"""
+ new_id = self.get_imported_object_id_by_old_id(model_class, old_id)
+ if new_id:
+ return model_class.objects.get(id=new_id)
+ return None
+
+ def get_objects_for_model(self, model_name):
+ """returns iterator of objects from the django
+ xml dump by name"""
+ object_soup = self.soup.find_all('object', {'model': model_name})
+ for datum in object_soup:
+ yield self.get_deserialized_object(datum)
+
+ def delete_new_messages(self):
+ """deletes any messages that were added by askbot during the import process"""
+ Message.objects.exclude(id__in=self.message_ids).delete()
+
+ def open_unique_file(self, name_hint):
+ """return a file using name_hint as the hint
+ for the file name, if file with that name exists,
+ create a unique file name containing hint as part of
+ the name"""
+ if os.path.exists(name_hint):
+ info = mkstemp(dir=os.getcwd(), prefix=name_hint + '_')
+ name_hint = info[1]
+ print 'saving file: %s' % name_hint
+ return open(name_hint, 'w')
+
+ def write_redirect(self, from_url, to_url, redirects_file):
+ """writes redirect clause to a file in format
+ chosen earlier in the `handle` function"""
+ if from_url != to_url:
+ redirects_file.write(self.redirect_format % (from_url, to_url))
+
+ def get_safe_username(self, username):
+ """get unique username similar to `username`
+ to avoid the uniqueness clash"""
+ existing_names = User.objects.filter(
+ username__istartswith=username
+ ).values_list('username', flat=True)
+
+ if len(existing_names) == 0:
+ return username
+
+ num = 1
+ while True:
+ new_name = username + str(num)
+ if new_name in existing_names:
+ num += 1
+ else:
+ return new_name
+
+ def get_deserialized_object(self, xml_soup):
+ """returns deserialized django object for xml soup with one item"""
+ item_xml = smart_str(xml_soup)
+ #below call assumes a single item within
+ obj = serializers.deserialize('xml', item_xml).next().object
+ obj._source_xml = item_xml
+ return obj
+
+ def get_m2m_ids_for_field(self, obj, field_name):
+ xml = obj._source_xml
+ soup = BeautifulSoup(xml)
+ ids = list()
+ for field in soup.findAll('field', attrs={'name': field_name}):
+ objs = field.findAll('object')
+ for obj in objs:
+ ids.append(obj.attrs['pk'])
+ return ids
+
+ def copy_string_parameter(self, from_obj, to_obj, from_param_name, to_param_name=None):
+ """copy value of string parameter from old to new object"""
+
+ to_param_name = to_param_name or from_param_name
+
+ from_par = getattr(from_obj, from_param_name)
+ to_par = getattr(to_obj, to_param_name)
+ if from_par is None and to_par is None:
+ return
+ from_par = from_par or ''
+ to_par = to_par or ''
+ if from_par.strip() == '' and to_par.strip() != '':
+ setattr(to_obj, to_param_name, from_par)
+
+ def copy_bool_parameter(self, from_obj, to_obj, from_param_name, to_param_name=None, operator='or'):
+ """copy value of boolean parameter from old to new object"""
+
+ to_param_name = to_param_name or from_param_name
+
+ from_par = getattr(from_obj, from_param_name)
+ to_par = getattr(to_obj, to_param_name)
+ if operator == 'or':
+ value = from_par or to_par
+ elif operator == 'and':
+ value = from_par and to_par
+ else:
+ raise ValueError('unsupported operator "%s"' % operator)
+ setattr(to_obj, to_param_name, value)
+
+ def merge_words_parameter(self, from_obj, to_obj, from_param_name, to_param_name=None):
+ """merge unique words from the two objects and assign to the new object"""
+
+ to_param_name = to_param_name or from_param_name
+
+ from_words = getattr(from_obj, from_param_name).split()
+ to_words = getattr(to_obj, to_param_name).split()
+ value = ' '.join(set(from_words)|set(to_words))
+ setattr(to_obj, to_param_name, value)
+
+ def copy_numeric_parameter(self, from_obj, to_obj, from_param_name, to_param_name=None, operator='max'):
+
+ to_param_name = to_param_name or from_param_name
+
+ from_par = getattr(from_obj, from_param_name)
+ to_par = getattr(to_obj, to_param_name)
+
+ if from_par is None:
+ return to_par
+ elif to_par is None:
+ return from_par
+
+ if operator == 'max':
+ value = max(from_par, to_par)
+ elif operator == 'min':
+ value = min(from_par, to_par)
+ elif operator == 'sum':
+ value = from_par + to_par
+ else:
+ raise ValueError('unsupported operator "%s"' % operator)
+ setattr(to_obj, to_param_name, value)
diff --git a/askbot/management/commands/dump_forum.py b/askbot/management/commands/dump_forum.py
deleted file mode 100644
index 0bead908..00000000
--- a/askbot/management/commands/dump_forum.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import sys
-import optparse
-from django.core import management
-from django.core.management.base import BaseCommand
-from askbot.utils import console
-
-class Command(BaseCommand):
- help = """Dumps askbot forum data into the file for the later use with "load_forum".
-The extension ".json" will be added automatically."""
-
- option_list = BaseCommand.option_list + (
- optparse.make_option('--dump-name',
- type = 'str',
- dest = 'dump_file'
- ),
- )
- def handle(self, *args, **options):
- dump_file = console.open_new_file(
- 'Please enter file name (no extension): ',
- hint = options.get('dump_file', None),
- extension = '.json'
- )
- print ("Saving file %s ..." % dump_file.name).encode('utf-8')
- stdout_orig = sys.stdout
- try:
- sys.stdout = dump_file
- management.call_command(
- 'dumpdata',
- #exclude = ('contenttypes',),
- indent = 4
- )
- sys.stdout = stdout_orig
- print "Done."
- except KeyboardInterrupt:
- sys.stdout = stdout_orig
- print "\nCanceled."
diff --git a/askbot/management/commands/export_osqa.py b/askbot/management/commands/export_osqa.py
new file mode 100644
index 00000000..5dd6eb5d
--- /dev/null
+++ b/askbot/management/commands/export_osqa.py
@@ -0,0 +1,215 @@
+from django.core.exceptions import ImproperlyConfigured
+from django.core.management.base import BaseCommand, CommandError
+from django.core.serializers.xml_serializer import Serializer
+from django.db import connections, router, DEFAULT_DB_ALIAS
+from django.utils.datastructures import SortedDict
+from StringIO import StringIO
+
+from optparse import make_option
+
+class XMLExportSerializer(Serializer):
+ def serialize(self, queryset, **options):
+ """
+ Serialize a queryset.
+ Copy-paste from the base serializer with a minor difference
+ commented below
+ """
+ self.options = options
+
+ self.stream = options.pop("stream", StringIO())
+ self.selected_fields = options.pop("fields", None)
+ self.use_natural_keys = options.pop("use_natural_keys", False)
+
+ self.start_serialization()
+ for obj in queryset:
+ self.start_object(obj)
+ #the line below is the only one that was changed
+ for field in obj._meta.fields:
+ if field.serialize:
+ if field.rel is None:
+ if self.selected_fields is None or field.attname in self.selected_fields:
+ self.handle_field(obj, field)
+ else:
+ if self.selected_fields is None or field.attname[:-3] in self.selected_fields:
+ self.handle_fk_field(obj, field)
+ for field in obj._meta.many_to_many:
+ if field.serialize:
+ if self.selected_fields is None or field.attname in self.selected_fields:
+ self.handle_m2m_field(obj, field)
+ self.end_object(obj)
+ self.end_serialization()
+ return self.getvalue()
+
+
+class Command(BaseCommand):
+ option_list = BaseCommand.option_list + (
+ make_option('--indent', default=4, dest='indent', type='int',
+ help='Specifies the indent level to use when pretty-printing output'),
+ make_option('--database', action='store', dest='database',
+ default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load '
+ 'fixtures into. Defaults to the "default" database.'),
+ make_option('-e', '--exclude', dest='exclude',action='append', default=['sessions', 'contenttypes'],
+ help='An appname or appname.ModelName to exclude (use multiple --exclude to exclude multiple apps/models).'),
+ make_option('-n', '--natural', action='store_true', dest='use_natural_keys', default=False,
+ help='Use natural keys if they are available.'),
+ make_option('-a', '--all', action='store_true', dest='use_base_manager', default=False,
+ help="Use Django's base manager to dump all models stored in the database, including those that would otherwise be filtered or modified by a custom manager."),
+ )
+ help = ("Output the contents of the OSQA database as XML fixture of the given "
+ "format (using each model's default manager unless --all is "
+ "specified).")
+ args = '[appname appname.ModelName ...]'
+
+ def handle(self, *app_labels, **options):
+ from django.db.models import get_app, get_apps, get_models, get_model
+
+ indent = options.get('indent', None)
+ using = options.get('database', DEFAULT_DB_ALIAS)
+ connection = connections[using]
+ excludes = options.get('exclude',[])
+ show_traceback = options.get('traceback', False)
+ use_natural_keys = options.get('use_natural_keys', False)
+ use_base_manager = options.get('use_base_manager', False)
+
+ excluded_apps = set()
+ excluded_models = set()
+ for exclude in excludes:
+ if '.' in exclude:
+ app_label, model_name = exclude.split('.', 1)
+ model_obj = get_model(app_label, model_name)
+ if not model_obj:
+ raise CommandError('Unknown model in excludes: %s' % exclude)
+ excluded_models.add(model_obj)
+ else:
+ try:
+ app_obj = get_app(exclude)
+ excluded_apps.add(app_obj)
+ except ImproperlyConfigured:
+ raise CommandError('Unknown app in excludes: %s' % exclude)
+
+ if len(app_labels) == 0:
+ app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps)
+ else:
+ app_list = SortedDict()
+ for label in app_labels:
+ try:
+ app_label, model_label = label.split('.')
+ try:
+ app = get_app(app_label)
+ except ImproperlyConfigured:
+ raise CommandError("Unknown application: %s" % app_label)
+ if app in excluded_apps:
+ continue
+ model = get_model(app_label, model_label)
+ if model is None:
+ raise CommandError("Unknown model: %s.%s" % (app_label, model_label))
+
+ if app in app_list.keys():
+ if app_list[app] and model not in app_list[app]:
+ app_list[app].append(model)
+ else:
+ app_list[app] = [model]
+ except ValueError:
+ # This is just an app - no model qualifier
+ app_label = label
+ try:
+ app = get_app(app_label)
+ except ImproperlyConfigured:
+ raise CommandError("Unknown application: %s" % app_label)
+ if app in excluded_apps:
+ continue
+ app_list[app] = None
+
+ # Now collate the objects to be serialized.
+ objects = []
+ for model in sort_dependencies(app_list.items()):
+ if model in excluded_models:
+ continue
+ if not model._meta.proxy and router.allow_syncdb(using, model):
+ if use_base_manager:
+ objects.extend(model._base_manager.using(using).all())
+ else:
+ objects.extend(model._default_manager.using(using).all())
+
+ try:
+ serializer = XMLExportSerializer()
+ return serializer.serialize(objects, indent=indent, use_natural_keys=use_natural_keys)
+ except Exception, e:
+ if show_traceback:
+ raise
+ raise CommandError("Unable to serialize database: %s" % e)
+
+def sort_dependencies(app_list):
+ """Sort a list of app,modellist pairs into a single list of models.
+
+ The single list of models is sorted so that any model with a natural key
+ is serialized before a normal model, and any model with a natural key
+ dependency has it's dependencies serialized first.
+ """
+ from django.db.models import get_model, get_models
+ # Process the list of models, and get the list of dependencies
+ model_dependencies = []
+ models = set()
+ for app, model_list in app_list:
+ if model_list is None:
+ model_list = get_models(app)
+
+ for model in model_list:
+ models.add(model)
+ # Add any explicitly defined dependencies
+ if hasattr(model, 'natural_key'):
+ deps = getattr(model.natural_key, 'dependencies', [])
+ if deps:
+ deps = [get_model(*d.split('.')) for d in deps]
+ else:
+ deps = []
+
+ # Now add a dependency for any FK or M2M relation with
+ # a model that defines a natural key
+ for field in model._meta.fields:
+ if hasattr(field.rel, 'to'):
+ rel_model = field.rel.to
+ if hasattr(rel_model, 'natural_key'):
+ deps.append(rel_model)
+ for field in model._meta.many_to_many:
+ rel_model = field.rel.to
+ if hasattr(rel_model, 'natural_key'):
+ deps.append(rel_model)
+ model_dependencies.append((model, deps))
+
+ model_dependencies.reverse()
+ # Now sort the models to ensure that dependencies are met. This
+ # is done by repeatedly iterating over the input list of models.
+ # If all the dependencies of a given model are in the final list,
+ # that model is promoted to the end of the final list. This process
+ # continues until the input list is empty, or we do a full iteration
+ # over the input models without promoting a model to the final list.
+ # If we do a full iteration without a promotion, that means there are
+ # circular dependencies in the list.
+ model_list = []
+ while model_dependencies:
+ skipped = []
+ changed = False
+ while model_dependencies:
+ model, deps = model_dependencies.pop()
+
+ # If all of the models in the dependency list are either already
+ # on the final model list, or not on the original serialization list,
+ # then we've found another model with all it's dependencies satisfied.
+ found = True
+ for candidate in ((d not in models or d in model_list) for d in deps):
+ if not candidate:
+ found = False
+ if found:
+ model_list.append(model)
+ changed = True
+ else:
+ skipped.append((model, deps))
+ if not changed:
+ raise CommandError("Can't resolve dependencies for %s in serialized app list." %
+ ', '.join('%s.%s' % (model._meta.app_label, model._meta.object_name)
+ for model, deps in sorted(skipped, key=lambda obj: obj[0].__name__))
+ )
+ model_dependencies = skipped
+
+ return model_list
diff --git a/askbot/management/commands/find_bodyless_questions.py b/askbot/management/commands/find_bodyless_questions.py
index 75312620..b137ba54 100644
--- a/askbot/management/commands/find_bodyless_questions.py
+++ b/askbot/management/commands/find_bodyless_questions.py
@@ -2,19 +2,28 @@
that do not have revisions by creating a fake initial revision
based on the content stored in the post itself
"""
-from django.core.management.base import NoArgsCommand
+from django.core.management.base import BaseCommand
from askbot import models
from askbot import const
from askbot.utils.console import ProgressBar
+from optparse import make_option
def print_results(items):
template = 'id=%d, title=%s'
for thread in items:
print template % (thread.id, thread.title.encode('utf8'))
-class Command(NoArgsCommand):
+class Command(BaseCommand):
"""Command class for "fix_bodyless_questions"
"""
+ option_list = BaseCommand.option_list + (
+ make_option('--delete',
+ action='store_true',
+ dest='delete',
+ default=False,
+ help='Delete poll instead of closing it',
+ ),
+ )
def handle(self, *arguments, **options):
"""function that handles the command job
"""
@@ -39,6 +48,12 @@ class Command(NoArgsCommand):
if len(bodyless):
print '\nQuestions without body text:'
print_results(bodyless)
+ if options['delete']:
+ for thread in bodyless:
+ thread.delete()
if len(multi_body):
print '\nQuestions with >1 instances of body text'
print_results(multi_body)
+ if options['delete']:
+ for thread in multi_body:
+ thread.delete()
diff --git a/askbot/management/commands/fix_comment_counts.py b/askbot/management/commands/fix_comment_counts.py
new file mode 100644
index 00000000..3a7f16f8
--- /dev/null
+++ b/askbot/management/commands/fix_comment_counts.py
@@ -0,0 +1,34 @@
+"""Management command for fixing comment counts in questions and answers
+
+Bug in converting answer to comment stored wrong comment count in target
+question or answer, and in some cases that makes it imposible for users to view
+all the comments.
+"""
+
+from django.core.management.base import NoArgsCommand
+from django.db.models import signals, Count, F
+from askbot.models import Post
+from askbot.utils.console import ProgressBar
+
+class Command(NoArgsCommand):
+
+ help = "Fixes the wrong comment counts on questions and answers, "\
+ "where answers have been converted to comments.\n"
+
+ def remove_save_signals(self):
+ """Prevent possible unvanted side effects of saving
+ """
+ signals.pre_save.receivers = []
+ signals.post_save.receivers = []
+
+ def handle(self, *arguments, **options):
+ """Function that handles the command job
+ """
+ self.remove_save_signals()
+ posts = Post.objects.annotate(real_comment_count=Count('comments')
+ ).exclude(real_comment_count=F('comment_count'))
+ count = posts.count()
+ message = 'Fixing comment counts'
+ for post in ProgressBar(posts.iterator(), count, message):
+ post.comment_count = post.comments.count();
+ post.save()
diff --git a/askbot/management/commands/fix_question_tags.py b/askbot/management/commands/fix_question_tags.py
index ed1ee6fb..3cb696b0 100644
--- a/askbot/management/commands/fix_question_tags.py
+++ b/askbot/management/commands/fix_question_tags.py
@@ -1,11 +1,31 @@
+import re
import sys
from django.core.management.base import NoArgsCommand
+from django.conf import settings as django_settings
from django.db import transaction
+from django.utils import translation
+from askbot import const
from askbot import models
from askbot import forms
from askbot.utils import console
+from askbot.utils.slug import slugify_camelcase
from askbot.models import signals
from askbot.conf import settings as askbot_settings
+from askbot.management.commands.rename_tags import get_admin
+
+def get_valid_tag_name(tag):
+ """Returns valid version of the tag name.
+ If necessary, lowercases the tag.
+ Strips the forbidden first characters in the tag.
+ """
+ name = tag.name
+ if askbot_settings.FORCE_LOWERCASE_TAGS:
+ #name = slugify_camelcase(name)
+ name = name.lower()
+ #if tag name starts with forbidden character, chop off that character
+ #until no more forbidden chars are at the beginning
+ first_char_regex = re.compile('^%s+' % const.TAG_FORBIDDEN_FIRST_CHARS)
+ return first_char_regex.sub('', name)
class Command(NoArgsCommand):
def handle_noargs(self, **options):
@@ -13,58 +33,115 @@ class Command(NoArgsCommand):
self.run_command()
signals.set_all_db_signal_receivers(signal_data)
+ def retag_threads(self, from_tags, to_tag):
+ """finds threads matching the `from_tags`
+ removes the `from_tags` from them and applies the
+ to_tags"""
+ threads = models.Thread.objects.filter(tags__in=from_tags)
+ from_tag_names = [tag.name for tag in from_tags]
+ for thread in threads:
+ tagnames = set(thread.get_tag_names())
+ tagnames.difference_update(from_tag_names)
+ tagnames.add(to_tag.name)
+ self.admin.retag_question(
+ question=thread._question_post(),
+ tags=' '.join(tagnames)
+ )
+
+
@transaction.commit_manually
def run_command(self):
"""method that runs the actual command"""
#go through tags and find character case duplicates and eliminate them
+ translation.activate(django_settings.LANGUAGE_CODE)
tagnames = models.Tag.objects.values_list('name', flat = True)
+ self.admin = get_admin()
+
+ #1) first we go through all tags and
+ #either fix or delete illegal tags
+ found_count = 0
+
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
- print line,
- 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()
+ try:
+ tag = models.Tag.objects.get(name=name)
+ except models.Tag.DoesNotExist:
+ #tag with this name was already deleted,
+ #because it was an invalid duplicate version
+ #of other valid tag
+ continue
+
+
+ fixed_name = get_valid_tag_name(tag)
+
+ #if fixed name is empty after cleaning, delete the tag
+ if fixed_name == '':
+ print 'Deleting invalid tag: %s' % name
+ tag.delete()
+ found_count += 1
+ continue
+
+ if fixed_name != name:
+ print 'Renaming tag: %s -> %s' % (name, fixed_name)
+
+ #if tag name changed, see if there is a duplicate
+ #with the same name, in which case we re-assign questions
+ #with the current tag to that other duplicate
+ #then delete the current tag as no longer used
+ if fixed_name != name:
+ try:
+ duplicate_tag = models.Tag.objects.get(name=fixed_name)
+ except models.Tag.DoesNotExist:
+ pass
+ self.retag_threads([tag], duplicate_tag)
+ tag.delete()
+ found_count += 1
+ continue
+
+
+ #if there are case variant dupes, we assign questions
+ #from the case variants to the current tag and
+ #delete the case variant tags
+ dupes = models.Tag.objects.filter(
+ name__iexact=fixed_name
+ ).exclude(pk=tag.id)
+
+ dupes_count = dupes.count()
+ if dupes_count:
+ self.retag_threads(dupes, tag)
+ dupes.delete()
+ found_count += dupes_count
+
+ if tag.name != fixed_name:
+ tag.name = fixed_name
+ tag.save()
+
transaction.commit()
- #go through questions and fix tag records on each
+ #2) go through questions and fix tag records on each
+ # and recalculate all the denormalised tag names on threads
threads = models.Thread.objects.all()
checked_count = 0
- found_count = 0
total_count = threads.count()
- print "Searching for questions with inconsistent tag records:",
+ print "Searching for questions with inconsistent copies of tag records:",
for thread in threads:
+ #make sure that denormalized tag set is the same as normalized
+ #we just add both the tags together and try to apply them
+ #to the question
tags = thread.tags.all()
denorm_tag_set = set(thread.get_tag_names())
norm_tag_set = set(thread.tags.values_list('name', flat=True))
- if norm_tag_set != denorm_tag_set:
-
- if thread.last_edited_by:
- user = thread.last_edited_by
- timestamp = thread.last_edited_at
- else:
- user = thread.author
- timestamp = thread.added_at
-
- tagnames = forms.TagNamesField().clean(thread.tagnames)
- thread.update_tags(
- tagnames = tagnames,
- user = user,
- timestamp = timestamp
+ if norm_tag_set != denorm_tag_set:
+ denorm_tag_set.update(norm_tag_set)
+ cleaned_tag_set = set(
+ models.Tag.objects.filter(
+ name__in=denorm_tag_set
+ ).values_list('name', flat=True)
+ )
+ self.admin.retag_question(
+ question=thread._question_post(),
+ tags=' '.join(cleaned_tag_set)
)
- thread.tagnames = tagnames
- thread.save()
- found_count += 1
transaction.commit()
checked_count += 1
diff --git a/askbot/management/commands/generate_post_snippets.py b/askbot/management/commands/generate_post_snippets.py
new file mode 100644
index 00000000..688450bf
--- /dev/null
+++ b/askbot/management/commands/generate_post_snippets.py
@@ -0,0 +1,18 @@
+from django.core.management.base import NoArgsCommand
+from django.db import transaction
+from askbot.models import Post
+from askbot.utils.console import ProgressBar
+
+class Command(NoArgsCommand):
+ help = 'Generates snippets for all posts'
+ @transaction.commit_manually
+ def handle_noargs(self, *args, **kwargs):
+ posts = Post.objects.all()
+ count = posts.count()
+ message = 'Building post snippets'
+ for post in ProgressBar(posts.iterator(), count, message):
+ if hasattr(post, 'summary'):
+ post.summary = post.get_snippet()
+ post.save()
+ transaction.commit()
+ transaction.commit()
diff --git a/askbot/management/commands/init_postgresql_full_text_search.py b/askbot/management/commands/init_postgresql_full_text_search.py
index 3cf4b03c..cc6a7263 100644
--- a/askbot/management/commands/init_postgresql_full_text_search.py
+++ b/askbot/management/commands/init_postgresql_full_text_search.py
@@ -11,7 +11,7 @@ class Command(NoArgsCommand):
askbot.get_install_directory(),
'search',
'postgresql',
- 'thread_and_post_models_01162012.plsql'
+ 'thread_and_post_models_10032013.plsql'
)
setup_full_text_search(script_path)
@@ -19,6 +19,6 @@ class Command(NoArgsCommand):
askbot.get_install_directory(),
'search',
'postgresql',
- 'user_profile_search_16102012.plsql'
+ 'user_profile_search_02262013.plsql'
)
setup_full_text_search(script_path)
diff --git a/askbot/management/commands/load_forum.py b/askbot/management/commands/load_forum.py
deleted file mode 100644
index 65ac410f..00000000
--- a/askbot/management/commands/load_forum.py
+++ /dev/null
@@ -1,16 +0,0 @@
-from django.core import management
-from django.db.models import signals
-from django.contrib.contenttypes.models import ContentType
-from django.core.management.base import BaseCommand
-from askbot import models
-
-class Command(BaseCommand):
- args = '<data file>'
- help = 'Loads askbot forum data from the dump file obtained with command "dump_forum"'
- def handle(self, *args, **options):
- #need to remove badge data b/c they are aslo in the dump
- models.BadgeData.objects.all().delete()
- ContentType.objects.all().delete()
- #turn off the post_save signal so than Activity can be copied
- signals.post_save.receivers = []
- management.call_command('loaddata', args[0])
diff --git a/askbot/management/commands/merge_users.py b/askbot/management/commands/merge_users.py
index 189b74bb..a5ce25cd 100644
--- a/askbot/management/commands/merge_users.py
+++ b/askbot/management/commands/merge_users.py
@@ -1,4 +1,5 @@
from django.core.management.base import CommandError, BaseCommand
+from django.db import transaction
from askbot.models import User
# TODO: this command is broken - doesn't take into account UNIQUE constraints
@@ -13,32 +14,40 @@ class MergeUsersBaseCommand(BaseCommand):
args = '<from_user_id> <to_user_id>'
help = 'Merge an account and all information from a <user_id> to a <user_id>, deleting the <from_user>'
+ @transaction.commit_manually
def handle(self, *arguments, **options):
-
self.parse_arguments(*arguments)
-
+
for rel in User._meta.get_all_related_objects():
+ sid = transaction.savepoint()
try:
self.process_field(rel.model, rel.field.name)
+ transaction.savepoint_commit(sid)
except Exception, error:
self.stdout.write((u'Warning: %s\n' % error).encode('utf-8'))
+ transaction.savepoint_rollback(sid)
+ transaction.commit()
for rel in User._meta.get_all_related_many_to_many_objects():
+ sid = transaction.savepoint()
try:
self.process_m2m_field(rel.model, rel.field.name)
+ transaction.savepoint_commit(sid)
except Exception, error:
self.stdout.write((u'Warning: %s\n' % error).encode('utf-8'))
+ transaction.savepoint_rollback(sid)
+ transaction.commit()
self.process_custom_user_fields()
self.cleanup()
def cleanup(self):
- raise Exception, 'Not implemented'
+ raise Exception, 'Not implemented'
def process_custom_user_fields(self):
- """Put app specific logic here."""
- raise Exception, 'Not implemented'
+ """Put app specific logic here."""
+ raise Exception, 'Not implemented'
def parse_arguments(self, *arguments):
if len(arguments) != 2:
@@ -66,19 +75,19 @@ class MergeUsersBaseCommand(BaseCommand):
class Command(MergeUsersBaseCommand):
- def process_custom_user_fields(self):
- self.to_user.reputation += self.from_user.reputation - 1
- self.to_user.gold += self.from_user.gold
- self.to_user.silver += self.from_user.silver
- self.to_user.bronze += self.from_user.bronze
-
- if self.from_user.last_seen > self.to_user.last_seen:
- self.to_user.last_seen = self.from_user.last_seen
+ def process_custom_user_fields(self):
+ self.to_user.reputation += self.from_user.reputation - 1
+ self.to_user.gold += self.from_user.gold
+ self.to_user.silver += self.from_user.silver
+ self.to_user.bronze += self.from_user.bronze
- if self.from_user.date_joined < self.to_user.date_joined:
- self.to_user.date_joined = self.from_user.date_joined
+ if self.from_user.last_seen > self.to_user.last_seen:
+ self.to_user.last_seen = self.from_user.last_seen
+
+ if self.from_user.date_joined < self.to_user.date_joined:
+ self.to_user.date_joined = self.from_user.date_joined
- def cleanup(self):
- self.to_user.save()
- self.from_user.delete()
+ def cleanup(self):
+ self.to_user.save()
+ self.from_user.delete()
diff --git a/askbot/management/commands/rename_tags.py b/askbot/management/commands/rename_tags.py
index bd15d685..b3eaf70d 100644
--- a/askbot/management/commands/rename_tags.py
+++ b/askbot/management/commands/rename_tags.py
@@ -4,8 +4,10 @@ retagged
"""
import sys
from optparse import make_option
+from django.conf import settings as django_settings
from django.core import management
from django.core.management.base import BaseCommand, CommandError
+from django.utils import translation
from askbot import api, models
from askbot.utils import console
@@ -94,6 +96,7 @@ ask you to confirm your action before making changes.
The data of tag id's is then delegated to the command "rename_tag_id"
"""
+ translation.activate(django_settings.LANGUAGE_CODE)
if options['from'] is None:
raise CommandError('the --from argument is required')
if options['to'] is None:
@@ -124,7 +127,7 @@ Also, you can try command "rename_tag_id"
""" % tag_name
raise CommandError(error_message)
except models.Tag.MultipleObjectsReturned:
- raise CommandError(u'found more than one tag named %s' % from_tag_name)
+ raise CommandError(u'found more than one tag named %s' % tag_name)
admin = get_admin(seed_user_id = options['user_id'])
diff --git a/askbot/management/commands/rename_tags_id.py b/askbot/management/commands/rename_tags_id.py
index 1da22868..45e4a76a 100644
--- a/askbot/management/commands/rename_tags_id.py
+++ b/askbot/management/commands/rename_tags_id.py
@@ -8,8 +8,10 @@ also, corresponding questions are retagged
import re
import sys
from optparse import make_option
+from django.conf import settings as django_settings
from django.core.management.base import BaseCommand, CommandError
from django.db import transaction
+from django.utils import translation
from askbot import const, models
from askbot.utils import console
from askbot.management.commands.rename_tags import get_admin
@@ -84,6 +86,7 @@ rename_tags, but using tag id's
def handle(self, *args, **options):
"""command handle function. retrieves tags by id
"""
+ translation.activate(django_settings.LANGUAGE_CODE)
try:
from_tag_ids = parse_tag_ids(options['from'])
to_tag_ids = parse_tag_ids(options['to'])
@@ -161,6 +164,7 @@ or repost a bug, if that does not help"""
tags = u' '.join(tag_names),
#silent = True #do we want to timestamp activity on question
)
+ question.invalidate_cached_thread_content_fragment()
i += 1
sys.stdout.write('%6.2f%%' % (100*float(i)/float(question_count)))
sys.stdout.write('\b'*7)
diff --git a/askbot/management/commands/send_accept_answer_reminders.py b/askbot/management/commands/send_accept_answer_reminders.py
index 22ae311d..70baac62 100644
--- a/askbot/management/commands/send_accept_answer_reminders.py
+++ b/askbot/management/commands/send_accept_answer_reminders.py
@@ -57,15 +57,7 @@ class Command(NoArgsCommand):
if question_count == 0:
continue
- subject_line = _(
- 'Accept the best answer for %(question_count)d of your questions'
- ) % {'question_count': question_count}
-
- #todo - make a template for these
- if question_count == 1:
- reminder_phrase = _('Please accept the best answer for this question:')
- else:
- reminder_phrase = _('Please accept the best answer for these questions:')
+ reminder_phrase = _('Please select the best responses to:')
data = {
'site_url': site_url(''),#here we need only the domain name
@@ -76,6 +68,7 @@ class Command(NoArgsCommand):
template = get_template('email/accept_answer_reminder.html')
body_text = template.render(Context(data))#todo: set lang
+ subject_line = askbot_settings.WORDS_ACCEPT_BEST_ANSWERS_FOR_YOUR_QUESTIONS
if DEBUG_THIS_COMMAND:
print "User: %s<br>\nSubject:%s<br>\nText: %s<br>\n" % \
(user.email, subject_line, body_text)
diff --git a/askbot/management/commands/send_email_alerts.py b/askbot/management/commands/send_email_alerts.py
index e1783316..a9162079 100644
--- a/askbot/management/commands/send_email_alerts.py
+++ b/askbot/management/commands/send_email_alerts.py
@@ -433,8 +433,8 @@ class Command(NoArgsCommand):
question_count = len(q_list.keys())
subject_line = ungettext(
- '%(question_count)d updated question about %(topics)s',
- '%(question_count)d updated questions about %(topics)s',
+ '%(question_count)d update about %(topics)s',
+ '%(question_count)d updates about %(topics)s',
question_count
) % {
'question_count': question_count,
diff --git a/askbot/management/commands/send_unanswered_question_reminders.py b/askbot/management/commands/send_unanswered_question_reminders.py
index 42ce5119..c428881d 100644
--- a/askbot/management/commands/send_unanswered_question_reminders.py
+++ b/askbot/management/commands/send_unanswered_question_reminders.py
@@ -64,11 +64,13 @@ class Command(NoArgsCommand):
tag_summary = Thread.objects.get_tag_summary_from_threads(threads)
subject_line = ungettext(
- '%(question_count)d unanswered question about %(topics)s',
- '%(question_count)d unanswered questions about %(topics)s',
+ '%(question_count)d %(unanswered_question)s about %(topics)s',
+ '%(question_count)d %(unanswered_questions)s about %(topics)s',
question_count
) % {
'question_count': question_count,
+ 'unanswered_question': askbot_settings.WORDS_UNANSWERED_QUESTION_SINGULAR,
+ 'unanswered_questions': askbot_settings.WORDS_UNANSWERED_QUESTION_PLURAL,
'topics': tag_summary
}
diff --git a/askbot/media/jquery-openid/jquery.openid.js b/askbot/media/jquery-openid/jquery.openid.js
index c8e925a3..20807065 100644
--- a/askbot/media/jquery-openid/jquery.openid.js
+++ b/askbot/media/jquery-openid/jquery.openid.js
@@ -310,7 +310,7 @@ $.fn.authenticator = function() {
var setup_password_login_or_change = function(provider_name){
var token_name = extra_token_name[provider_name]
var password_action_input = $('input[name=password_action]');
- if (userIsAuthenticated === true){
+ if (userIsAuthenticated === true && askbot['settings']['useLdapForPasswordLogin'] == false){
var password_button = $('input[name=change_password]');
var submit_action = submit_change_password;
if (provider_name === 'local'){
@@ -334,8 +334,7 @@ $.fn.authenticator = function() {
password_action_input.val('change_password');
var focus_input = $('#id_new_password');
var submittable_input = $('#id_new_password_retyped');
- }
- else{
+ } else {
$('#password-heading>span').html(token_name);
var password_button = $('input[name=login_with_password]');
var submit_action = submit_login_with_password;
diff --git a/askbot/media/js/live_search.js b/askbot/media/js/live_search.js
index f6eecff1..e833059f 100644
--- a/askbot/media/js/live_search.js
+++ b/askbot/media/js/live_search.js
@@ -162,6 +162,7 @@ SearchDropMenu.prototype.showWaitIcon = function() {
this._footer.hide();
this._element.addClass('empty');
}
+ this._element.addClass('waiting');
};
SearchDropMenu.prototype.hideWaitIcon = function() {
@@ -170,6 +171,7 @@ SearchDropMenu.prototype.hideWaitIcon = function() {
this._footer.show();
this._element.removeClass('empty');
}
+ this._element.removeClass('waiting');
};
SearchDropMenu.prototype.hideHeader = function() {
@@ -896,7 +898,7 @@ FullTextSearch.prototype.decorate = function(element) {
dropMenu.setAskHandler(this.makeAskHandler());
dropMenu.setAskButtonEnabled(this._askButtonEnabled);
this._dropMenu = dropMenu;
- element.parent().after(this._dropMenu.getElement());
+ element.parent().append(this._dropMenu.getElement());
$(element).click(function(e) { return false });
$(document).click(function() { dropMenu.reset(); });
diff --git a/askbot/media/js/post.js b/askbot/media/js/post.js
index 18031482..d077ce9e 100644
--- a/askbot/media/js/post.js
+++ b/askbot/media/js/post.js
@@ -83,35 +83,6 @@ function setupFormValidation(form, validationRules, validationMessages, onSubmit
});
}
-/**
- * generic tag cleaning function, settings
- * are from askbot live settings and askbot.const
- */
-var cleanTag = function(tag_name, settings) {
- var tag_regex = new RegExp(settings['tag_regex']);
- if (tag_regex.test(tag_name) === false) {
- throw settings['messages']['wrong_chars']
- }
-
- var max_length = settings['max_tag_length'];
- if (tag_name.length > max_length) {
- throw interpolate(
- ngettext(
- 'must be shorter than %(max_chars)s character',
- 'must be shorter than %(max_chars)s characters',
- max_length
- ),
- {'max_chars': max_length },
- true
- );
- }
- if (settings['force_lowercase_tags']) {
- return tag_name.toLowerCase();
- } else {
- return tag_name;
- }
-};
-
var validateTagLength = function(value){
var tags = getUniqueWords(value);
var are_tags_ok = true;
@@ -171,11 +142,15 @@ var CPValidator = function() {
required: " " + gettext('enter your question'),
minlength: interpolate(
ngettext(
- 'question must have > %s character',
- 'question must have > %s characters',
+ '%(question)s must have > %(length)s character',
+ '%(question)s must have > %(length)s characters',
askbot['settings']['minTitleLength']
),
- [askbot['settings']['minTitleLength'], ]
+ {
+ 'question': askbot['messages']['questionSingular'],
+ 'length': askbot['settings']['minTitleLength']
+ },
+ true
)
}
};
@@ -193,11 +168,15 @@ var CPValidator = function() {
required: " " + gettext('content cannot be empty'),
minlength: interpolate(
ngettext(
- 'answer must be > %s character',
- 'answer must be > %s characters',
+ '%(answer)s must be > %(length)s character',
+ '%(answer)s must be > %(length)s characters',
askbot['settings']['minAnswerBodyLength']
),
- [askbot['settings']['minAnswerBodyLength'], ]
+ {
+ 'answer': askbot['messages']['answerSingular'],
+ 'length': askbot['settings']['minAnswerBodyLength']
+ },
+ true
)
},
}
@@ -546,12 +525,17 @@ var Vote = function(){
var questionSubscribeSidebar= 'question-subscribe-sidebar';
var acceptAnonymousMessage = gettext('insufficient privilege');
- var acceptOwnAnswerMessage = gettext('cannot pick own answer as best');
var pleaseLogin = " <a href='" + askbot['urls']['user_signin'] + ">"
+ gettext('please login') + "</a>";
- var favoriteAnonymousMessage = gettext('anonymous users cannot follow questions') + pleaseLogin;
+ var tmpMsg = interpolate(
+ gettext('anonymous users cannot %(follow_questions)s'),
+ {'follow_questions': askbot['messages']['followQuestions']},
+ true
+ );
+ var favoriteAnonymousMessage = tmpMsg + pleaseLogin;
+ //todo: this below is probably not used
var subscribeAnonymousMessage = gettext('anonymous users cannot subscribe to questions') + pleaseLogin;
var voteAnonymousMessage = gettext('anonymous users cannot vote') + pleaseLogin;
//there were a couple of more messages...
@@ -617,17 +601,17 @@ var Vote = function(){
};
var getOffensiveQuestionFlag = function(){
- var offensiveQuestionFlag = '.question-card span[id^="'+ offensiveIdPrefixQuestionFlag +'"]';
+ var offensiveQuestionFlag = 'div.question span[id^="'+ offensiveIdPrefixQuestionFlag +'"]';
return $(offensiveQuestionFlag);
};
var getRemoveOffensiveQuestionFlag = function(){
- var removeOffensiveQuestionFlag = '.question-card span[id^="'+ removeOffensiveIdPrefixQuestionFlag +'"]';
+ var removeOffensiveQuestionFlag = 'div.question span[id^="'+ removeOffensiveIdPrefixQuestionFlag +'"]';
return $(removeOffensiveQuestionFlag);
};
var getRemoveAllOffensiveQuestionFlag = function(){
- var removeAllOffensiveQuestionFlag = '.question-card span[id^="'+ removeAllOffensiveIdPrefixQuestionFlag +'"]';
+ var removeAllOffensiveQuestionFlag = 'div.question span[id^="'+ removeAllOffensiveIdPrefixQuestionFlag +'"]';
return $(removeAllOffensiveQuestionFlag);
};
@@ -795,7 +779,12 @@ var Vote = function(){
showMessage(object, acceptAnonymousMessage);
}
else if(data.allowed == "-1"){
- showMessage(object, acceptOwnAnswerMessage);
+ var message = interpolate(
+ gettext('sorry, you cannot %(accept_own_answer)s'),
+ {'accept_own_answer': askbot['messages']['acceptOwnAnswer']},
+ true
+ );
+ showMessage(object, message);
}
else if(data.status == "1"){
$("#"+answerContainerIdPrefix+postId).removeClass("accepted-answer");
@@ -2403,7 +2392,10 @@ PostCommentsWidget.prototype.getActivateHandler = function(){
}
else {
//if user can't post, we tell him something and refuse
- if (askbot['data']['userIsAuthenticated']) {
+ if (askbot['settings']['readOnlyModeEnabled'] === true) {
+ var message = askbot['messages']['readOnlyMessage'];
+ showMessage(button, message, 'after');
+ } else if (askbot['data']['userIsAuthenticated']) {
me.startNewComment();
} else {
var message = gettext('please sign in or register to post comments');
@@ -2514,7 +2506,7 @@ var socialSharing = function(){
URL = window.location.href;
var urlBits = URL.split('/');
URL = urlBits.slice(0, -2).join('/') + '/';
- TEXT = encodeURIComponent($('h1 > a').html());
+ TEXT = encodeURIComponent($('h1 > a').text());
var hashtag = encodeURIComponent(
askbot['settings']['sharingSuffixText']
);
@@ -3388,9 +3380,55 @@ var TagEditor = function() {
WrappedElement.call(this);
this._has_hot_backspace = false;
this._settings = JSON.parse(askbot['settings']['tag_editor']);
+ /*
+ tags: {
+ required: askbot['settings']['tagsAreRequired'],
+ maxlength: askbot['settings']['maxTagsPerPost'] * askbot['settings']['maxTagLength'],
+ limit_tag_count: true,
+ limit_tag_length: true
+ },
+ tags: {
+ required: " " + gettext('tags cannot be empty'),
+ maxlength: askbot['messages']['tagLimits'],
+ limit_tag_count: askbot['messages']['maxTagsPerPost'],
+ limit_tag_length: askbot['messages']['maxTagLength']
+ },
+ */
};
inherits(TagEditor, WrappedElement);
+/* retagger function
+ var doRetag = function(){
+ $.ajax({
+ type: "POST",
+ url: retagUrl,//todo add this url to askbot['urls']
+ dataType: "json",
+ data: { tags: getUniqueWords(tagInput.val()).join(' ') },
+ success: function(json) {
+ if (json['success'] === true){
+ new_tags = getUniqueWords(json['new_tags']);
+ oldTagsHtml = '';
+ cancelRetag();
+ drawNewTags(new_tags.join(' '));
+ if (json['message']) {
+ notify.show(json['message']);
+ }
+ }
+ else {
+ cancelRetag();
+ showMessage(tagsDiv, json['message']);
+ }
+ },
+ error: function(xhr, textStatus, errorThrown) {
+ showMessage(tagsDiv, gettext('sorry, something is not right here'));
+ cancelRetag();
+ }
+ });
+ return false;
+ }
+*/
+
+
TagEditor.prototype.getSelectedTags = function() {
return $.trim(this._hidden_tags_input.val()).split(/\s+/);
};
diff --git a/askbot/media/js/tag_selector.js b/askbot/media/js/tag_selector.js
index dfc8a29a..c905ab86 100644
--- a/askbot/media/js/tag_selector.js
+++ b/askbot/media/js/tag_selector.js
@@ -274,10 +274,16 @@ function pickedTags(){
});
}
+ var tagSettings = JSON.parse(askbot['settings']['tag_editor']);
var clean_tagnames = [];
$.each(tagnames, function(idx, tagname){
if (!(tagname in to_target)){
- clean_tagnames.push(tagname);
+ try {
+ cleanTag(tagname, tagSettings);
+ clean_tagnames.push(tagname);
+ } catch (e) {
+ alert(e);
+ }
}
});
diff --git a/askbot/media/js/user.js b/askbot/media/js/user.js
index de5d0804..90f35f2f 100644
--- a/askbot/media/js/user.js
+++ b/askbot/media/js/user.js
@@ -1076,6 +1076,7 @@ inherits(UserQuestionsPaginator, Paginator);
UserQuestionsPaginator.prototype.renderPage = function(data) {
$('.users-questions').html(data['questions']);
+ $('.timeago').timeago();
};
UserQuestionsPaginator.prototype.getPageDataUrl = function(pageNo) {
@@ -1095,6 +1096,7 @@ inherits(UserAnswersPaginator, Paginator);
UserAnswersPaginator.prototype.renderPage = function(data) {
$('.users-answers').html(data['html']);
+ $('.timeago').timeago();
};
UserAnswersPaginator.prototype.getPageDataUrl = function() {
diff --git a/askbot/media/js/utils.js b/askbot/media/js/utils.js
index 7e7b2935..64932ccd 100644
--- a/askbot/media/js/utils.js
+++ b/askbot/media/js/utils.js
@@ -44,6 +44,41 @@ var getNewUniqueInt = function() {
return num;
};
+/**
+ * generic tag cleaning function, settings
+ * are from askbot live settings and askbot.const
+ */
+var cleanTag = function(tag_name, settings) {
+ var tag_regex = new RegExp(settings['tag_regex']);
+ if (tag_regex.test(tag_name) === false) {
+ var firstChar = tag_name.substring(0, 1);
+ if (settings['tag_forbidden_first_chars'].indexOf(firstChar) > -1) {
+ throw settings['messages']['wrong_first_char'];
+ } else {
+ throw settings['messages']['wrong_chars'];
+ }
+ }
+
+ var max_length = settings['max_tag_length'];
+ if (tag_name.length > max_length) {
+ throw interpolate(
+ ngettext(
+ 'must be shorter than %(max_chars)s character',
+ 'must be shorter than %(max_chars)s characters',
+ max_length
+ ),
+ {'max_chars': max_length },
+ true
+ );
+ }
+ if (settings['force_lowercase_tags']) {
+ return tag_name.toLowerCase();
+ } else {
+ return tag_name;
+ }
+};
+
+
var getSingletonController = function(controllerClass, name) {
askbot['controllers'] = askbot['controllers'] || {};
var controller = askbot['controllers'][name];
@@ -2750,10 +2785,9 @@ Tag.prototype.createDom = function(){
}
this._inner_element.addClass('tag tag-right');
this._inner_element.attr('rel', 'tag');
- if (this._title === null){
- this.setTitle(
- interpolate(gettext("see questions tagged '%s'"), [this.getName()])
- );
+ if (this._title === null) {
+ var name = this.getName();
+ this.setTitle(interpolate(gettext("see questions tagged '%s'"), [name,]));
}
this._inner_element.attr('title', this._title);
this._inner_element.html(this.getDisplayTagName());
diff --git a/askbot/media/js/wmd/wmd.js b/askbot/media/js/wmd/wmd.js
index 6f7505d0..f84cd6e4 100644
--- a/askbot/media/js/wmd/wmd.js
+++ b/askbot/media/js/wmd/wmd.js
@@ -122,14 +122,15 @@ Attacklab.wmdBase = function(){
// Adds a listener callback to a DOM element which is fired on a specified
// event.
util.addEvent = function(elem, event, listener){
- if (elem && elem.attachEvent) {
- // IE only. The "on" is mandatory.
- elem.attachEvent("on" + event, listener);
- }
- else {
- // Other browsers.
- elem.addEventListener(event, listener, false);
- }
+ if (elem) {
+ if (elem.attachEvent) {
+ // IE only. The "on" is mandatory.
+ elem.attachEvent("on" + event, listener);
+ } else {
+ // Other browsers.
+ elem.addEventListener(event, listener, false);
+ }
+ }
};
diff --git a/askbot/media/style/style.css b/askbot/media/style/style.css
index fb1cf98b..0f0119f3 100644
--- a/askbot/media/style/style.css
+++ b/askbot/media/style/style.css
@@ -198,6 +198,9 @@ h1 {
/* ----- Extra space above for messages ----- */
body.user-messages {
margin-top: 2.4em;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
}
/* ----- Custom positions ----- */
.left {
@@ -460,11 +463,21 @@ body.user-messages {
border-top: #fcfcfc 1px solid;
margin-bottom: 10px;
font-family: 'Open Sans Condensed', Arial, sans-serif;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+}
+#secondaryHeader td {
+ padding: 0;
+}
+#secondaryHeader td.search-bar {
+ padding: 0 32px 0 15px;
+ position: relative;
}
#homeButton {
border-right: #afaf9e 1px solid;
background: -6px -36px url(../images/sprites.png) no-repeat;
- height: 55px;
+ height: 54px;
width: 43px;
display: block;
float: left;
@@ -473,8 +486,7 @@ body.user-messages {
background: -51px -36px url(../images/sprites.png) no-repeat;
}
.scope-selector {
- display: block;
- float: left;
+ display: inline-block;
font-size: 20px;
color: #7a7a6b;
height: 55px;
@@ -482,7 +494,7 @@ body.user-messages {
margin-left: 16px;
}
.scope-selector.on {
- background: url(../images/scopearrow.png) no-repeat center bottom;
+ background: url(../images/scopearrow.png) no-repeat center 41px;
}
.scope-selector.ask-message {
font-size: 24px;
@@ -505,12 +517,12 @@ body.user-messages {
#searchBar {
/* Main search form , check widgets/search_bar.html */
- display: block;
- background-color: #fff;
border: 1px solid #c9c9b5;
+ background: white;
height: 41px;
z-index: 1000;
position: relative;
+ width: 100%;
/* the guts are absolute-positioned */
}
@@ -570,17 +582,20 @@ body.user-messages {
}
.search-drop-menu {
box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
background: whitesmoke;
- border: 1px solid #c9c9b5;
border-top: none;
+ top: 42px;
margin: 0;
- position: relative;
+ outline: 1px solid #dadad4;
+ position: absolute;
z-index: 10000;
}
.search-drop-menu ul {
list-style: none;
overflow: auto;
- padding: 0 0 10px 0;
+ padding: 0;
margin: 0;
position: relative;
width: 100%;
@@ -598,12 +613,13 @@ body.user-messages {
.search-drop-menu ul li.selected a {
color: whitesmoke;
}
-.search-drop-menu ul.empty {
- margin-bottom: 0;
-}
.search-drop-menu .footer {
text-align: center;
- padding: 9px 0 10px 0;
+ margin: 0 0 1px 0;
+ padding: 4px 0 10px 0;
+}
+.search-drop-menu.empty .footer {
+ padding-top: 9px;
}
.search-drop-menu.empty ul {
padding: 1px;
@@ -623,7 +639,7 @@ input[type="submit"].searchBtn {
border: #FFF 1px solid;
line-height: 22px;
text-align: center;
- margin: 1px 0 0 0;
+ margin: 0;
width: 48px;
background: -98px -37px url(../images/sprites.png) no-repeat;
border-radius: 0;
@@ -652,13 +668,21 @@ input[type="submit"].searchBtn {
color: white;
height: 0;
z-index: 0;
+ position: absolute;
+ left: -1000px;
+ /* hide away */
+
+}
+.ask-page .search-drop-menu {
+ top: 37px;
}
.ask-page .search-drop-menu.empty {
border: none;
- padding: 0;
+ outline: none;
+ padding: 0 !important;
}
.ask-page .search-drop-menu.empty ul {
- padding: 0;
+ padding: 0 !important;
}
input[type="submit"].searchBtn:hover {
background-image: none;
@@ -801,73 +825,23 @@ form.ajax-file-upload img.spinner {
font-size: 20px;
height: 42px;
line-height: 44px;
- margin: 6px 0 0 0;
+ margin: -1px 0 0 0;
text-transform: uppercase;
width: 200px;
/* to match width of sidebar */
}
-/*
- Put the secondary navigation together:
- 1) raise the search bar by 55px
- 2) add padding to fit the buttons
-*/
-#searchBar {
- margin: 0 228px 0 327px;
- width: auto;
- margin-top: -49px;
- padding: 0 49px 0 8px;
-}
-/* line up drop menu the same way as the search bar */
.search-drop-menu {
- margin: 0 228px 0 327px;
- width: auto;
+ width: 100%;
}
.ask-page .search-drop-menu,
body.anon.ask-page .search-drop-menu {
- margin: -9px 0 10px;
+ padding: 5px 10px 6px 0;
}
#scopeNav {
- height: 41px;
- float: left;
- width: 280px;
-}
-.scopes-True-True-False #searchBar,
-.scopes-True-True-False .search-drop-menu {
- margin-left: 228px;
-}
-.scopes-True-True-False #scopeNav {
- width: 180px;
-}
-.scopes-True-False-True #searchBar,
-.scopes-True-False-True .search-drop-menu {
- margin-left: 203px;
-}
-.scopes-True-False-True #scopeNav {
- width: 150px;
-}
-.scopes-False-True-True #searchBar,
-.scopes-False-True-True .search-drop-menu {
- margin-left: 286px;
-}
-.scopes-False-True-True #scopeNav {
- width: 238px;
-}
-.scopes-True-False-False #searchBar,
-.scopes-False-True-False #searchBar,
-.scopes-False-False-True #searchBar,
-.scopes-False-False-False #searchBar,
-.scopes-True-False-False .search-drop-menu,
-.scopes-False-True-False .search-drop-menu,
-.scopes-False-False-True .search-drop-menu,
-.scopes-False-False-False .search-drop-menu {
- margin-left: 52px;
-}
-.scopes-True-False-False #scopeNav,
-.scopes-False-True-False #scopeNav,
-.scopes-False-False-True #scopeNav,
-.scopes-False-False-False #scopeNav {
- width: 0;
+ height: 54px;
+ display: inline-block;
+ white-space: nowrap;
}
/* ----- Content layout, check two_column_body.html or one_column_body.html ----- */
#ContentLeft {
@@ -1078,7 +1052,7 @@ body.anon.ask-page .search-drop-menu {
-webkit-box-shadow: 1px 1px 3px #999999;
-moz-box-shadow: 1px 1px 3px #999999;
box-shadow: 1px 1px 3px #999999;
- padding: 7px 10px 1px 10px;
+ padding: 7px 10px 9px 0;
margin-bottom: 10px;
width: 100%;
}
@@ -1199,7 +1173,8 @@ body.anon.ask-page .search-drop-menu {
ul#searchTags {
margin-left: 10px;
float: right;
- padding-top: 2px;
+ padding: 8px 6px 0px 6px;
+ min-width: 43px;
}
.search-tips {
font-size: 16px;
@@ -1381,23 +1356,25 @@ ul#searchTags {
.paginator .page a,
.paginator .page a:visited,
.paginator .curr {
- padding: .25em;
- margin: 0em .25em;
+ padding: 0 .25em;
+ margin: 0em .15em 0 0;
}
.paginator .curr {
- background-color: #8ebcc7;
+ /*background-color: #8ebcc7;*/
+
color: #fff;
font-weight: bold;
}
.paginator .curr a {
background: #8ebcc7;
color: white;
- padding: 0;
+ /*padding: 0;*/
+
}
.paginator .curr.page a:hover {
background: #8ebcc7;
color: white;
- padding: 0;
+ padding: 0 0.25em;
}
.paginator .page a:hover,
.paginator .prev a:hover,
@@ -1505,7 +1482,7 @@ ul#related-tags li {
background: #f3f6f6;
border: #fff 1px solid ;
border-top: #fff 2px solid;
- outline: #cfdbdb 1px solid;
+ outline: #cfdbdb 1px solid !important;
/* .box-shadow(0px,1px,0px,#88a8a8);*/
display: block;
@@ -1667,6 +1644,7 @@ ul#related-tags li {
padding: 4px 0 0 0;
margin-top: 0px;
width: 100%;
+ position: relative;
}
#askFormBar p {
margin: 0 0 5px 0;
@@ -2151,7 +2129,7 @@ ul#related-tags li {
float: right;
font-size: 9px;
font-family: Arial;
- line-height: 13px;
+ line-height: 12px;
margin: 0px 0px 5px 5px;
padding: 4px;
width: 166px;
@@ -3586,6 +3564,14 @@ a.offensive {
.message p {
margin-bottom: 0px;
}
+.system-messages {
+ color: red;
+ background: yellow;
+ font-size: 21px;
+ font-weight: bold;
+ line-height: 25px;
+ padding: 0 5px;
+}
p.space-above {
margin-top: 10px;
}
@@ -3920,7 +3906,7 @@ p.signup_p {
}
.user-card .avatar-box {
float: left;
- margin: 3px 6px 0 0;
+ margin: 0px 6px 0 2px;
}
.user-card .info {
height: 32px;
@@ -4066,6 +4052,9 @@ a.primary-group-name {
color: #990E08;
font-weight: bold;
}
+.post-update-info .user-info {
+ margin-top: -2px;
+}
.users-page .wmd-prompt-dialog {
background: #ccc;
}
@@ -4201,30 +4190,34 @@ textarea.tipped-input {
}
/* tag editor */
.tag-editor {
- height: 64px;
- border: #ccc 3px solid;
- padding-left: 8px;
+ height: 32px;
+ border: #cce6ec 3px solid;
+ padding-left: 6px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.tag-editor ul.tags {
margin: 0;
}
.tag-editor ul.tags li {
- margin-top: 8px;
+ margin-top: 6px;
height: 13px;
}
.tag-editor input.new-tags-input,
.tag-editor input.new-tags-input:focus {
border: none;
- font-size: 15px;
+ box-shadow: none;
+ font-size: 14px;
font-color: #707070;
height: 16px;
line-height: 16px;
- margin-top: 9px;
+ margin: 9px 0 0 -6px;
-webkit-box-shadow: none;
/* undo bootstrap glow */
-moz-box-shadow: none;
- box-shadow: none;
+ padding: 0 0 0 6px;
}
/* fixes for bootstrap */
.caret {
@@ -4578,17 +4571,26 @@ td.setting-input textarea {
.short-summary:first-child {
padding-top: 0;
}
- #searchBar,
- body.anon #searchBar {
- margin: -49px 8px 0 52px;
- }
- .search-drop-menu,
- body.anon .search-drop-menu {
- margin: 0 8px 0 52px;
- }
.short-summary {
width: 100%;
}
+ #secondaryHeader td.search-bar {
+ padding: 0 6px;
+ }
+}
+@media screen and (max-width: 540px) {
+ .question-page .post-controls {
+ float: left;
+ margin-left: -8px;
+ padding-left: 0;
+ text-align: left;
+ }
+ .question-page .post-controls .question-close {
+ display: none;
+ }
+ .question-page div.comments.empty {
+ margin-top: 0;
+ }
}
@media screen and (max-width: 480px) {
.openid-signin h1,
@@ -4609,6 +4611,15 @@ td.setting-input textarea {
width: 100%;
}
}
+@media screen and (max-width: 380px) {
+ .wmd-button-bar .wmd-hr-button,
+ .wmd-button-bar .wmd-heading-button {
+ display: none;
+ }
+ .editor-status {
+ margin-right: 0;
+ }
+}
@media screen and (max-width: 338px) {
#scopeNav {
display: none;
@@ -4624,6 +4635,9 @@ td.setting-input textarea {
width: 100%;
margin: 6px 0;
}
+ .question-page .post-controls .offensive-flag {
+ display: none;
+ }
}
/* language-specific fixes */
body.lang-zh .box .inputs #interestingTagInput,
@@ -4694,39 +4708,12 @@ body.lang-zh-tw.question-page a.submit,
body.lang-zh_TW.question-page a.submit {
line-height: 30px !important;
}
-body.lang-zh .scopes-True-True-False #searchBar,
-body.lang-zh_CN .scopes-True-True-False #searchBar,
-body.lang-zh-cn .scopes-True-True-False #searchBar,
-body.lang-zh-tw .scopes-True-True-False #searchBar,
-body.lang-zh_TW .scopes-True-True-False #searchBar,
-body.lang-zh .scopes-True-True-False .search-drop-menu,
-body.lang-zh_CN .scopes-True-True-False .search-drop-menu,
-body.lang-zh-cn .scopes-True-True-False .search-drop-menu,
-body.lang-zh-tw .scopes-True-True-False .search-drop-menu,
-body.lang-zh_TW .scopes-True-True-False .search-drop-menu {
- margin-left: 194px;
-}
-body.lang-zh .scopes-True-True-True #searchBar,
-body.lang-zh_CN .scopes-True-True-True #searchBar,
-body.lang-zh-cn .scopes-True-True-True #searchBar,
-body.lang-zh-tw .scopes-True-True-True #searchBar,
-body.lang-zh_TW .scopes-True-True-True #searchBar,
-body.lang-zh .scopes-True-True-True .search-drop-menu,
-body.lang-zh_CN .scopes-True-True-True .search-drop-menu,
-body.lang-zh-cn .scopes-True-True-True .search-drop-menu,
-body.lang-zh-tw .scopes-True-True-True .search-drop-menu,
-body.lang-zh_TW .scopes-True-True-True .search-drop-menu {
- margin-left: 274px;
-}
body.lang-hu .scope-selector {
font-size: 17px;
margin-left: 10px;
}
-body.lang-hu .scopes-True-True-False #scopeNav {
- width: 200px;
-}
-body.lang-hu .scopes-True-True-False #searchBar,
-body.lang-hu .scopes-True-True-False .search-drop-menu {
+body.lang-hu #searchBar,
+body.lang-hu .search-drop-menu {
margin-left: 252px;
}
body.lang-hu .box .inputs #interestingTagInput,
@@ -4755,34 +4742,9 @@ body.lang-es .short-summary .counts .views div,
body.lang-es .short-summary .counts .votes div {
font-size: 10px;
}
-body.lang-es .scopes-True-True-False #scopeNav {
- width: 187px;
-}
-body.lang-es .scopes-True-True-False #searchBar,
-body.lang-es .scopes-True-True-False .search-drop-menu {
- margin-left: 250px;
-}
-body.lang-es .scopes-True-True-True #searchBar,
-body.lang-es .scopes-True-True-True .search-drop-menu {
- margin-left: 327px;
-}
body.lang-de .scope-selector {
font-size: 17px;
}
-body.lang-de .scopes-True-True-False #scopeNav {
- width: 218px;
-}
-body.lang-de .scopes-True-True-False #searchBar,
-body.lang-de .scopes-True-True-False .search-drop-menu {
- margin-left: 250px;
-}
-body.lang-de .scopes-True-True-True #scopeNav {
- width: 354px;
-}
-body.lang-de .scopes-True-True-True #searchBar,
-body.lang-de .scopes-True-True-True .search-drop-menu {
- margin-left: 354px;
-}
body.lang-de #metaNav a {
font-size: 16px;
}
@@ -4801,24 +4763,12 @@ body.lang-gl .box .inputs #subscribedTagInput,
body.lang-gl .box .inputs #ab-tag-search {
width: 127px;
}
-body.lang-gl .scopes-True-True-True #searchBar,
-body.lang-gl .scopes-True-True-True .search-drop-menu {
- margin-left: 299px;
-}
body.lang-pt_BR .box .inputs #interestingTagInput,
body.lang-pt_BR .box .inputs #ignoredTagInput,
body.lang-pt_BR .box .inputs #subscribedTagInput,
body.lang-pt_BR .box .inputs #ab-tag-search {
width: 116px;
}
-body.lang-pt_BR .scopes-True-True-False #searchBar,
-body.lang-pt_BR .scopes-True-True-False .search-drop-menu {
- margin-left: 236px;
-}
-body.lang-fr .scopes-True-True-True #searchBar,
-body.lang-fr .scopes-True-True-True .search-drop-menu {
- margin-left: 287px;
-}
body.lang-fr .box .inputs #interestingTagInput,
body.lang-fr .box .inputs #ignoredTagInput,
body.lang-fr .box .inputs #subscribedTagInput,
@@ -4834,34 +4784,15 @@ body.lang-fi #scopeNav {
body.lang-fi .scope-selector {
font-size: 17px;
}
-body.lang-fi .scopes-True-True-True #searchBar,
-body.lang-fi .scopes-True-True-True .search-drop-menu {
- margin-left: 371px;
-}
-body.lang-fi .scopes-True-True-False #searchBar,
-body.lang-fi .scopes-True-True-False .search-drop-menu {
- margin-left: 268px;
-}
body.lang-fi .box .inputs #interestingTagInput,
body.lang-fi .box .inputs #ignoredTagInput,
body.lang-fi .box .inputs #subscribedTagInput,
body.lang-fi .box .inputs #ab-tag-search {
width: 142px;
}
-body.lang-ru #scopeNav {
- width: 315px;
-}
body.lang-ru .scope-selector {
font-size: 17px;
}
-body.lang-ru .scopes-True-True-True #searchBar,
-body.lang-ru .scopes-True-True-True .search-drop-menu {
- margin-left: 326px;
-}
-body.lang-ru .scopes-True-True-False #searchBar,
-body.lang-ru .scopes-True-True-False .search-drop-menu {
- margin-left: 227px;
-}
body.lang-ru .box .inputs #interestingTagInput,
body.lang-ru .box .inputs #ignoredTagInput,
body.lang-ru .box .inputs #subscribedTagInput,
@@ -4871,32 +4802,12 @@ body.lang-ru .box .inputs #ab-tag-search {
body.lang-ko #scopeNav {
width: 315px;
}
-body.lang-ko .scopes-True-True-True #searchBar,
-body.lang-ko .scopes-True-True-True .search-drop-menu {
- margin-left: 248px;
-}
-body.lang-ko .scopes-True-True-False #searchBar,
-body.lang-ko .scopes-True-True-False .search-drop-menu {
- margin-left: 183px;
-}
body.lang-ko .box .inputs #interestingTagInput,
body.lang-ko .box .inputs #ignoredTagInput,
body.lang-ko .box .inputs #subscribedTagInput,
body.lang-ko .box .inputs #ab-tag-search {
width: 144px;
}
-body.lang-nb_NO .scopes-True-True-True #searchBar,
-body.lang-nb_NO .scopes-True-True-True #searchBar,
-body.lang-nb_NO .scopes-True-True-True .search-drop-menu,
-body.lang-nb_NO .scopes-True-True-True .search-drop-menu {
- margin-left: 289px;
-}
-body.lang-nb_NO .scopes-True-True-False #searchBar,
-body.lang-nb_NO .scopes-True-True-False #searchBar,
-body.lang-nb_NO .scopes-True-True-False .search-drop-menu,
-body.lang-nb_NO .scopes-True-True-False .search-drop-menu {
- margin-left: 220px;
-}
body.lang-nb_NO .box .inputs #interestingTagInput,
body.lang-nb_NO .box .inputs #interestingTagInput,
body.lang-nb_NO .box .inputs #ignoredTagInput,
diff --git a/askbot/media/style/style.less b/askbot/media/style/style.less
index 513fc6b3..e4a5623b 100644
--- a/askbot/media/style/style.less
+++ b/askbot/media/style/style.less
@@ -205,6 +205,9 @@ h1 {
body.user-messages {
margin-top: 2.4em;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
}
/* ----- Custom positions ----- */
@@ -487,37 +490,44 @@ body.user-messages {
border-top:#fcfcfc 1px solid;
margin-bottom:10px;
font-family:@main-font;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ td {
+ padding: 0;
+ &.search-bar {
+ padding: 0 32px 0 15px;
+ position: relative;
+ }
+ }
}
#homeButton{
border-right: #afaf9e 1px solid;
.sprites(-6px,-36px);
- height:55px;
- width:43px;
- display:block;
- float:left;
+ height: 54px;
+ width: 43px;
+ display: block;
+ float: left;
}
-#homeButton:hover{
+#homeButton:hover {
.sprites(-51px,-36px);
}
.scope-selector {
- display:block;
- float:left;
- font-size:20px;
- color:#7a7a6b;
- height:55px;
- line-height:55px;
- margin-left:16px
-}
-
-.scope-selector.on {
- background:url(../images/scopearrow.png) no-repeat center bottom;
-}
-
-.scope-selector.ask-message {
- font-size:24px;
+ display: inline-block;
+ font-size: 20px;
+ color: #7a7a6b;
+ height: 55px;
+ line-height: 55px;
+ margin-left: 16px;
+ &.on {
+ background: url(../images/scopearrow.png) no-repeat center 41px;
+ }
+ &.ask-message {
+ font-size: 24px;
+ }
}
.validate-email-page {
@@ -539,12 +549,12 @@ body.user-messages {
}
#searchBar { /* Main search form , check widgets/search_bar.html */
- display: block;
- background-color: #fff;
border: 1px solid #c9c9b5;
+ background: white;
height: 41px;
z-index: 1000;
position: relative;
+ width: 100%;
/* the guts are absolute-positioned */
input.searchInput,
@@ -605,17 +615,20 @@ body.user-messages {
.search-drop-menu {
box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
background: whitesmoke;
- border: 1px solid #c9c9b5;
border-top: none;
+ top: 42px;
margin: 0;
- position: relative;
+ outline: 1px solid #dadad4;
+ position: absolute;
z-index: 10000;
ul {
list-style: none;
overflow: auto;
- padding: 0 0 10px 0;
+ padding: 0;
margin: 0;
position: relative;
width: 100%;
@@ -634,13 +647,13 @@ body.user-messages {
}
}
- ul.empty {
- margin-bottom: 0;
- }
-
.footer {
text-align: center;
- padding: 9px 0 10px 0;
+ margin: 0 0 1px 0;
+ padding: 4px 0 10px 0;
+ }
+ &.empty .footer {
+ padding-top: 9px;
}
}
@@ -666,7 +679,7 @@ input[type="submit"].searchBtn {
border:#FFF 1px solid;
line-height: 22px;
text-align: center;
- margin: 1px 0 0 0;
+ margin: 0;
width: 48px;
.sprites(-98px,-37px);
.rounded-corners(0);
@@ -694,12 +707,18 @@ input[type="submit"].searchBtn {
color: white;
height: 0;
z-index: 0;
+ position: absolute;
+ left: -1000px;/* hide away */
}
- .search-drop-menu.empty {
- border: none;
- padding: 0;
- ul {
- padding: 0;
+ .search-drop-menu {
+ top: 37px;
+ &.empty {
+ border: none;
+ outline: none;
+ padding: 0 !important;
+ ul {
+ padding: 0 !important;
+ }
}
}
}
@@ -822,74 +841,22 @@ form.ajax-file-upload {
font-size: 20px;
height: 42px;
line-height: 44px;
- margin: 6px 0 0 0;
+ margin: -1px 0 0 0;
text-transform: uppercase;
width: 200px;/* to match width of sidebar */
}
-/*
- Put the secondary navigation together:
- 1) raise the search bar by 55px
- 2) add padding to fit the buttons
-*/
-#searchBar {
- margin: 0 228px 0 327px;
- width: auto;
- margin-top: -49px;
- padding: 0 49px 0 8px;
-}
-/* line up drop menu the same way as the search bar */
.search-drop-menu {
- margin: 0 228px 0 327px;
- width: auto;
+ width: 100%;
}
.ask-page .search-drop-menu,
body.anon.ask-page .search-drop-menu {
- margin: -9px 0 10px;
+ padding: 5px 10px 6px 0;
}
#scopeNav {
- height: 41px;
- float: left;
- width: 280px;
-}
-.scopes-True-True-False {
- #searchBar,
- .search-drop-menu {
- margin-left: 228px;
- }
- #scopeNav {
- width: 180px;
- }
-}
-.scopes-True-False-True {
- #searchBar,
- .search-drop-menu {
- margin-left: 203px;
- }
- #scopeNav {
- width: 150px;
- }
-}
-.scopes-False-True-True {
- #searchBar,
- .search-drop-menu {
- margin-left: 286px;
- }
- #scopeNav {
- width: 238px;
- }
-}
-.scopes-True-False-False,
-.scopes-False-True-False,
-.scopes-False-False-True,
-.scopes-False-False-False {
- #searchBar,
- .search-drop-menu {
- margin-left: 52px;
- }
- #scopeNav {
- width: 0;
- }
+ height: 54px;
+ display: inline-block;
+ white-space: nowrap;
}
/* ----- Content layout, check two_column_body.html or one_column_body.html ----- */
@@ -1121,7 +1088,7 @@ body.anon.ask-page .search-drop-menu {
-khtml-border-radius: 5px;
-webkit-border-radius: 5px;
.box-shadow(1px, 1px, 3px, #999);
- padding: 7px 10px 1px 10px;
+ padding: 7px 10px 9px 0;
margin-bottom: 10px;
width: 100%;
ul {
@@ -1255,7 +1222,8 @@ body.anon.ask-page .search-drop-menu {
ul#searchTags {
margin-left:10px;
float:right;
- padding-top:2px;
+ padding: 8px 6px 0px 6px;
+ min-width: 43px;
}
.search-tips {
@@ -1462,25 +1430,25 @@ ul#searchTags {
}
.page a, .page a:visited, .curr {
- padding: .25em;
- margin: 0em .25em;
+ padding: 0 .25em;
+ margin: 0em .15em 0 0;
}
.curr {
- background-color: #8ebcc7;
+ /*background-color: #8ebcc7;*/
color: #fff;
font-weight: bold;
a {
background: #8ebcc7;
color: white;
- padding: 0;
+ /*padding: 0;*/
}
}
.curr.page {
a:hover {
background: #8ebcc7;
color: white;
- padding: 0;
+ padding: 0 0.25em;
}
}
@@ -1606,7 +1574,7 @@ ul#related-tags li {
background: #f3f6f6;
border:#fff 1px solid ;
border-top:#fff 2px solid;
- outline:#cfdbdb 1px solid;
+ outline:#cfdbdb 1px solid !important;
/* .box-shadow(0px,1px,0px,#88a8a8);*/
display: block;
float: left;
@@ -1774,6 +1742,7 @@ ul#related-tags li {
padding: 4px 0 0 0;
margin-top:0px;
width: 100%;
+ position: relative;
p {
margin:0 0 5px 0;
@@ -2288,7 +2257,7 @@ ul#related-tags li {
float: right;
font-size: 9px;
font-family:@secondary-font;
- line-height: 13px;
+ line-height: 12px;
margin:0px 0px 5px 5px;
padding:4px;
width: 166px;
@@ -3805,6 +3774,15 @@ a.offensive {
margin-bottom: 0px;
}
+.system-messages {
+ color: red;
+ background: yellow;
+ font-size: 21px;
+ font-weight: bold;
+ line-height: 25px;
+ padding: 0 5px;
+}
+
p.space-above {
margin-top: 10px;
}
@@ -4196,7 +4174,7 @@ p.signup_p {
.avatar-box {
float: left;
- margin: 3px 6px 0 0;
+ margin: 0px 6px 0 2px;
}
.info {
height: 32px;
@@ -4255,6 +4233,10 @@ a.primary-group-name {
font-weight: bold;
}
+.post-update-info .user-info {
+ margin-top: -2px;
+}
+
.users-page {
.wmd-prompt-dialog {
background: #ccc;
@@ -4414,27 +4396,31 @@ textarea.tipped-input {
/* tag editor */
.tag-editor {
- height: 64px;
- border: #ccc 3px solid;
- padding-left: 8px;
+ height: 32px;
+ border: #cce6ec 3px solid;
+ padding-left: 6px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
ul.tags {
margin: 0;
li {
- margin-top: 8px;
+ margin-top: 6px;
height: 13px;
}
}
input.new-tags-input,
input.new-tags-input:focus {
border: none;
- font-size: 15px;
+ box-shadow: none;
+ font-size: 14px;
font-color: @info-text;
height: 16px;
line-height: 16px;
- margin-top: 9px;
+ margin: 9px 0 0 -6px;
-webkit-box-shadow: none;/* undo bootstrap glow */
-moz-box-shadow: none;
- box-shadow: none;
+ padding: 0 0 0 6px;
}
}
@@ -4815,17 +4801,29 @@ td.setting-input {
.short-summary:first-child {
padding-top: 0;
}
- #searchBar,
- body.anon #searchBar {
- margin: -49px 8px 0 52px;
- }
- .search-drop-menu,
- body.anon .search-drop-menu {
- margin: 0 8px 0 52px;
- }
.short-summary {
width: 100%;
}
+ #secondaryHeader td.search-bar {
+ padding: 0 6px;
+ }
+}
+
+@media screen and (max-width: 540px) {
+ .question-page {
+ .post-controls {
+ float: left;
+ margin-left: -8px;
+ padding-left: 0;
+ text-align: left;
+ .question-close {
+ display: none;
+ }
+ }
+ div.comments.empty {
+ margin-top: 0;
+ }
+ }
}
@media screen and (max-width: 480px) {
@@ -4848,6 +4846,18 @@ td.setting-input {
}
}
+@media screen and (max-width: 380px) {
+ .wmd-button-bar {
+ .wmd-hr-button,
+ .wmd-heading-button {
+ display: none;
+ }
+ }
+ .editor-status {
+ margin-right: 0;
+ }
+}
+
@media screen and (max-width: 338px) {
#scopeNav {
display: none;
@@ -4862,6 +4872,11 @@ td.setting-input {
margin: 6px 0;
}
}
+ .question-page .post-controls {
+ .offensive-flag {
+ display: none;
+ }
+ }
}
/* language-specific fixes */
@@ -4892,33 +4907,16 @@ body.lang-zh_TW {
&.question-page a.submit {
line-height: 30px !important;
}
- .scopes-True-True-False {
- #searchBar,
- .search-drop-menu {
- margin-left: 194px;
- }
- }
- .scopes-True-True-True {
- #searchBar,
- .search-drop-menu {
- margin-left: 274px;
- }
- }
}
body.lang-hu {
- .scope-selector{
+ .scope-selector {
font-size: 17px;
margin-left: 10px;
}
- .scopes-True-True-False {
- #scopeNav {
- width: 200px;
- }
- #searchBar,
- .search-drop-menu {
+ #searchBar,
+ .search-drop-menu {
margin-left: 252px;
- }
}
.box {
.inputs{
@@ -4957,45 +4955,12 @@ body.lang-es {
.short-summary .counts .votes div {
font-size: 10px;
}
- .scopes-True-True-False {
- #scopeNav {
- width: 187px;
- }
- #searchBar,
- .search-drop-menu {
- margin-left: 250px;
- }
- }
- .scopes-True-True-True {
- #searchBar,
- .search-drop-menu {
- margin-left: 327px;
- }
- }
}
body.lang-de {
.scope-selector {
font-size: 17px;
}
- .scopes-True-True-False {
- #scopeNav {
- width: 218px;
- }
- #searchBar,
- .search-drop-menu {
- margin-left: 250px;
- }
- }
- .scopes-True-True-True {
- #scopeNav {
- width: 354px;
- }
- #searchBar,
- .search-drop-menu {
- margin-left: 354px;
- }
- }
#metaNav a {
font-size: 16px;
}
@@ -5025,12 +4990,6 @@ body.lang-gl {
}
}
}
- .scopes-True-True-True {
- #searchBar,
- .search-drop-menu {
- margin-left: 299px;
- }
- }
}
body.lang-pt_BR {
@@ -5044,21 +5003,9 @@ body.lang-pt_BR {
}
}
}
- .scopes-True-True-False {
- #searchBar,
- .search-drop-menu {
- margin-left: 236px;
- }
- }
}
body.lang-fr {
- .scopes-True-True-True {
- #searchBar,
- .search-drop-menu {
- margin-left: 287px;
- }
- }
.box {
.inputs {
#interestingTagInput,
@@ -5081,18 +5028,6 @@ body.lang-fi {
.scope-selector {
font-size: 17px;
}
- .scopes-True-True-True {
- #searchBar,
- .search-drop-menu {
- margin-left: 371px;
- }
- }
- .scopes-True-True-False {
- #searchBar,
- .search-drop-menu {
- margin-left: 268px;
- }
- }
.box {
.inputs {
#interestingTagInput,
@@ -5106,24 +5041,9 @@ body.lang-fi {
}
body.lang-ru {
- #scopeNav {
- width: 315px;
- }
.scope-selector {
font-size: 17px;
}
- .scopes-True-True-True {
- #searchBar,
- .search-drop-menu {
- margin-left: 326px;
- }
- }
- .scopes-True-True-False {
- #searchBar,
- .search-drop-menu {
- margin-left: 227px;
- }
- }
.box {
.inputs {
#interestingTagInput,
@@ -5140,18 +5060,6 @@ body.lang-ko {
#scopeNav {
width: 315px;
}
- .scopes-True-True-True {
- #searchBar,
- .search-drop-menu {
- margin-left: 248px;
- }
- }
- .scopes-True-True-False {
- #searchBar,
- .search-drop-menu {
- margin-left: 183px;
- }
- }
.box {
.inputs {
#interestingTagInput,
@@ -5166,18 +5074,6 @@ body.lang-ko {
body.lang-nb_NO,
body.lang-nb_NO, {
- .scopes-True-True-True {
- #searchBar,
- .search-drop-menu {
- margin-left: 289px;
- }
- }
- .scopes-True-True-False {
- #searchBar,
- .search-drop-menu {
- margin-left: 220px;
- }
- }
.box {
.inputs {
#interestingTagInput,
diff --git a/askbot/middleware/cancel.py b/askbot/middleware/cancel.py
index f13d8d69..ac2f3ded 100644
--- a/askbot/middleware/cancel.py
+++ b/askbot/middleware/cancel.py
@@ -8,7 +8,7 @@ class CancelActionMiddleware(object):
msg = getattr(view_func,'CANCEL_MESSAGE')
except AttributeError:
msg = 'action canceled'
- request.user.message_set.create(message=msg)
+ request.user.message_set.create(message=unicode(msg))
return HttpResponseRedirect(get_next_url(request))
else:
return None
diff --git a/askbot/middleware/forum_mode.py b/askbot/middleware/forum_mode.py
index 331fe85b..5fd2bda3 100644
--- a/askbot/middleware/forum_mode.py
+++ b/askbot/middleware/forum_mode.py
@@ -8,13 +8,14 @@ from django.conf import settings
from django.core.urlresolvers import resolve
from askbot.shims.django_shims import ResolverMatch
from askbot.conf import settings as askbot_settings
+import urllib
PROTECTED_VIEW_MODULES = (
'askbot.views',
'askbot.feed',
)
ALLOWED_VIEWS = (
- 'askbot.views.meta.media',
+ 'askbot.views.meta.config_variable',
)
def is_view_protected(view_func):
@@ -63,5 +64,9 @@ class ForumModeMiddleware(object):
_('Please log in to use %s') % \
askbot_settings.APP_SHORT_NAME
)
- return HttpResponseRedirect(settings.LOGIN_URL)
+ redirect_url = '%s?next=%s' % (
+ settings.LOGIN_URL,
+ urllib.quote_plus(request.get_full_path())
+ )
+ return HttpResponseRedirect(redirect_url)
return None
diff --git a/askbot/migrations/0006_add_subscription_setting_for_comments_and_mentions.py b/askbot/migrations/0006_add_subscription_setting_for_comments_and_mentions.py
index 1dbfe24f..711e87e4 100644
--- a/askbot/migrations/0006_add_subscription_setting_for_comments_and_mentions.py
+++ b/askbot/migrations/0006_add_subscription_setting_for_comments_and_mentions.py
@@ -45,7 +45,7 @@ class Migration(DataMigration):
new_feed.save()
verbose_frequency = unicode(dict(const.NOTIFICATION_DELIVERY_SCHEDULE_CHOICES)[frequency])
print 'added \'%s\' subscription for %s (%d)' % (
- verbose_frequency,
+ unicode(verbose_frequency),
unidecode(user.username),
user.id
)
diff --git a/askbot/migrations/0032_auto__del_field_badgedata_multiple__del_field_badgedata_description__d.py b/askbot/migrations/0032_auto__del_field_badgedata_multiple__del_field_badgedata_description__d.py
index 2c58d82a..d7c28d3e 100644
--- a/askbot/migrations/0032_auto__del_field_badgedata_multiple__del_field_badgedata_description__d.py
+++ b/askbot/migrations/0032_auto__del_field_badgedata_multiple__del_field_badgedata_description__d.py
@@ -9,7 +9,7 @@ class Migration(SchemaMigration):
def forwards(self, orm):
# Removing unique constraint on 'BadgeData', fields ['type', 'name']
- #db.delete_unique('askbot_badgedata', ['type', 'name'])
+ db.delete_unique('askbot_badgedata', ['type', 'name'])
# Deleting field 'BadgeData.multiple'
db.delete_column('askbot_badgedata', 'multiple')
@@ -17,6 +17,7 @@ class Migration(SchemaMigration):
# Deleting field 'BadgeData.description'
db.delete_column('askbot_badgedata', 'description')
+
# Deleting field 'BadgeData.type'
db.delete_column('askbot_badgedata', 'type')
diff --git a/askbot/migrations/0171_auto__add_importedobjectinfo__add_importrun.py b/askbot/migrations/0171_auto__add_importedobjectinfo__add_importrun.py
new file mode 100644
index 00000000..8822dda8
--- /dev/null
+++ b/askbot/migrations/0171_auto__add_importedobjectinfo__add_importrun.py
@@ -0,0 +1,439 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding model 'ImportedObjectInfo'
+ db.create_table('askbot_importedobjectinfo', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('old_id', self.gf('django.db.models.fields.IntegerField')()),
+ ('new_id', self.gf('django.db.models.fields.IntegerField')()),
+ ('model', self.gf('django.db.models.fields.CharField')(default='', max_length=255)),
+ ('run', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['askbot.ImportRun'])),
+ ('extra_info', self.gf('picklefield.fields.PickledObjectField')()),
+ ))
+ db.send_create_signal('askbot', ['ImportedObjectInfo'])
+
+ # Adding model 'ImportRun'
+ db.create_table('askbot_importrun', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('command', self.gf('django.db.models.fields.TextField')(default='')),
+ ('timestamp', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
+ ))
+ db.send_create_signal('askbot', ['ImportRun'])
+
+
+ def backwards(self, orm):
+ # Deleting model 'ImportedObjectInfo'
+ db.delete_table('askbot_importedobjectinfo')
+
+ # Deleting model 'ImportRun'
+ db.delete_table('askbot_importrun')
+
+
+ models = {
+ 'askbot.activity': {
+ 'Meta': {'object_name': 'Activity', 'db_table': "u'activity'"},
+ 'active_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'activity_type': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_auditted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Post']", 'null': 'True'}),
+ 'receiving_users': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'received_activity'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
+ 'recipients': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'incoming_activity'", 'symmetrical': 'False', 'through': "orm['askbot.ActivityAuditStatus']", 'to': "orm['auth.User']"}),
+ 'summary': ('django.db.models.fields.TextField', [], {'default': "''"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'askbot.activityauditstatus': {
+ 'Meta': {'unique_together': "(('user', 'activity'),)", 'object_name': 'ActivityAuditStatus'},
+ 'activity': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Activity']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'askbot.anonymousanswer': {
+ 'Meta': {'object_name': 'AnonymousAnswer'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ip_addr': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'anonymous_answers'", 'to': "orm['askbot.Post']"}),
+ 'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'text': ('django.db.models.fields.TextField', [], {}),
+ 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'askbot.anonymousquestion': {
+ 'Meta': {'object_name': 'AnonymousQuestion'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ip_addr': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}),
+ 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'text': ('django.db.models.fields.TextField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'askbot.askwidget': {
+ 'Meta': {'object_name': 'AskWidget'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Group']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'include_text_field': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'inner_style': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'outer_style': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Tag']", 'null': 'True', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'askbot.award': {
+ 'Meta': {'object_name': 'Award', 'db_table': "u'award'"},
+ 'awarded_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'badge': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_badge'", 'to': "orm['askbot.BadgeData']"}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'notified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_user'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.badgedata': {
+ 'Meta': {'ordering': "('slug',)", 'object_name': 'BadgeData'},
+ 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'symmetrical': 'False', 'through': "orm['askbot.Award']", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
+ },
+ 'askbot.bulktagsubscription': {
+ 'Meta': {'ordering': "['-date_added']", 'object_name': 'BulkTagSubscription'},
+ 'date_added': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['askbot.Group']", 'symmetrical': 'False'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['askbot.Tag']", 'symmetrical': 'False'}),
+ 'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'})
+ },
+ 'askbot.draftanswer': {
+ 'Meta': {'object_name': 'DraftAnswer'},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'draft_answers'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'thread': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'draft_answers'", 'to': "orm['askbot.Thread']"})
+ },
+ 'askbot.draftquestion': {
+ 'Meta': {'object_name': 'DraftQuestion'},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125', 'null': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True'})
+ },
+ 'askbot.emailfeedsetting': {
+ 'Meta': {'unique_together': "(('subscriber', 'feed_type'),)", 'object_name': 'EmailFeedSetting'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'feed_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
+ 'frequency': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '8'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'reported_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+ 'subscriber': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'notification_subscriptions'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.favoritequestion': {
+ 'Meta': {'object_name': 'FavoriteQuestion', 'db_table': "u'favorite_question'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'thread': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Thread']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.group': {
+ 'Meta': {'object_name': 'Group', '_ormbases': ['auth.Group']},
+ 'description': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'described_group'", 'unique': 'True', 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'group_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.Group']", 'unique': 'True', 'primary_key': 'True'}),
+ 'is_vip': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
+ 'moderate_answers_to_enquirers': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'moderate_email': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'openness': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}),
+ 'preapproved_email_domains': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
+ 'preapproved_emails': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
+ 'read_only': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'askbot.groupmembership': {
+ 'Meta': {'object_name': 'GroupMembership', '_ormbases': ['auth.AuthUserGroups']},
+ 'authusergroups_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.AuthUserGroups']", 'unique': 'True', 'primary_key': 'True'}),
+ 'level': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'})
+ },
+ 'askbot.importedobjectinfo': {
+ 'Meta': {'object_name': 'ImportedObjectInfo'},
+ 'extra_info': ('picklefield.fields.PickledObjectField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255'}),
+ 'new_id': ('django.db.models.fields.IntegerField', [], {}),
+ 'old_id': ('django.db.models.fields.IntegerField', [], {}),
+ 'run': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.ImportRun']"})
+ },
+ 'askbot.importrun': {
+ 'Meta': {'object_name': 'ImportRun'},
+ 'command': ('django.db.models.fields.TextField', [], {'default': "''"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
+ },
+ 'askbot.markedtag': {
+ 'Meta': {'object_name': 'MarkedTag'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'reason': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
+ 'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_selections'", 'to': "orm['askbot.Tag']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.post': {
+ 'Meta': {'object_name': 'Post'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'posts'", 'to': "orm['auth.User']"}),
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
+ 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_posts'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'group_posts'", 'symmetrical': 'False', 'through': "orm['askbot.PostToGroup']", 'to': "orm['askbot.Group']"}),
+ 'html': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '16'}),
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'last_edited_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_edited_posts'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_posts'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'old_answer_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+ 'old_comment_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+ 'old_question_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comments'", 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'points': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_column': "'score'"}),
+ 'post_type': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'summary': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'thread': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'posts'", 'null': 'True', 'blank': 'True', 'to': "orm['askbot.Thread']"}),
+ 'vote_down_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'vote_up_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'askbot.postflagreason': {
+ 'Meta': {'object_name': 'PostFlagReason'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'details': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'post_reject_reasons'", 'to': "orm['askbot.Post']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ },
+ 'askbot.postrevision': {
+ 'Meta': {'ordering': "('-revision',)", 'unique_together': "(('post', 'revision'),)", 'object_name': 'PostRevision'},
+ 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
+ 'approved_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'approved_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'postrevisions'", 'to': "orm['auth.User']"}),
+ 'by_email': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'post': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'revisions'", 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'revised_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '125', 'blank': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '300', 'blank': 'True'})
+ },
+ 'askbot.posttogroup': {
+ 'Meta': {'unique_together': "(('post', 'group'),)", 'object_name': 'PostToGroup', 'db_table': "'askbot_post_groups'"},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'post': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Post']"})
+ },
+ 'askbot.questionview': {
+ 'Meta': {'object_name': 'QuestionView'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'viewed'", 'to': "orm['askbot.Post']"}),
+ 'when': ('django.db.models.fields.DateTimeField', [], {}),
+ 'who': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'question_views'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.questionwidget': {
+ 'Meta': {'object_name': 'QuestionWidget'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Group']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order_by': ('django.db.models.fields.CharField', [], {'default': "'-added_at'", 'max_length': '18'}),
+ 'question_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '7'}),
+ 'search_query': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'style': ('django.db.models.fields.TextField', [], {'default': '"\\n@import url(\'http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz:300,400,700\');\\nbody {\\n overflow: hidden;\\n}\\n\\n#container {\\n width: 200px;\\n height: 350px;\\n}\\nul {\\n list-style: none;\\n padding: 5px;\\n margin: 5px;\\n}\\nli {\\n border-bottom: #CCC 1px solid;\\n padding-bottom: 5px;\\n padding-top: 5px;\\n}\\nli:last-child {\\n border: none;\\n}\\na {\\n text-decoration: none;\\n color: #464646;\\n font-family: \'Yanone Kaffeesatz\', sans-serif;\\n font-size: 15px;\\n}\\n"', 'blank': 'True'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'askbot.replyaddress': {
+ 'Meta': {'object_name': 'ReplyAddress'},
+ 'address': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}),
+ 'allowed_from_email': ('django.db.models.fields.EmailField', [], {'max_length': '150'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reply_addresses'", 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'reply_action': ('django.db.models.fields.CharField', [], {'default': "'auto_answer_or_comment'", 'max_length': '32'}),
+ 'response_post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'edit_addresses'", 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'used_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'askbot.repute': {
+ 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"},
+ 'comment': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'negative': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'positive': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Post']", 'null': 'True', 'blank': 'True'}),
+ 'reputation': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'reputation_type': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'reputed_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'askbot.tag': {
+ 'Meta': {'ordering': "('-used_count', 'name')", 'object_name': 'Tag', 'db_table': "u'tag'"},
+ 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_tags'", 'to': "orm['auth.User']"}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_tags'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
+ 'suggested_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'suggested_tags'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
+ 'tag_wiki': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'described_tag'", 'unique': 'True', 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
+ },
+ 'askbot.tagsynonym': {
+ 'Meta': {'object_name': 'TagSynonym'},
+ 'auto_rename_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_auto_rename_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+ 'owned_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_synonyms'", 'to': "orm['auth.User']"}),
+ 'source_tag_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'target_tag_name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'})
+ },
+ 'askbot.thread': {
+ 'Meta': {'object_name': 'Thread'},
+ 'accepted_answer': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'answer_accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
+ 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
+ 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'unused_favorite_threads'", 'symmetrical': 'False', 'through': "orm['askbot.FavoriteQuestion']", 'to': "orm['auth.User']"}),
+ 'favourite_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'followed_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'followed_threads'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'group_threads'", 'symmetrical': 'False', 'through': "orm['askbot.ThreadToGroup']", 'to': "orm['askbot.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '16'}),
+ 'last_activity_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_activity_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'unused_last_active_in_threads'", 'to': "orm['auth.User']"}),
+ 'points': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_column': "'score'"}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'threads'", 'symmetrical': 'False', 'to': "orm['askbot.Tag']"}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'view_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
+ },
+ 'askbot.threadtogroup': {
+ 'Meta': {'unique_together': "(('thread', 'group'),)", 'object_name': 'ThreadToGroup', 'db_table': "'askbot_thread_groups'"},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'thread': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Thread']"}),
+ 'visibility': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'})
+ },
+ 'askbot.vote': {
+ 'Meta': {'unique_together': "(('user', 'voted_post'),)", 'object_name': 'Vote', 'db_table': "u'vote'"},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['auth.User']"}),
+ 'vote': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'voted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'voted_post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['askbot.Post']"})
+ },
+ 'auth.authusergroups': {
+ 'Meta': {'unique_together': "(('group', 'user'),)", 'object_name': 'AuthUserGroups', 'db_table': "'auth_user_groups'", 'managed': 'False'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
+ 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
+ 'email_signature': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_fake': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'languages': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '128'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+ 'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
+ 'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+ 'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
+ 'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'show_marked_tags': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'social_sharing_mode': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'twitter_access_token': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256'}),
+ 'twitter_handle': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '32'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ }
+ }
+
+ complete_apps = ['askbot'] \ No newline at end of file
diff --git a/askbot/migrations_api/__init__.py b/askbot/migrations_api/__init__.py
index a9b20a69..5a65f9cf 100644
--- a/askbot/migrations_api/__init__.py
+++ b/askbot/migrations_api/__init__.py
@@ -13,7 +13,7 @@ def safe_add_column(table, column, column_data, keep_default = False):
so, we need to add these columns here in separate transactions
and roll back if they fail, if we want we could also record - which columns clash
"""
- if db.backend_name == 'mysql':
+ if db.backend_name in ('mysql', 'postgres'):
if len(db.execute('select column_name from information_schema.columns where table_name=%s and column_name=%s', params=[table, column])) == 0:
db.add_column(table, column, column_data, keep_default = keep_default)
else:
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index a2f55ab7..42f97185 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -35,7 +35,7 @@ from django.core import exceptions as django_exceptions
from django_countries.fields import CountryField
from askbot import exceptions as askbot_exceptions
from askbot import const
-from askbot.const.message_keys import get_i18n_message
+from askbot.const import message_keys
from askbot.conf import settings as askbot_settings
from askbot.models.question import Thread
from askbot.skins import utils as skin_utils
@@ -54,10 +54,10 @@ from askbot.models.post import PostFlagReason, AnonymousAnswer
from askbot.models.post import PostToGroup
from askbot.models.post import DraftAnswer
from askbot.models.reply_by_email import ReplyAddress
-from askbot.models import signals
-from askbot.models.badges import award_badges_signal, get_badge, BadgeData
-from askbot.models.repute import Award, Repute, Vote
+from askbot.models.badges import award_badges_signal, get_badge
+from askbot.models.repute import Award, Repute, Vote, BadgeData
from askbot.models.widgets import AskWidget, QuestionWidget
+from askbot.models.meta import ImportRun, ImportedObjectInfo
from askbot import auth
from askbot.utils.decorators import auto_now_timestamp
from askbot.utils.markup import URL_RE
@@ -68,6 +68,7 @@ from askbot.utils.html import site_url
from askbot.utils.diff import textDiff as htmldiff
from askbot.utils.url_utils import strip_path
from askbot import mail
+from askbot.models import signals
from django import VERSION
@@ -76,6 +77,8 @@ DJANGO_VERSION = VERSION[:2]
if DJANGO_VERSION > (1, 3):
from askbot.models.message import Message
+else:
+ from django.contrib.messages.models import Message
def get_model(model_name):
"""a shortcut for getting model for an askbot app"""
@@ -464,6 +467,13 @@ def user_has_interesting_wildcard_tags(self):
and self.interesting_tags != ''
)
+def user_has_badge(self, badge):
+ """True, if user was awarded a given badge,
+ ``badge`` is instance of BadgeData
+ """
+ return Award.objects.filter(user=self, badge=badge).count() > 0
+
+
def user_can_create_tags(self):
"""true if user can create tags"""
if askbot_settings.ENABLE_TAG_MODERATION:
@@ -565,19 +575,16 @@ def user_get_notifications(self, notification_types=None, **kwargs):
)
def _assert_user_can(
- user = None,
- post = None, #related post (may be parent)
- admin_or_moderator_required = False,
- owner_can = False,
- suspended_owner_cannot = False,
- owner_min_rep_setting = None,
- blocked_error_message = None,
- suspended_error_message = None,
- min_rep_setting = None,
- low_rep_error_message = None,
- owner_low_rep_error_message = None,
- general_error_message = None,
- ):
+ user=None,
+ post=None, #related post (may be parent)
+ admin_or_moderator_required=False,
+ owner_can=False,
+ action_display=None,
+ suspended_owner_cannot=False,
+ suspended_user_cannot=False,
+ blocked_user_cannot=False,
+ min_rep_setting=None
+ ):
"""generic helper assert for use in several
User.assert_can_XYZ() calls regarding changing content
@@ -586,69 +593,81 @@ def _assert_user_can(
if assertion fails, method raises exception.PermissionDenied
with appropriate text as a payload
"""
+ action_display = action_display or _('perform this action')
if askbot_settings.GROUPS_ENABLED:
if user.is_read_only():
message = _('Sorry, but you have only read access')
raise django_exceptions.PermissionDenied(message)
- if general_error_message is None:
- general_error_message = _('Sorry, this operation is not allowed')
- if blocked_error_message and user.is_blocked():
- error_message = blocked_error_message
+ if blocked_user_cannot and user.is_blocked():
+ error_message = _(message_keys.ACCOUNT_CANNOT_PERFORM_ACTION) % {
+ 'perform_action': action_display,
+ 'your_account_is': _('your account is blocked')
+ }
elif post and owner_can and user == post.get_owner():
- if owner_min_rep_setting:
- if post.get_owner().reputation < owner_min_rep_setting:
- if user.is_moderator() or user.is_administrator():
- return
- else:
- assert(owner_low_rep_error_message is not None)
- raise askbot_exceptions.InsufficientReputation(
- owner_low_rep_error_message
- )
- if suspended_owner_cannot and user.is_suspended():
- if suspended_error_message:
- error_message = suspended_error_message
- else:
- error_message = general_error_message
- assert(error_message is not None)
- raise django_exceptions.PermissionDenied(error_message)
+ if user.is_suspended() and suspended_owner_cannot:
+ error_message = _(message_keys.ACCOUNT_CANNOT_PERFORM_ACTION) % {
+ 'perform_action': action_display,
+ 'your_account_is': _('your account is suspended')
+ }
else:
return
- return
- elif suspended_error_message and user.is_suspended():
- error_message = suspended_error_message
+ elif suspended_user_cannot and user.is_suspended():
+ error_message = _(message_keys.ACCOUNT_CANNOT_PERFORM_ACTION) % {
+ 'perform_action': action_display,
+ 'your_account_is': _('your account is suspended')
+ }
elif user.is_administrator() or user.is_moderator():
return
elif user.is_post_moderator(post):
return
- elif low_rep_error_message and user.reputation < min_rep_setting:
- raise askbot_exceptions.InsufficientReputation(low_rep_error_message)
+ elif min_rep_setting and user.reputation < min_rep_setting:
+ raise askbot_exceptions.InsufficientReputation(
+ _(message_keys.MIN_REP_REQUIRED_TO_PERFORM_ACTION) % {
+ 'perform_action': action_display,
+ 'min_rep': min_rep_setting
+ }
+ )
+ elif admin_or_moderator_required:
+ if min_rep_setting is None:
+ #message about admins only
+ error_message = _(
+ 'Sorry, only moderators and site administrators can %(perform_action)s'
+ ) % {
+ 'perform_action': action_display
+ }
+ else:
+ #message with minimum reputation
+ error_message = _(
+ 'Sorry, only administrators, moderators '
+ 'or users with reputation > %(min_rep)s '
+ 'can %(perform_action)s'
+ ) % {
+ 'min_rep': min_rep_setting,
+ 'perform_action': action_display
+ }
else:
- if admin_or_moderator_required == False:
- return
+ return
- #if admin or moderator is required, then substitute the message
- if admin_or_moderator_required:
- error_message = general_error_message
assert(error_message is not None)
raise django_exceptions.PermissionDenied(error_message)
def user_assert_can_approve_post_revision(self, post_revision = None):
_assert_user_can(
- user = self,
- admin_or_moderator_required = True
+ user=self,
+ admin_or_moderator_required=True
)
def user_assert_can_unaccept_best_answer(self, answer = None):
assert getattr(answer, 'post_type', '') == 'answer'
- blocked_error_message = _(
- 'Sorry, you cannot accept or unaccept best answers '
- 'because your account is blocked'
- )
- suspended_error_message = _(
- 'Sorry, you cannot accept or unaccept best answers '
- 'because your account is suspended'
- )
+ suspended_error_message = _(message_keys.ACCOUNT_CANNOT_PERFORM_ACTION) % {
+ 'perform_action': askbot_settings.WORDS_ACCEPT_OR_UNACCEPT_THE_BEST_ANSWER,
+ 'your_account_is': _('your account is suspended')
+ }
+ blocked_error_message = _(message_keys.ACCOUNT_CANNOT_PERFORM_ACTION) % {
+ 'perform_action': askbot_settings.WORDS_ACCEPT_OR_UNACCEPT_THE_BEST_ANSWER,
+ 'your_account_is': _('your account is blocked')
+ }
if self.is_blocked():
error_message = blocked_error_message
@@ -658,18 +677,12 @@ def user_assert_can_unaccept_best_answer(self, answer = None):
if self == answer.get_owner():
if not self.is_administrator():
#check rep
- min_rep_setting = askbot_settings.MIN_REP_TO_ACCEPT_OWN_ANSWER
- low_rep_error_message = _(
- ">%(points)s points required to accept or unaccept "
- " your own answer to your own question"
- ) % {'points': min_rep_setting}
-
_assert_user_can(
- user = self,
- blocked_error_message = blocked_error_message,
- suspended_error_message = suspended_error_message,
- min_rep_setting = min_rep_setting,
- low_rep_error_message = low_rep_error_message
+ user=self,
+ action_display=askbot_settings.WORDS_ACCEPT_OR_UNACCEPT_OWN_ANSWER,
+ blocked_user_cannot=True,
+ suspended_owner_cannot=True,
+ min_rep_setting = askbot_settings.MIN_REP_TO_ACCEPT_OWN_ANSWER
)
return # success
@@ -683,19 +696,19 @@ def user_assert_can_unaccept_best_answer(self, answer = None):
)
if datetime.datetime.now() < will_be_able_at:
- error_message = _(
- 'Sorry, you will be able to accept this answer '
- 'only after %(will_be_able_at)s'
- ) % {'will_be_able_at': will_be_able_at.strftime('%d/%m/%Y')}
+ error_message = _(message_keys.CANNOT_PERFORM_ACTION_UNTIL) % {
+ 'perform_action': askbot_settings.WORDS_ACCEPT_OR_UNACCEPT_OWN_ANSWER,
+ 'until': will_be_able_at.strftime('%d/%m/%Y')
+ }
else:
return
else:
question_owner = answer.thread._question_post().get_owner()
- error_message = _(
- 'Sorry, only moderators or original author of the question '
- ' - %(username)s - can accept or unaccept the best answer'
- ) % {'username': question_owner.username}
+ error_message = _(message_keys.MODERATORS_OR_AUTHOR_CAN_PEFROM_ACTION) % {
+ 'post_author': askbot_settings.WORDS_AUTHOR_OF_THE_QUESTION,
+ 'perform_action': askbot_settings.WORDS_ACCEPT_OR_UNACCEPT_THE_BEST_ANSWER,
+ }
raise django_exceptions.PermissionDenied(error_message)
@@ -719,54 +732,32 @@ def user_assert_can_vote_for_post(
_('Sorry, you cannot vote for your own posts')
)
- blocked_error_message = _(
- 'Sorry your account appears to be blocked ' +
- 'and you cannot vote - please contact the ' +
- 'site administrator to resolve the issue'
- ),
- suspended_error_message = _(
- 'Sorry your account appears to be suspended ' +
- 'and you cannot vote - please contact the ' +
- 'site administrator to resolve the issue'
- )
-
assert(direction in ('up', 'down'))
if direction == 'up':
min_rep_setting = askbot_settings.MIN_REP_TO_VOTE_UP
- low_rep_error_message = _(
- ">%(points)s points required to upvote"
- ) % \
- {'points': askbot_settings.MIN_REP_TO_VOTE_UP}
+ action_display = _('upvote')
else:
min_rep_setting = askbot_settings.MIN_REP_TO_VOTE_DOWN
- low_rep_error_message = _(
- ">%(points)s points required to downvote"
- ) % \
- {'points': askbot_settings.MIN_REP_TO_VOTE_DOWN}
+ action_display = _('downvote')
_assert_user_can(
- user = self,
- blocked_error_message = blocked_error_message,
- suspended_error_message = suspended_error_message,
+ user=self,
+ action_display=action_display,
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
min_rep_setting = min_rep_setting,
- low_rep_error_message = low_rep_error_message
)
def user_assert_can_upload_file(request_user):
- blocked_error_message = _('Sorry, blocked users cannot upload files')
- suspended_error_message = _('Sorry, suspended users cannot upload files')
- low_rep_error_message = _(
- 'sorry, file uploading requires karma >%(min_rep)s',
- ) % {'min_rep': askbot_settings.MIN_REP_TO_UPLOAD_FILES }
-
_assert_user_can(
- user = request_user,
- suspended_error_message = suspended_error_message,
- min_rep_setting = askbot_settings.MIN_REP_TO_UPLOAD_FILES,
- low_rep_error_message = low_rep_error_message
+ user=request_user,
+ action_display=_('upload files'),
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
+ min_rep_setting=askbot_settings.MIN_REP_TO_UPLOAD_FILES
)
@@ -787,14 +778,11 @@ def user_assert_can_post_question(self):
"""raises exceptions.PermissionDenied with
text that has the reason for the denial
"""
-
- blocked_message = get_i18n_message('BLOCKED_USERS_CANNOT_POST')
- suspended_message = get_i18n_message('SUSPENDED_USERS_CANNOT_POST')
-
_assert_user_can(
- user = self,
- blocked_error_message = blocked_message,
- suspended_error_message = suspended_message
+ user=self,
+ action_display=askbot_settings.WORDS_ASK_QUESTIONS,
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
)
@@ -804,8 +792,10 @@ def user_assert_can_post_answer(self, thread = None):
limit_answers = askbot_settings.LIMIT_ONE_ANSWER_PER_USER
if limit_answers and thread.has_answer_by_user(self):
message = _(
- 'Sorry, you already gave an answer, please edit it instead.'
- )
+ 'Sorry, %(you_already_gave_an_answer)s, please edit it instead.'
+ ) % {
+ 'you_already_gave_an_answer': askbot_settings.WORDS_YOU_ALREADY_GAVE_AN_ANSWER
+ }
raise askbot_exceptions.AnswerAlreadyGiven(message)
self.assert_can_post_question()
@@ -848,18 +838,17 @@ def user_assert_can_edit_comment(self, comment = None):
def user_can_post_comment(self, parent_post = None):
"""a simplified method to test ability to comment
"""
- return True
- """
- #commented out to disable the min rep
- if self.reputation >= askbot_settings.MIN_REP_TO_LEAVE_COMMENTS:
- return True
- if parent_post and self == parent_post.author:
- return True
if self.is_administrator_or_moderator():
return True
- return False
- """
+ elif self.is_suspended():
+ if parent_post and self == parent_post.author:
+ return True
+ else:
+ return False
+ elif self.is_blocked():
+ return False
+ return True
def user_assert_can_post_comment(self, parent_post = None):
"""raises exceptions.PermissionDenied if
@@ -867,52 +856,35 @@ def user_assert_can_post_comment(self, parent_post = None):
the reason will be in text of exception
"""
+ _assert_user_can(
+ user=self,
+ post=parent_post,
+ action_display=_('post comments'),
+ owner_can=True,
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
+ )
- suspended_error_message = _(
- 'Sorry, since your account is suspended '
- 'you can comment only your own posts'
- )
- low_rep_error_message = _(
- 'Sorry, to comment any post a minimum reputation of '
- '%(min_rep)s points is required. You can still comment '
- 'your own posts and answers to your questions'
- ) % {'min_rep': 0}#askbot_settings.MIN_REP_TO_LEAVE_COMMENTS}
-
- blocked_message = get_i18n_message('BLOCKED_USERS_CANNOT_POST')
+def user_assert_can_see_deleted_post(self, post=None):
+ """attn: this assertion is independently coded in
+ Question.get_answers call
+ """
try:
_assert_user_can(
- user = self,
- post = parent_post,
- owner_can = True,
- blocked_error_message = blocked_message,
- suspended_error_message = suspended_error_message,
- min_rep_setting = 0,#askbot_settings.MIN_REP_TO_LEAVE_COMMENTS,
- low_rep_error_message = low_rep_error_message,
+ user=self,
+ post=post,
+ admin_or_moderator_required=True,
+ owner_can=True
)
- except askbot_exceptions.InsufficientReputation, e:
- if parent_post.post_type == 'answer':
- if self == parent_post.thread._question_post().author:
- return
- raise e
-
-def user_assert_can_see_deleted_post(self, post = None):
+ except django_exceptions.PermissionDenied, e:
+ #re-raise the same exception with a different message
+ error_message = _(
+ 'This post has been deleted and can be seen only '
+ 'by post owners, site administrators and moderators'
+ )
+ raise django_exceptions.PermissionDenied(error_message)
- """attn: this assertion is independently coded in
- Question.get_answers call
- """
-
- error_message = _(
- 'This post has been deleted and can be seen only '
- 'by post owners, site administrators and moderators'
- )
- _assert_user_can(
- user = self,
- post = post,
- admin_or_moderator_required = True,
- owner_can = True,
- general_error_message = error_message
- )
def user_assert_can_edit_deleted_post(self, post = None):
assert(post.deleted == True)
@@ -920,9 +892,9 @@ def user_assert_can_edit_deleted_post(self, post = None):
self.assert_can_see_deleted_post(post)
except django_exceptions.PermissionDenied, e:
error_message = _(
- 'Sorry, only moderators, site administrators '
- 'and post owners can edit deleted posts'
- )
+ 'Sorry, only moderators, site administrators '
+ 'and post owners can edit deleted posts'
+ )
raise django_exceptions.PermissionDenied(error_message)
def user_assert_can_edit_post(self, post = None):
@@ -935,37 +907,21 @@ def user_assert_can_edit_post(self, post = None):
return
- blocked_error_message = _(
- 'Sorry, since your account is blocked '
- 'you cannot edit posts'
- )
- suspended_error_message = _(
- 'Sorry, since your account is suspended '
- 'you can edit only your own posts'
- )
if post.wiki == True:
- low_rep_error_message = _(
- 'Sorry, to edit wiki posts, a minimum '
- 'reputation of %(min_rep)s is required'
- ) % \
- {'min_rep': askbot_settings.MIN_REP_TO_EDIT_WIKI}
+ action_display=_('edit wiki posts')
min_rep_setting = askbot_settings.MIN_REP_TO_EDIT_WIKI
else:
- low_rep_error_message = _(
- 'Sorry, to edit other people\'s posts, a minimum '
- 'reputation of %(min_rep)s is required'
- ) % \
- {'min_rep': askbot_settings.MIN_REP_TO_EDIT_OTHERS_POSTS}
+ action_display=_('edit posts')
min_rep_setting = askbot_settings.MIN_REP_TO_EDIT_OTHERS_POSTS
_assert_user_can(
- user = self,
- post = post,
- owner_can = True,
- blocked_error_message = blocked_error_message,
- suspended_error_message = suspended_error_message,
- low_rep_error_message = low_rep_error_message,
- min_rep_setting = min_rep_setting,
+ user=self,
+ post=post,
+ action_display=action_display,
+ owner_can=True,
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
+ min_rep_setting = min_rep_setting
)
@@ -1015,12 +971,16 @@ def user_assert_can_delete_question(self, question = None):
return
else:
msg = ungettext(
- 'Sorry, cannot delete your question since it '
- 'has an upvoted answer posted by someone else',
- 'Sorry, cannot delete your question since it '
- 'has some upvoted answers posted by other users',
+ 'Sorry, cannot %(delete_your_question)s since it '
+ 'has an %(upvoted_answer)s posted by someone else',
+ 'Sorry, cannot %(delete_your_question)s since it '
+ 'has some %(upvoted_answers)s posted by other users',
answer_count
- )
+ ) % {
+ 'delete_your_question': askbot_settings.WORDS_DELETE_YOUR_QUESTION,
+ 'upvoted_answer': askbot_settings.WORDS_UPVOTED_ANSWER,
+ 'upvoted_answers': askbot_settings.WORDS_UPVOTED_ANSWERS
+ }
raise django_exceptions.PermissionDenied(msg)
@@ -1029,111 +989,44 @@ def user_assert_can_delete_answer(self, answer = None):
instead of "answer", because this logic also applies to
assert on deleting question (in addition to some special rules)
"""
- blocked_error_message = _(
- 'Sorry, since your account is blocked '
- 'you cannot delete posts'
- )
- suspended_error_message = _(
- 'Sorry, since your account is suspended '
- 'you can delete only your own posts'
- )
- low_rep_error_message = _(
- 'Sorry, to delete other people\'s posts, a minimum '
- 'reputation of %(min_rep)s is required'
- ) % \
- {'min_rep': askbot_settings.MIN_REP_TO_DELETE_OTHERS_POSTS}
min_rep_setting = askbot_settings.MIN_REP_TO_DELETE_OTHERS_POSTS
-
-
_assert_user_can(
- user = self,
- post = answer,
- owner_can = True,
- blocked_error_message = blocked_error_message,
- suspended_error_message = suspended_error_message,
- low_rep_error_message = low_rep_error_message,
- min_rep_setting = min_rep_setting,
+ user=self,
+ post=answer,
+ action_display=_('delete posts'),
+ owner_can=True,
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
+ min_rep_setting=min_rep_setting,
)
def user_assert_can_close_question(self, question = None):
assert(getattr(question, 'post_type', '') == 'question')
- blocked_error_message = _(
- 'Sorry, since your account is blocked '
- 'you cannot close questions'
- )
- suspended_error_message = _(
- 'Sorry, since your account is suspended '
- 'you cannot close questions'
- )
- low_rep_error_message = _(
- 'Sorry, to close other people\' posts, a minimum '
- 'reputation of %(min_rep)s is required'
- ) % \
- {'min_rep': askbot_settings.MIN_REP_TO_CLOSE_OTHERS_QUESTIONS}
min_rep_setting = askbot_settings.MIN_REP_TO_CLOSE_OTHERS_QUESTIONS
-
- owner_min_rep_setting = askbot_settings.MIN_REP_TO_CLOSE_OWN_QUESTIONS
-
- owner_low_rep_error_message = _(
- 'Sorry, to close own question '
- 'a minimum reputation of %(min_rep)s is required'
- ) % {'min_rep': owner_min_rep_setting}
-
-
_assert_user_can(
user = self,
post = question,
+ action_display=askbot_settings.WORDS_CLOSE_QUESTIONS,
owner_can = True,
suspended_owner_cannot = True,
- owner_min_rep_setting = owner_min_rep_setting,
- blocked_error_message = blocked_error_message,
- suspended_error_message = suspended_error_message,
- low_rep_error_message = low_rep_error_message,
- owner_low_rep_error_message = owner_low_rep_error_message,
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
min_rep_setting = min_rep_setting,
)
def user_assert_can_reopen_question(self, question = None):
assert(question.post_type == 'question')
-
- #for some reason rep to reopen own questions != rep to close own q's
- owner_min_rep_setting = askbot_settings.MIN_REP_TO_REOPEN_OWN_QUESTIONS
- min_rep_setting = askbot_settings.MIN_REP_TO_CLOSE_OTHERS_QUESTIONS
-
- general_error_message = _(
- 'Sorry, only administrators, moderators '
- 'or post owners with reputation > %(min_rep)s '
- 'can reopen questions.'
- ) % {'min_rep': owner_min_rep_setting }
-
- owner_low_rep_error_message = _(
- 'Sorry, to reopen own question '
- 'a minimum reputation of %(min_rep)s is required'
- ) % {'min_rep': owner_min_rep_setting}
-
- blocked_error_message = _(
- 'Sorry, you cannot reopen questions '
- 'because your account is blocked'
- )
-
- suspended_error_message = _(
- 'Sorry, you cannot reopen questions '
- 'because your account is suspended'
- )
-
_assert_user_can(
- user = self,
- post = question,
- owner_can = True,
- suspended_owner_cannot = True,
- owner_min_rep_setting = owner_min_rep_setting,
- min_rep_setting = min_rep_setting,
- owner_low_rep_error_message = owner_low_rep_error_message,
- general_error_message = general_error_message,
- blocked_error_message = blocked_error_message,
- suspended_error_message = suspended_error_message
+ user=self,
+ post=question,
+ action_display=_('reopen questions'),
+ suspended_owner_cannot=True,
+ #for some reason rep to reopen own questions != rep to close own q's
+ min_rep_setting=askbot_settings.MIN_REP_TO_CLOSE_OTHERS_QUESTIONS,
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
)
@@ -1142,37 +1035,21 @@ def user_assert_can_flag_offensive(self, post = None):
assert(post is not None)
double_flagging_error_message = _(
- 'You have flagged this question before and '
+ 'You have flagged this post before and '
'cannot do it more than once'
)
if self.get_flags_for_post(post).count() > 0:
raise askbot_exceptions.DuplicateCommand(double_flagging_error_message)
- blocked_error_message = _(
- 'Sorry, since your account is blocked '
- 'you cannot flag posts as offensive'
- )
-
- suspended_error_message = _(
- 'Sorry, your account appears to be suspended and you cannot make new posts '
- 'until this issue is resolved. You can, however edit your existing posts. '
- 'Please contact the forum administrator to reach a resolution.'
- )
-
- low_rep_error_message = _(
- 'Sorry, to flag posts as offensive a minimum reputation '
- 'of %(min_rep)s is required'
- ) % \
- {'min_rep': askbot_settings.MIN_REP_TO_FLAG_OFFENSIVE}
min_rep_setting = askbot_settings.MIN_REP_TO_FLAG_OFFENSIVE
_assert_user_can(
user = self,
post = post,
- blocked_error_message = blocked_error_message,
- suspended_error_message = suspended_error_message,
- low_rep_error_message = low_rep_error_message,
+ action_display=_('flag posts as offensive'),
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
min_rep_setting = min_rep_setting
)
#one extra assertion
@@ -1199,28 +1076,13 @@ def user_assert_can_remove_flag_offensive(self, post = None):
if self.get_flags_for_post(post).count() < 1:
raise django_exceptions.PermissionDenied(non_existing_flagging_error_message)
- blocked_error_message = _(
- 'Sorry, since your account is blocked you cannot remove flags'
- )
-
- suspended_error_message = _(
- 'Sorry, your account appears to be suspended and you cannot remove flags. '
- 'Please contact the forum administrator to reach a resolution.'
- )
-
min_rep_setting = askbot_settings.MIN_REP_TO_FLAG_OFFENSIVE
- low_rep_error_message = ungettext(
- 'Sorry, to flag posts a minimum reputation of %(min_rep)d is required',
- 'Sorry, to flag posts a minimum reputation of %(min_rep)d is required',
- min_rep_setting
- ) % {'min_rep': min_rep_setting}
-
_assert_user_can(
user = self,
post = post,
- blocked_error_message = blocked_error_message,
- suspended_error_message = suspended_error_message,
- low_rep_error_message = low_rep_error_message,
+ action_display=_('remove flags'),
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
min_rep_setting = min_rep_setting
)
#one extra assertion
@@ -1250,67 +1112,30 @@ def user_assert_can_remove_all_flags_offensive(self, post = None):
def user_assert_can_retag_question(self, question = None):
if question.deleted == True:
- try:
- self.assert_can_edit_deleted_post(question)
- except django_exceptions.PermissionDenied:
- error_message = _(
- 'Sorry, only question owners, '
- 'site administrators and moderators '
- 'can retag deleted questions'
- )
- raise django_exceptions.PermissionDenied(error_message)
-
-
- blocked_error_message = _(
- 'Sorry, since your account is blocked '
- 'you cannot retag questions'
- )
- suspended_error_message = _(
- 'Sorry, since your account is suspended '
- 'you can retag only your own questions'
- )
- low_rep_error_message = _(
- 'Sorry, to retag questions a minimum '
- 'reputation of %(min_rep)s is required'
- ) % \
- {'min_rep': askbot_settings.MIN_REP_TO_RETAG_OTHERS_QUESTIONS}
- min_rep_setting = askbot_settings.MIN_REP_TO_RETAG_OTHERS_QUESTIONS
+ self.assert_can_edit_deleted_post(question)
_assert_user_can(
- user = self,
- post = question,
- owner_can = True,
- blocked_error_message = blocked_error_message,
- suspended_error_message = suspended_error_message,
- low_rep_error_message = low_rep_error_message,
- min_rep_setting = min_rep_setting,
+ user=self,
+ post=question,
+ action_display=askbot_settings.WORDS_RETAG_QUESTIONS,
+ owner_can=True,
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
+ min_rep_setting=askbot_settings.MIN_REP_TO_RETAG_OTHERS_QUESTIONS
)
def user_assert_can_delete_comment(self, comment = None):
- blocked_error_message = _(
- 'Sorry, since your account is blocked '
- 'you cannot delete comment'
- )
- suspended_error_message = _(
- 'Sorry, since your account is suspended '
- 'you can delete only your own comments'
- )
- low_rep_error_message = _(
- 'Sorry, to delete comments '
- 'reputation of %(min_rep)s is required'
- ) % \
- {'min_rep': askbot_settings.MIN_REP_TO_DELETE_OTHERS_COMMENTS}
min_rep_setting = askbot_settings.MIN_REP_TO_DELETE_OTHERS_COMMENTS
_assert_user_can(
user = self,
post = comment,
+ action_display=_('delete comments'),
owner_can = True,
- blocked_error_message = blocked_error_message,
- suspended_error_message = suspended_error_message,
- low_rep_error_message = low_rep_error_message,
+ blocked_user_cannot=True,
+ suspended_user_cannot=True,
min_rep_setting = min_rep_setting,
)
@@ -1418,12 +1243,15 @@ def user_post_anonymous_askbot_content(user, session_key):
aa.save()
#maybe add pending posts message?
else:
- if user.is_blocked():
- msg = get_i18n_message('BLOCKED_USERS_CANNOT_POST')
- user.message_set.create(message = msg)
- elif user.is_suspended():
- msg = get_i18n_message('SUSPENDED_USERS_CANNOT_POST')
- user.message_set.create(message = msg)
+ if user.is_blocked() or user.is_suspended():
+ if user.is_blocked():
+ account_status = _('your account is blocked')
+ elif user.is_suspended():
+ account_status = _('your account is suspended')
+ user.message_set.create(message = _(message_keys.ACCOUNT_CANNOT_PERFORM_ACTION) % {
+ 'perform_action': _('make posts'),
+ 'your_account_is': account_status
+ })
else:
for aq in aq_list:
aq.publish(user)
@@ -2053,9 +1881,13 @@ def user_post_answer(
left = ungettext('in %(min)d min','in %(min)d mins',minutes) % {'min':minutes}
day = ungettext('%(days)d day','%(days)d days',askbot_settings.MIN_DAYS_TO_ANSWER_OWN_QUESTION) % {'days':askbot_settings.MIN_DAYS_TO_ANSWER_OWN_QUESTION}
error_message = _(
- 'New users must wait %(days)s before answering their own question. '
+ 'New users must wait %(days)s to %(answer_own_questions)s. '
' You can post an answer %(left)s'
- ) % {'days': day,'left': left}
+ ) % {
+ 'days': day,
+ 'left': left,
+ 'answer_own_questions': askbot_settings.WORDS_ANSWER_OWN_QUESTIONS
+ }
assert(error_message is not None)
raise django_exceptions.PermissionDenied(error_message)
@@ -2498,11 +2330,12 @@ def user_get_primary_group(self):
first non-personal non-everyone group
works only for one real private group per-person
"""
- groups = self.get_groups(private=True)
- for group in groups:
- if group.is_personal():
- continue
- return group
+ if askbot_settings.GROUPS_ENABLED:
+ groups = self.get_groups(private=True)
+ for group in groups:
+ if group.is_personal():
+ continue
+ return group
return None
def user_can_make_group_private_posts(self):
@@ -2754,7 +2587,7 @@ def user_is_following_question(user, question):
return question.thread.followed_by.filter(id=user.id).exists()
-def upvote(self, post, timestamp=None, cancel=False, force = False):
+def upvote(self, post, timestamp=None, cancel=False, force=False):
#force parameter not used yet
return _process_vote(
self,
@@ -2764,7 +2597,7 @@ def upvote(self, post, timestamp=None, cancel=False, force = False):
vote_type=Vote.VOTE_UP
)
-def downvote(self, post, timestamp=None, cancel=False, force = False):
+def downvote(self, post, timestamp=None, cancel=False, force=False):
#force not used yet
return _process_vote(
self,
@@ -3097,6 +2930,7 @@ User.add_to_class('has_interesting_wildcard_tags', user_has_interesting_wildcard
User.add_to_class('has_ignored_wildcard_tags', user_has_ignored_wildcard_tags)
User.add_to_class('can_moderate_user', user_can_moderate_user)
User.add_to_class('has_affinity_to_question', user_has_affinity_to_question)
+User.add_to_class('has_badge', user_has_badge)
User.add_to_class('moderate_user_reputation', user_moderate_user_reputation)
User.add_to_class('set_status', user_set_status)
User.add_to_class('get_badge_summary', user_get_badge_summary)
@@ -3209,13 +3043,13 @@ def format_instant_notification_email(
)
#todo: remove hardcoded style
else:
- content_preview = post.format_for_email(is_leaf_post = True)
+ content_preview = post.format_for_email(is_leaf_post=True, recipient=to_user)
#add indented summaries for the parent posts
- content_preview += post.format_for_email_as_parent_thread_summary()
+ content_preview += post.format_for_email_as_parent_thread_summary(recipient=to_user)
#content_preview += '<p>======= Full thread summary =======</p>'
- #content_preview += post.thread.format_for_email(user=to_user)
+ #content_preview += post.thread.format_for_email(recipient=to_user)
if update_type == 'post_shared':
user_action = _('%(user)s shared a %(post_link)s.')
@@ -3239,10 +3073,22 @@ def format_instant_notification_email(
post_url = site_url(post.get_absolute_url())
user_url = site_url(from_user.get_absolute_url())
+
+ if to_user.is_administrator_or_moderator() and askbot_settings.SHOW_ADMINS_PRIVATE_USER_DATA:
+ user_link_fmt = '<a href="%(profile_url)s">%(username)s</a> (<a href="mailto:%(email)s">%(email)s</a>)'
+ user_link = user_link_fmt % {
+ 'profile_url': user_url,
+ 'username': from_user.username,
+ 'email': from_user.email
+ }
+ elif post.is_anonymous:
+ user_link = from_user.get_name_of_anonymous_user()
+ else:
+ user_link = '<a href="%s">%s</a>' % (user_url, from_user.username)
+
user_action = user_action % {
- 'user': '<a href="%s">%s</a>' % (user_url, from_user.username),
+ 'user': user_link,
'post_link': '<a href="%s">%s</a>' % (post_url, _(post.post_type))
- #'post_link': '%s <a href="%s">>>></a>' % (_(post.post_type), post_url)
}
can_reply = to_user.can_post_by_email()
@@ -3709,6 +3555,10 @@ def greet_new_user(user, **kwargs):
if askbot_settings.NEW_USER_GREETING:
user.message_set.create(message = askbot_settings.NEW_USER_GREETING)
+ import sys
+ if 'test' in sys.argv:
+ return
+
if askbot_settings.REPLY_BY_EMAIL:#with this on we also collect signature
template_name = 'email/welcome_lamson_on.html'
else:
@@ -3786,22 +3636,17 @@ def set_user_avatar_type_flag(instance, created, **kwargs):
def update_user_avatar_type_flag(instance, **kwargs):
instance.user.update_avatar_type()
-def make_admin_if_first_user(instance, **kwargs):
+def make_admin_if_first_user(user, **kwargs):
"""first user automatically becomes an administrator
the function is run only once in the interpreter session
+
+ function is run when user registers
"""
import sys
- #have to check sys.argv to satisfy the test runner
- #which fails with the cache-based skipping
- #for real the setUp() code in the base test case must
- #clear the cache!!!
- if 'test' not in sys.argv and cache.cache.get('admin-created'):
- #no need to hit the database every time!
- return
user_count = User.objects.all().count()
- if user_count == 0:
- instance.set_admin_status()
- cache.cache.set('admin-created', True)
+ if user_count == 1:
+ user.set_admin_status()
+ user.save()
def moderate_group_joining(sender, instance=None, created=False, **kwargs):
if created and instance.level == GroupMembership.PENDING:
@@ -3819,8 +3664,14 @@ def tweet_new_post(sender, user=None, question=None, answer=None, form_data=None
post = question or answer
tweet_new_post_task.delay(post.id)
+def init_badge_data(sender, created_models=None, **kwargs):
+ if BadgeData in created_models:
+ from askbot.models import badges
+ badges.init_badges()
+
+django_signals.post_syncdb.connect(init_badge_data)
+
#signal for User model save changes
-django_signals.pre_save.connect(make_admin_if_first_user, sender=User)
django_signals.pre_save.connect(calculate_gravatar_hash, sender=User)
django_signals.post_save.connect(add_missing_subscriptions, sender=User)
django_signals.post_save.connect(add_user_to_global_group, sender=User)
@@ -3846,6 +3697,7 @@ signals.flag_offensive.connect(record_flag_offensive, sender=Post)
signals.remove_flag_offensive.connect(remove_flag_offensive, sender=Post)
signals.tags_updated.connect(record_update_tags)
signals.user_registered.connect(greet_new_user)
+signals.user_registered.connect(make_admin_if_first_user)
signals.user_updated.connect(record_user_full_updated, sender=User)
signals.user_logged_in.connect(complete_pending_tag_subscriptions)#todo: add this to fake onlogin middleware
signals.user_logged_in.connect(post_anonymous_askbot_content)
@@ -3894,6 +3746,9 @@ __all__ = [
'User',
'ReplyAddress',
+
+ 'ImportRun',
+ 'ImportedObjectInfo',
'get_model',
]
diff --git a/askbot/models/badges.py b/askbot/models/badges.py
index 244c8e2f..44eda0c3 100644
--- a/askbot/models/badges.py
+++ b/askbot/models/badges.py
@@ -21,10 +21,8 @@ import datetime
from django.template.defaultfilters import slugify
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
+from django.utils.translation import ungettext
from django.dispatch import Signal
-from askbot.models.repute import BadgeData, Award
-from askbot.models.user import Activity
-from askbot.models.question import FavoriteQuestion as Fave#name collision
from askbot.models.post import Post
from askbot import const
from askbot.conf import settings as askbot_settings
@@ -57,6 +55,7 @@ class Badge(object):
self.css_class = const.BADGE_CSS_CLASSES[self.level]
def get_stored_data(self):
+ from askbot.models.repute import BadgeData
data, created = BadgeData.objects.get_or_create(slug = self.key)
return data
@@ -86,7 +85,7 @@ class Badge(object):
def award(self, recipient = None, context_object = None, timestamp = None):
"""do award, the recipient was proven to deserve"""
-
+ from askbot.models.repute import Award
if self.multiple == False:
if recipient.badges.filter(slug = self.key).count() != 0:
return False
@@ -171,8 +170,11 @@ class PeerPressure(Badge):
class Teacher(Badge):
def __init__(self):
description = _(
- 'Received at least %(votes)s upvote for an answer for the first time'
- ) % {'votes': askbot_settings.TEACHER_BADGE_MIN_UPVOTES}
+ 'Gave an %(answer_voted_up)s at least %(votes)s times for the first time'
+ ) % {
+ 'votes': askbot_settings.TEACHER_BADGE_MIN_UPVOTES,
+ 'answer_voted_up': askbot_settings.WORDS_ANSWER_VOTED_UP
+ }
super(Teacher, self).__init__(
key = 'teacher',
name = _('Teacher'),
@@ -186,7 +188,7 @@ class Teacher(Badge):
if context_object.post_type != 'answer':
return False
- if context_object.points>= askbot_settings.TEACHER_BADGE_MIN_UPVOTES:
+ if context_object.points >= askbot_settings.TEACHER_BADGE_MIN_UPVOTES:
return self.award(context_object.author, context_object, timestamp)
return False
@@ -249,14 +251,16 @@ class CivicDuty(Badge):
class SelfLearner(Badge):
def __init__(self):
- description = _('Answered own question with at least %(num)s up votes')
- min_votes = askbot_settings.SELF_LEARNER_BADGE_MIN_UPVOTES
+ description = _('%(answered_own_question)s with at least %(num)s up votes') % {
+ 'num': askbot_settings.SELF_LEARNER_BADGE_MIN_UPVOTES,
+ 'answered_own_question': askbot_settings.WORDS_ANSWERED_OWN_QUESTION
+ }
super(SelfLearner, self).__init__(
- key = 'self-learner',
- name = _('Self-Learner'),
- description = description % {'num': min_votes},
- level = const.BRONZE_BADGE,
- multiple = True
+ key='self-learner',
+ name=_('Self-Learner'),
+ description=description,
+ level=const.BRONZE_BADGE,
+ multiple=True
)
def consider_award(self, actor = None,
@@ -301,72 +305,90 @@ class QualityPost(Badge):
class NiceAnswer(QualityPost):
def __new__(cls):
self = super(NiceAnswer, cls).__new__(cls)
- self.name = _('Nice Answer')
+ self.name = askbot_settings.WORDS_NICE_ANSWER
self.key = 'nice-answer'
self.level = const.BRONZE_BADGE
self.multiple = True
self.min_votes = askbot_settings.NICE_ANSWER_BADGE_MIN_UPVOTES
- self.description = _('Answer voted up %(num)s times') % {'num': self.min_votes}
+ self.description = _('%(answer_voted_up)s %(num)s times') % {
+ 'num': self.min_votes,
+ 'answer_voted_up': askbot_settings.WORDS_ANSWER_VOTED_UP
+ }
self.post_type = 'answer'
return self
class GoodAnswer(QualityPost):
def __new__(cls):
self = super(GoodAnswer, cls).__new__(cls)
- self.name = _('Good Answer')
+ self.name = askbot_settings.WORDS_GOOD_ANSWER
self.key = 'good-answer'
self.level = const.SILVER_BADGE
self.multiple = True
self.min_votes = askbot_settings.GOOD_ANSWER_BADGE_MIN_UPVOTES
- self.description = _('Answer voted up %(num)s times') % {'num': self.min_votes}
+ self.description = _('%(answer_voted_up)s %(num)s times') % {
+ 'num': self.min_votes,
+ 'answer_voted_up': askbot_settings.WORDS_ANSWER_VOTED_UP
+ }
self.post_type = 'answer'
return self
class GreatAnswer(QualityPost):
def __new__(cls):
self = super(GreatAnswer, cls).__new__(cls)
- self.name = _('Great Answer')
+ self.name = askbot_settings.WORDS_GREAT_ANSWER
self.key = 'great-answer'
self.level = const.GOLD_BADGE
self.multiple = True
self.min_votes = askbot_settings.GREAT_ANSWER_BADGE_MIN_UPVOTES
- self.description = _('Answer voted up %(num)s times') % {'num': self.min_votes}
+ self.description = _('%(answer_voted_up)s %(num)s times') % {
+ 'num': self.min_votes,
+ 'answer_voted_up': askbot_settings.WORDS_ANSWER_VOTED_UP
+ }
self.post_type = 'answer'
return self
class NiceQuestion(QualityPost):
def __new__(cls):
self = super(NiceQuestion, cls).__new__(cls)
- self.name = _('Nice Question')
+ self.name = askbot_settings.WORDS_NICE_QUESTION
self.key = 'nice-question'
self.level = const.BRONZE_BADGE
self.multiple = True
self.min_votes = askbot_settings.NICE_QUESTION_BADGE_MIN_UPVOTES
- self.description = _('Question voted up %(num)s times') % {'num': self.min_votes}
+ self.description = _('%(question_voted_up)s up %(num)s times') % {
+ 'num': self.min_votes,
+ 'question_voted_up': askbot_settings.WORDS_QUESTION_VOTED_UP
+ }
self.post_type = 'question'
return self
class GoodQuestion(QualityPost):
def __new__(cls):
self = super(GoodQuestion, cls).__new__(cls)
- self.name = _('Good Question')
+ self.name = askbot_settings.WORDS_GOOD_QUESTION
self.key = 'good-question'
self.level = const.SILVER_BADGE
self.multiple = True
self.min_votes = askbot_settings.GOOD_QUESTION_BADGE_MIN_UPVOTES
- self.description = _('Question voted up %(num)s times') % {'num': self.min_votes}
+ self.description = _('%(question_voted_up)s up %(num)s times') % {
+ 'num': self.min_votes,
+ 'question_voted_up': askbot_settings.WORDS_QUESTION_VOTED_UP
+ }
self.post_type = 'question'
return self
class GreatQuestion(QualityPost):
def __new__(cls):
self = super(GreatQuestion, cls).__new__(cls)
- self.name = _('Great Question')
+ self.name = askbot_settings.WORDS_GREAT_QUESTION
self.key = 'great-question'
self.level = const.GOLD_BADGE
self.multiple = True
self.min_votes = askbot_settings.GREAT_QUESTION_BADGE_MIN_UPVOTES
- self.description = _('Question voted up %(num)s times') % {'num': self.min_votes}
+ self.description = _('%(question_voted_up)s %(num)s times') % {
+ 'num': self.min_votes,
+ 'question_voted_up': askbot_settings.WORDS_QUESTION_VOTED_UP
+ }
self.post_type = 'question'
return self
@@ -378,7 +400,9 @@ class Student(QualityPost):
self.level = const.BRONZE_BADGE
self.multiple = False
self.min_votes = 1
- self.description = _('Asked first question with at least one up vote')
+ self.description = _('%(asked_first_question)s with at least one up vote') % {
+ 'asked_first_question': askbot_settings.WORDS_ASKED_FIRST_QUESTION
+ }
self.post_type = 'question'
return self
@@ -411,35 +435,41 @@ class FrequentedQuestion(Badge):
class PopularQuestion(FrequentedQuestion):
def __new__(cls):
self = super(PopularQuestion, cls).__new__(cls)
- self.name = _('Popular Question')
+ self.name = askbot_settings.WORDS_POPULAR_QUESTION
self.key = 'popular-question'
self.level = const.BRONZE_BADGE
self.min_views = askbot_settings.POPULAR_QUESTION_BADGE_MIN_VIEWS
- self.description = _('Asked a question with %(views)s views') \
- % {'views' : self.min_views}
+ self.description = _('%(asked_a_question)s with %(views)s views') % {
+ 'views' : self.min_views,
+ 'asked_a_question': askbot_settings.WORDS_ASKED_A_QUESTION
+ }
return self
class NotableQuestion(FrequentedQuestion):
def __new__(cls):
self = super(NotableQuestion, cls).__new__(cls)
- self.name = _('Notable Question')
+ self.name = askbot_settings.WORDS_NOTABLE_QUESTION
self.key = 'notable-question'
self.level = const.SILVER_BADGE
self.min_views = askbot_settings.NOTABLE_QUESTION_BADGE_MIN_VIEWS
- self.description = _('Asked a question with %(views)s views') \
- % {'views' : self.min_views}
+ self.description = _('%(asked_a_question)s with %(views)s views') % {
+ 'views' : self.min_views,
+ 'asked_a_question': askbot_settings.WORDS_ASKED_A_QUESTION
+ }
return self
class FamousQuestion(FrequentedQuestion):
def __new__(cls):
self = super(FamousQuestion, cls).__new__(cls)
- self.name = _('Famous Question')
+ self.name = askbot_settings.WORDS_FAMOUS_QUESTION
self.key = 'famous-question'
self.level = const.GOLD_BADGE
self.multiple = True
self.min_views = askbot_settings.FAMOUS_QUESTION_BADGE_MIN_VIEWS
- self.description = _('Asked a question with %(views)s views') \
- % {'views' : self.min_views}
+ self.description = _('%(asked_a_question)s with %(views)s views') % {
+ 'views' : self.min_views,
+ 'asked_a_question': askbot_settings.WORDS_ASKED_A_QUESTION
+ }
return self
class Scholar(Badge):
@@ -447,7 +477,10 @@ class Scholar(Badge):
he/she accepts an answer for the first time
"""
def __init__(self):
- description = _('Asked a question and accepted an answer')
+ description = _('%(asked_a_question)s and %(accepted_an_answer)s') % {
+ 'asked_a_question': askbot_settings.WORDS_ASKED_A_QUESTION,
+ 'accepted_an_answer': askbot_settings.WORDS_ACCEPTED_AN_ANSWER
+ }
super(Scholar, self).__init__(
key = 'scholar',
name = _('Scholar'),
@@ -496,8 +529,11 @@ class Enlightened(VotedAcceptedAnswer):
self.level = const.SILVER_BADGE
self.multiple = False
self.min_votes = askbot_settings.ENLIGHTENED_BADGE_MIN_UPVOTES
- descr = _('First answer was accepted with %(num)s or more votes')
- self.description = descr % {'num': self.min_votes}
+ descr = _('%(gave_accepted_answer)s upvoted %(num)s or more times')
+ self.description = descr % {
+ 'num': self.min_votes,
+ 'gave_accepted_answer': askbot_settings.WORDS_GAVE_ACCEPTED_ANSWER
+ }
return self
class Guru(VotedAcceptedAnswer):
@@ -507,24 +543,31 @@ class Guru(VotedAcceptedAnswer):
self.name = _('Guru')
self.level = const.GOLD_BADGE
self.multiple = True
- descr = _('Answer accepted with %(num)s or more votes')
self.min_votes = askbot_settings.GURU_BADGE_MIN_UPVOTES
- self.description = descr % {'num': self.min_votes}
+ descr = _('%(gave_accepted_answer)s upvoted %(num)s or more times')
+ self.description = descr % {
+ 'num': self.min_votes,
+ 'gave_accepted_answer': askbot_settings.WORDS_GAVE_ACCEPTED_ANSWER
+ }
return self
class Necromancer(Badge):
def __init__(self):
- description = _(
- 'Answered a question more than %(days)s days '
- 'later with at least %(votes)s votes'
- )
days = askbot_settings.NECROMANCER_BADGE_MIN_DELAY
votes = askbot_settings.NECROMANCER_BADGE_MIN_UPVOTES
+ description = _(
+ '%(answered_a_question)s more than %(days)s days '
+ 'later with at least %(votes)s votes'
+ ) % {
+ 'days':days,
+ 'votes':votes,
+ 'answered_a_question': askbot_settings.WORDS_ANSWERED_A_QUESTION
+ }
super(Necromancer, self).__init__(
key = 'necromancer',
name = _('Necromancer'),
level = const.SILVER_BADGE,
- description = description % {'days':days, 'votes':votes},
+ description = description,
multiple = True
)
@@ -602,6 +645,7 @@ class EditorTypeBadge(Badge):
const.TYPE_ACTIVITY_UPDATE_ANSWER
)
filters = {'user': actor, 'activity_type__in': atypes}
+ from askbot.models.user import Activity
if Activity.objects.filter(**filters).count() == self.min_edits:
return self.award(actor, context_object, timestamp)
@@ -660,19 +704,25 @@ class FavoriteTypeBadge(Badge):
must provide min_stars property for the badge
"""
def __init__(self):
- descr = _('Question favorited by %(num)s users')
+ description = _(
+ '%(asked_a_question)s with %(num)s followers'
+ ) % {
+ 'num': self.min_stars,
+ 'asked_a_question': askbot_settings.WORDS_ASKED_A_QUESTION
+ }
super(FavoriteTypeBadge, self).__init__(
- key = self.key,
- name = self.name,
- level = self.level,
- multiple = True,
- description = descr % {'num': self.min_stars}
+ key=self.key,
+ name=self.name,
+ level=self.level,
+ multiple=True,
+ description=description
)
def consider_award(self, actor = None,
context_object = None, timestamp = None):
question = context_object
#model FavoriteQuestion imported under alias of Fave
+ from askbot.models.question import FavoriteQuestion as Fave#name collision
count = Fave.objects.filter(
thread = question.thread
).exclude(
@@ -686,7 +736,7 @@ class StellarQuestion(FavoriteTypeBadge):
def __new__(cls):
self = super(StellarQuestion, cls).__new__(cls)
self.key = 'stellar-question'
- self.name = _('Stellar Question')
+ self.name = askbot_settings.WORDS_STELLAR_QUESTION
self.level = const.GOLD_BADGE
self.min_stars = askbot_settings.STELLAR_QUESTION_BADGE_MIN_STARS
return self
@@ -695,7 +745,7 @@ class FavoriteQuestion(FavoriteTypeBadge):
def __new__(cls):
self = super(FavoriteQuestion, cls).__new__(cls)
self.key = 'favorite-question'
- self.name = _('Favorite Question')
+ self.name = askbot_settings.WORDS_FAVORITE_QUESTION
self.level = const.SILVER_BADGE
self.min_stars = askbot_settings.FAVORITE_QUESTION_BADGE_MIN_STARS
return self
@@ -752,8 +802,10 @@ class Taxonomist(Badge):
name = _('Taxonomist'),
level = const.SILVER_BADGE,
multiple = False,
- description = _(
- 'Created a tag used by %(num)s questions'
+ description = ungettext(
+ 'Created a tag used %(num)s time',
+ 'Created a tag used %(num)s times',
+ askbot_settings.TAXONOMIST_BADGE_MIN_USE_COUNT
) % {'num': askbot_settings.TAXONOMIST_BADGE_MIN_USE_COUNT}
)
@@ -880,6 +932,7 @@ def init_badges():
get_badge(key).get_stored_data()
#remove any badges from the database
#that are no longer in the BADGES dictionary
+ from askbot.models.repute import BadgeData
BadgeData.objects.exclude(
slug__in = map(slugify, BADGES.keys())
).delete()
diff --git a/askbot/models/meta.py b/askbot/models/meta.py
new file mode 100644
index 00000000..013e918a
--- /dev/null
+++ b/askbot/models/meta.py
@@ -0,0 +1,32 @@
+"""Models that are not essential to operation of
+an askbot instance, but may be used in some cases.
+Data in these models can be erased without loss of function.
+"""
+from django.db import models
+from picklefield.fields import PickledObjectField
+
+class ImportRun(models.Model):
+ """records information about the data import run"""
+ command = models.TextField(default='')
+ timestamp = models.DateTimeField(auto_now_add=True)
+
+ class Meta:
+ app_label = 'askbot'
+
+class ImportedObjectInfo(models.Model):
+ """records data about objects imported into askbot
+ from other sources.
+ This is useful to create redirect urls when object id's change
+ """
+ old_id = models.IntegerField(help_text='Old object id in the source database')
+ new_id = models.IntegerField(help_text='New object id in the current database')
+ model = models.CharField(
+ default='',
+ help_text='dotted python path to model',
+ max_length=255
+ )
+ run = models.ForeignKey(ImportRun)
+ extra_info = PickledObjectField(help_text='to hold dictionary for various data')
+
+ class Meta:
+ app_label = 'askbot'
diff --git a/askbot/models/post.py b/askbot/models/post.py
index 906cba1e..7ab0b524 100644
--- a/askbot/models/post.py
+++ b/askbot/models/post.py
@@ -25,10 +25,6 @@ import askbot
from askbot.utils.slug import slugify
from askbot import const
-from askbot.models.user import Activity
-from askbot.models.user import EmailFeedSetting
-from askbot.models.user import Group
-from askbot.models.user import GroupMembership
from askbot.models.tag import Tag, MarkedTag
from askbot.models.tag import tags_match_some_wildcard
from askbot.conf import settings as askbot_settings
@@ -46,7 +42,7 @@ from askbot.search import mysql
class PostToGroup(models.Model):
post = models.ForeignKey('Post')
- group = models.ForeignKey(Group)
+ group = models.ForeignKey('Group')
class Meta:
unique_together = ('post', 'group')
@@ -62,6 +58,7 @@ class PostQuerySet(models.query.QuerySet):
#as all methods on this class seem to want to
#belong to Thread manager or Query set.
def get_for_user(self, user):
+ from askbot.models.user import Group
if askbot_settings.GROUPS_ENABLED:
if user is None or user.is_anonymous():
groups = [Group.objects.get_global_group()]
@@ -347,7 +344,7 @@ class Post(models.Model):
parent = models.ForeignKey('Post', blank=True, null=True, related_name='comments') # Answer or Question for Comment
thread = models.ForeignKey('Thread', blank=True, null=True, default = None, related_name='posts')
- groups = models.ManyToManyField(Group, through='PostToGroup', related_name = 'group_posts')#used for group-private posts
+ groups = models.ManyToManyField('Group', through='PostToGroup', related_name = 'group_posts')#used for group-private posts
author = models.ForeignKey(User, related_name='posts')
added_at = models.DateTimeField(default=datetime.datetime.now)
@@ -415,9 +412,9 @@ class Post(models.Model):
"""
url = site_url(self.get_absolute_url(no_slug=True))
if self.post_type == 'question':
- tweet = _('Question: ')
+ tweet = askbot_settings.WORDS_QUESTION_SINGULAR + ': '
elif self.post_type == 'answer':
- tweet = _('Answer: ')
+ tweet = askbot_settings.WORDS_ANSWER_SINGULAR + ': '
chars_left = 140 - (len(url) + len(tweet) + 1)
title_str = self.thread.title[:chars_left]
@@ -449,10 +446,14 @@ class Post(models.Model):
removed_mentions = list()
if '@' in text:
op = self.get_origin_post()
- anticipated_authors = op.get_author_list(
- include_comments = True,
- recursive = True
- )
+
+ if op.id:
+ anticipated_authors = op.get_author_list(
+ include_comments = True,
+ recursive = True
+ )
+ else:
+ anticipated_authors = list()
extra_name_seeds = markup.extract_mentioned_name_seeds(text)
@@ -504,7 +505,6 @@ class Post(models.Model):
"""generic method to use with posts to be used prior to saving
post edit or addition
"""
-
assert(author is not None)
last_revision = self.html
@@ -643,6 +643,7 @@ class Post(models.Model):
#vip groups to the list behind the scenes.
groups = list(groups)
#add moderator groups to the post implicitly
+ from askbot.models.user import Group
vips = Group.objects.filter(is_vip=True)
groups.extend(vips)
#todo: use bulk-creation
@@ -688,6 +689,7 @@ class Post(models.Model):
else:
summary = self.get_snippet()
+ from askbot.models import Activity
update_activity = Activity(
user = updated_by,
active_at = timestamp,
@@ -701,6 +703,7 @@ class Post(models.Model):
update_activity.add_recipients(notify_sets['for_inbox'])
#create new mentions (barring the double-adds)
+ from askbot.models import Activity
for u in notify_sets['for_mentions'] - notify_sets['for_inbox']:
Activity.objects.create_new_mention(
mentioned_whom = u,
@@ -740,6 +743,7 @@ class Post(models.Model):
"""makes post private within user's groups
todo: this is a copy-paste in thread and post
"""
+ from askbot.models.user import Group
if group_id:
group = Group.objects.get(id=group_id)
groups = [group]
@@ -767,12 +771,14 @@ class Post(models.Model):
def make_public(self):
"""removes the privacy mark from users groups"""
+ from askbot.models.user import Group
groups = (Group.objects.get_global_group(),)
self.add_to_groups(groups)
def is_private(self):
"""true, if post belongs to the global group"""
if askbot_settings.GROUPS_ENABLED:
+ from askbot.models.user import Group
group = Group.objects.get_global_group()
return not self.groups.filter(id=group.id).exists()
return False
@@ -895,9 +901,9 @@ class Post(models.Model):
"""
if max_length is None:
if self.post_type == 'comment':
- max_words = 30
+ max_words = 150
else:
- max_words = 100
+ max_words = 500
else:
max_words = int(max_length/5)
@@ -936,6 +942,7 @@ class Post(models.Model):
return list()
#load group memberships for the candidates
+ from askbot.models.user import GroupMembership
memberships = GroupMembership.objects.filter(
user__in=candidates,
group__in=groups
@@ -951,7 +958,8 @@ class Post(models.Model):
return filtered_candidates
def format_for_email(
- self, quote_level=0, is_leaf_post=False, format=None
+ self, quote_level=0, is_leaf_post=False, format=None,
+ recipient=None
):
"""format post for the output in email,
if quote_level > 0, the post will be indented that number of times
@@ -962,13 +970,14 @@ class Post(models.Model):
template = get_template('email/quoted_post.html')
data = {
'post': self,
+ 'recipient': recipient,
'quote_level': quote_level,
'is_leaf_post': is_leaf_post,
'format': format
}
return template.render(Context(data))#todo: set lang
- def format_for_email_as_parent_thread_summary(self):
+ def format_for_email_as_parent_thread_summary(self, recipient=None):
"""format for email as summary of parent posts
all the way to the original question"""
quote_level = 0
@@ -980,20 +989,25 @@ class Post(models.Model):
break
quote_level += 1
output += parent_post.format_for_email(
- quote_level = quote_level,
- format = 'parent_subthread'
+ quote_level=quote_level,
+ format='parent_subthread',
+ recipient=recipient
)
current_post = parent_post
return output
- def format_for_email_as_subthread(self):
+ def format_for_email_as_subthread(self, recipient=None):
"""outputs question or answer and all it's comments
returns empty string for all other post types
"""
from django.template import Context
from django.template.loader import get_template
template = get_template('email/post_as_subthread.html')
- return template.render(Context({'post': self}))#todo: set lang
+ data = {
+ 'post': self,
+ 'recipient': recipient
+ }
+ return template.render(Context(data))#todo: set lang
def set_cached_comments(self, comments):
"""caches comments in the lifetime of the object
@@ -1138,6 +1152,7 @@ class Post(models.Model):
"""
subscriber_set = set()
+ from askbot.models.user import EmailFeedSetting
global_subscriptions = EmailFeedSetting.objects.filter(
feed_type = 'q_all',
frequency = 'i'
@@ -1215,6 +1230,7 @@ class Post(models.Model):
#print 'potential subscribers: ', potential_subscribers
#1) mention subscribers - common to questions and answers
+ from askbot.models.user import EmailFeedSetting
if mentioned_users:
mention_subscribers = EmailFeedSetting.objects.filter_subscribers(
potential_subscribers = mentioned_users,
@@ -1308,6 +1324,7 @@ class Post(models.Model):
if mentioned_users:
potential_subscribers.update(mentioned_users)
+ from askbot.models.user import EmailFeedSetting
if potential_subscribers:
comment_subscribers = EmailFeedSetting.objects.filter_subscribers(
potential_subscribers = potential_subscribers,
@@ -1459,6 +1476,8 @@ class Post(models.Model):
)
elif user.email_tag_filter_strategy == const.INCLUDE_ALL:
return True
+ elif user.email_tag_filter_strategy == const.INCLUDE_SUBSCRIBED:
+ return user.has_affinity_to_question(question, affinity_type='like')
else:
raise ValueError(
'unexpected User.email_tag_filter_strategy %s'\
@@ -1598,10 +1617,7 @@ class Post(models.Model):
if self.is_approved() is False:
raise exceptions.QuestionHidden()
if self.deleted:
- message = _(
- 'Sorry, this question has been '
- 'deleted and is no longer accessible'
- )
+ message = _('Sorry, this content is no longer available')
if user.is_anonymous():
raise exceptions.QuestionHidden(message)
try:
@@ -1614,17 +1630,10 @@ class Post(models.Model):
try:
self.thread._question_post().assert_is_visible_to(user)
except exceptions.QuestionHidden:
- message = _(
- 'Sorry, the answer you are looking for is '
- 'no longer available, because the parent '
- 'question has been removed'
- )
+ message = _('Sorry, this content is no longer available')
raise exceptions.QuestionHidden(message)
if self.deleted:
- message = _(
- 'Sorry, this answer has been '
- 'removed and is no longer accessible'
- )
+ message = _('Sorry, this content is no longer available')
if user.is_anonymous():
raise exceptions.AnswerHidden(message)
try:
@@ -1637,18 +1646,10 @@ class Post(models.Model):
try:
self.parent.assert_is_visible_to(user)
except exceptions.QuestionHidden:
- message = _(
- 'Sorry, the comment you are looking for is no '
- 'longer accessible, because the parent question '
- 'has been removed'
- )
+ message = _('Sorry, this comment is no longer available')
raise exceptions.QuestionHidden(message)
except exceptions.AnswerHidden:
- message = _(
- 'Sorry, the comment you are looking for is no '
- 'longer accessible, because the parent answer '
- 'has been removed'
- )
+ message = _('Sorry, this comment is no longer available')
raise exceptions.AnswerHidden(message)
def assert_is_visible_to_user_groups(self, user):
@@ -2135,6 +2136,7 @@ class PostRevision(models.Model):
#if sent by email to group and group does not want moderation
if self.by_email and self.email_address:
group_name = self.email_address.split('@')[0]
+ from askbot.models.user import Group
try:
group = Group.objects.get(name = group_name, deleted = False)
return group.group.profile.moderate_email
diff --git a/askbot/models/question.py b/askbot/models/question.py
index fe68870a..5455b927 100644
--- a/askbot/models/question.py
+++ b/askbot/models/question.py
@@ -14,6 +14,7 @@ from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
from django.utils.translation import string_concat
from django.utils.translation import get_language
+from django.utils.translation import activate as activate_language
import askbot
from askbot.conf import settings as askbot_settings
@@ -24,8 +25,6 @@ from askbot.models.tag import get_tags_by_names
from askbot.models.tag import filter_accepted_tags, filter_suggested_tags
from askbot.models.tag import separate_unused_tags
from askbot.models.base import DraftContent, BaseQuerySetManager
-from askbot.models.post import Post, PostRevision
-from askbot.models.post import PostToGroup
from askbot.models.user import Group, PERSONAL_GROUP_NAME_PREFIX
from askbot.models import signals
from askbot import const
@@ -34,6 +33,27 @@ from askbot.search import mysql
from askbot.utils.slug import slugify
from askbot.search.state_manager import DummySearchState
+
+def clean_tagnames(tagnames):
+ """Cleans tagnames string so that the field fits the constraint of the
+ database.
+ TODO: remove this when the Thread.tagnames field is converted into
+ text_field
+ """
+ original = tagnames
+ tagnames = tagnames.strip().split()
+ #see if the tagnames field fits into 125 bytes
+ while True:
+ encoded_tagnames = ' '.join(tagnames).encode('utf-8')
+ length = len(encoded_tagnames)
+ if length == 0:
+ return ''
+ elif length <= 125:
+ return ' '.join(tagnames)
+ else:
+ tagnames.pop()
+
+
class ThreadQuerySet(models.query.QuerySet):
def get_visible(self, user):
"""filters out threads not belonging to the user groups"""
@@ -52,7 +72,7 @@ class ThreadQuerySet(models.query.QuerySet):
if getattr(django_settings, 'ENABLE_HAYSTACK_SEARCH', False):
from askbot.search.haystack.searchquery import AskbotSearchQuerySet
hs_qs = AskbotSearchQuerySet().filter(content=search_query).models(self.model)
- return hs_qs.get_django_queryset()
+ return self & hs_qs.get_django_queryset()
else:
db_engine_name = askbot.get_database_engine_name()
filter_parameters = {'deleted': False}
@@ -134,6 +154,7 @@ class ThreadManager(BaseQuerySetManager):
# TODO: Some of this code will go to Post.objects.create_new
language = language or get_language()
+ tagnames = clean_tagnames(tagnames)
thread = super(
ThreadManager,
@@ -147,6 +168,7 @@ class ThreadManager(BaseQuerySetManager):
)
#todo: code below looks like ``Post.objects.create_new()``
+ from askbot.models.post import Post
question = Post(
post_type='question',
thread=thread,
@@ -369,7 +391,7 @@ class ThreadManager(BaseQuerySetManager):
except User.DoesNotExist:
meta_data['author_name'] = None
else:
- qs = qs.filter(posts__post_type__in=('question', 'answer'), posts__author=u, posts__deleted=False)
+ qs = qs.filter(posts__post_type='question', posts__author=u, posts__deleted=False)
meta_data['author_name'] = u.username
#get users tag filters
@@ -466,6 +488,7 @@ class ThreadManager(BaseQuerySetManager):
#threads = [thread for thread in threads if not thread.summary_html_cached()]
thread_ids = [obj.id for obj in threads]
+ from askbot.models.post import Post
page_questions = Post.objects.filter(
post_type='question', thread__id__in = thread_ids
).only(# pick only the used fields
@@ -491,6 +514,7 @@ class ThreadManager(BaseQuerySetManager):
def get_thread_contributors(self, thread_list):
"""Returns query set of Thread contributors"""
# INFO: Evaluate this query to avoid subquery in the subsequent query below (At least MySQL can be awfully slow on subqueries)
+ from askbot.models.post import Post
u_id = list(Post.objects.filter(post_type__in=('question', 'answer'), thread__in=thread_list).values_list('author', flat=True))
#todo: this does not belong gere - here we select users with real faces
@@ -505,6 +529,8 @@ class ThreadManager(BaseQuerySetManager):
def get_for_user(self, user):
"""returns threads where a given user had participated"""
+ from askbot.models.post import PostRevision
+ from askbot.models.post import Post
post_ids = PostRevision.objects.filter(
author = user
).values_list(
@@ -543,7 +569,7 @@ class ThreadToGroup(models.Model):
class Thread(models.Model):
- SUMMARY_CACHE_KEY_TPL = 'thread-question-summary-%d'
+ SUMMARY_CACHE_KEY_TPL = 'thread-question-summary-%d-%s'
ANSWER_LIST_KEY_TPL = 'thread-answer-list-%d'
title = models.CharField(max_length=300)
@@ -560,6 +586,8 @@ class Thread(models.Model):
last_activity_by = models.ForeignKey(User, related_name='unused_last_active_in_threads')
language_code = models.CharField(max_length=16, default=django_settings.LANGUAGE_CODE)
+ #todo: these two are redundant (we used to have a "star" and "subscribe"
+ #now merged into "followed")
followed_by = models.ManyToManyField(User, related_name='followed_threads')
favorited_by = models.ManyToManyField(User, through='FavoriteQuestion', related_name='unused_favorite_threads')
@@ -578,7 +606,7 @@ class Thread(models.Model):
#approvals - by whom and when
approved = models.BooleanField(default=True, db_index=True)
- accepted_answer = models.ForeignKey(Post, null=True, blank=True, related_name='+')
+ accepted_answer = models.ForeignKey('Post', null=True, blank=True, related_name='+')
answer_accepted_at = models.DateTimeField(null=True, blank=True)
added_at = models.DateTimeField(default = datetime.datetime.now)
@@ -605,6 +633,7 @@ class Thread(models.Model):
post = getattr(self, '_question_cache', None)
if post:
return post
+ from askbot.models.post import Post
self._question_cache = Post.objects.get(post_type='question', thread=self)
return self._question_cache
@@ -828,14 +857,15 @@ class Thread(models.Model):
else:
return self.title
- def format_for_email(self, user=None):
+ def format_for_email(self, recipient=None):
"""experimental function: output entire thread for email"""
question, answers, junk, published_ans_ids = \
- self.get_cached_post_data(user=user)
+ self.get_cached_post_data(user=recipient)
- output = question.format_for_email_as_subthread()
+ output = question.format_for_email_as_subthread(recipient=recipient)
if answers:
+ #todo: words
answer_heading = ungettext(
'%(count)d answer:',
'%(count)d answers:',
@@ -843,7 +873,7 @@ class Thread(models.Model):
) % {'count': len(answers)}
output += '<p>%s</p>' % answer_heading
for answer in answers:
- output += answer.format_for_email_as_subthread()
+ output += answer.format_for_email_as_subthread(recipient=recipient)
return output
def get_answers_by_user(self, user):
@@ -911,7 +941,7 @@ class Thread(models.Model):
# )
def invalidate_cached_thread_content_fragment(self):
- cache.cache.delete(self.SUMMARY_CACHE_KEY_TPL % self.id)
+ cache.cache.delete(self.SUMMARY_CACHE_KEY_TPL % (self.id, get_language()))
def get_post_data_cache_key(self, sort_method = None):
return 'thread-data-%s-%s' % (self.id, sort_method)
@@ -1106,6 +1136,7 @@ class Thread(models.Model):
# Denormalize questions to speed up template rendering
# todo: just denormalize question_post_id on the thread!
thread_map = dict([(thread.id, thread) for thread in similar_threads])
+ from askbot.models.post import Post
questions = Post.objects.get_questions()
questions = questions.select_related('thread').filter(thread__in=similar_threads)
for q in questions:
@@ -1150,6 +1181,7 @@ class Thread(models.Model):
#it is important that update method is called - not save,
#because we do not want the signals to fire here
thread_question = self._question_post()
+ from askbot.models.post import Post
Post.objects.filter(id=thread_question.id).update(is_anonymous=False)
thread_question.revisions.all().update(is_anonymous=False)
@@ -1183,6 +1215,7 @@ class Thread(models.Model):
"""removes child posts from given groups"""
post_ids = self.posts.all().values_list('id', flat=True)
group_ids = [group.id for group in groups]
+ from askbot.models.post import PostToGroup
PostToGroup.objects.filter(
post__id__in=post_ids,
tag__id__in=group_ids
@@ -1400,19 +1433,18 @@ class Thread(models.Model):
silent=silent
)
+
def retag(self, retagged_by=None, retagged_at=None, tagnames=None, silent=False):
"""changes thread tags"""
if None in (retagged_by, retagged_at, tagnames):
raise Exception('arguments retagged_at, retagged_by and tagnames are required')
- if len(tagnames) > 125:#todo: remove magic number!!!
- raise django_exceptions.ValidationError('tagnames value too long')
+ tagnames = clean_tagnames(tagnames)
+ self.tagnames = tagnames
+ self.save()
thread_question = self._question_post()
- self.tagnames = tagnames.strip()
- self.save()
-
# Update the Question itself
if silent == False:
thread_question.last_edited_at = retagged_at
@@ -1426,6 +1458,8 @@ class Thread(models.Model):
# Create a new revision
latest_revision = thread_question.get_latest_revision()
+
+ from askbot.models.post import PostRevision
PostRevision.objects.create(
post=thread_question,
title=latest_revision.title,
@@ -1490,7 +1524,7 @@ class Thread(models.Model):
#parameter visitor is there to get summary out by the user groups
if askbot_settings.GROUPS_ENABLED:
return None
- return cache.cache.get(self.SUMMARY_CACHE_KEY_TPL % self.id)
+ return cache.cache.get(self.SUMMARY_CACHE_KEY_TPL % (self.id, get_language()))
def update_summary_html(self, visitor = None):
#todo: it is quite wrong that visitor is an argument here
@@ -1508,6 +1542,7 @@ class Thread(models.Model):
}
from askbot.views.context import get_extra as get_extra_context
context.update(get_extra_context('ASKBOT_QUESTION_SUMMARY_EXTRA_CONTEXT', None, context))
+ activate_language(self.language_code)
html = get_template('widgets/question_summary.html').render(context)
# INFO: Timeout is set to 30 days:
# * timeout=0/None is not a reliable cross-backend way to set infinite timeout
@@ -1515,17 +1550,17 @@ class Thread(models.Model):
# * Additionally, Memcached treats timeouts > 30day as dates (https://code.djangoproject.com/browser/django/tags/releases/1.3/django/core/cache/backends/memcached.py#L36),
# which probably doesn't break anything but if we can stick to 30 days then let's stick to it
cache.cache.set(
- self.SUMMARY_CACHE_KEY_TPL % self.id,
+ self.SUMMARY_CACHE_KEY_TPL % (self.id, get_language()),
html,
timeout=const.LONG_TIME
)
return html
def summary_html_cached(self):
- return cache.cache.has_key(self.SUMMARY_CACHE_KEY_TPL % self.id)
+ return cache.cache.has_key(self.SUMMARY_CACHE_KEY_TPL % (self.id, get_language()))
class QuestionView(models.Model):
- question = models.ForeignKey(Post, related_name='viewed')
+ question = models.ForeignKey('Post', related_name='viewed')
who = models.ForeignKey(User, related_name='question_views')
when = models.DateTimeField()
@@ -1598,9 +1633,3 @@ class AnonymousQuestion(DraftContent):
text=self.text,
tagnames=self.tagnames
)
- #add message with a link to the ask page
- extra_message = _(
- 'Please, <a href="%s">review your question</a>.'
- ) % reverse('ask')
- message = string_concat(unicode(error), u' ', extra_message)
- user.message_set.create(message=unicode(message))
diff --git a/askbot/models/reply_by_email.py b/askbot/models/reply_by_email.py
index 983edc8f..0b164d24 100644
--- a/askbot/models/reply_by_email.py
+++ b/askbot/models/reply_by_email.py
@@ -5,7 +5,6 @@ import logging
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
-from django.utils.translation import ugettext_lazy
from askbot.models.post import Post
from askbot.models.base import BaseQuerySetManager
from askbot.conf import settings as askbot_settings
@@ -35,12 +34,12 @@ class ReplyAddressManager(BaseQuerySetManager):
REPLY_ACTION_CHOICES = (
- ('post_answer', ugettext_lazy('Post an answer')),
- ('post_comment', ugettext_lazy('Post a comment')),
- ('replace_content', ugettext_lazy('Edit post')),
- ('append_content', ugettext_lazy('Append to post')),
- ('auto_answer_or_comment', ugettext_lazy('Answer or comment, depending on the size of post')),
- ('validate_email', ugettext_lazy('Validate email and record signature')),
+ ('post_answer', 'Post an answer'),
+ ('post_comment', 'Post a comment'),
+ ('replace_content', 'Edit post'),
+ ('append_content', 'Append to post'),
+ ('auto_answer_or_comment', 'Answer or comment, depending on the size of post'),
+ ('validate_email', 'Validate email and record signature'),
)
class ReplyAddress(models.Model):
"""Stores a reply address for the post
diff --git a/askbot/models/repute.py b/askbot/models/repute.py
index 5e9c295f..515356f0 100644
--- a/askbot/models/repute.py
+++ b/askbot/models/repute.py
@@ -101,6 +101,9 @@ class BadgeData(models.Model):
from askbot.models import badges
return badges.get_badge(self.slug)
+ def is_multiple(self):
+ return self._get_meta_data().multiple
+
def get_name(self):
return self._get_meta_data().name
@@ -213,21 +216,10 @@ class Repute(models.Model):
'username': self.user.username,
'question_title': self.question.thread.title
}
- if delta > 0:
- link_title = _(
- '%(points)s points were added for %(username)s\'s '
- 'contribution to question %(question_title)s'
- ) % link_title_data
- else:
- link_title = _(
- '%(points)s points were subtracted for %(username)s\'s '
- 'contribution to question %(question_title)s'
- ) % link_title_data
- return '<a href="%(url)s" title="%(link_title)s">%(question_title)s</a>' \
+ return '<a href="%(url)s">%(question_title)s</a>' \
% {
'url': self.question.get_absolute_url(),
'question_title': escape(self.question.thread.title),
- 'link_title': escape(link_title)
}
diff --git a/askbot/models/user.py b/askbot/models/user.py
index ad49222b..a3e2d4f0 100644
--- a/askbot/models/user.py
+++ b/askbot/models/user.py
@@ -16,11 +16,6 @@ from askbot import const
from askbot.conf import settings as askbot_settings
from askbot.utils import functions
from askbot.models.base import BaseQuerySetManager
-from askbot.models.tag import Tag
-from askbot.models.tag import clean_group_name#todo - delete this
-from askbot.models.tag import get_tags_by_names
-from askbot.forms import DomainNameField
-from askbot.utils.forms import email_is_allowed
from collections import defaultdict
PERSONAL_GROUP_NAME_PREFIX = '_personal_'
@@ -312,6 +307,7 @@ class EmailFeedSetting(models.Model):
'q_sel': 'i',
'm_and_c': 'i'
}
+ #todo: words
FEED_TYPE_CHOICES = (
('q_all', ugettext_lazy('Entire forum')),
('q_ask', ugettext_lazy('Questions that I asked')),
@@ -455,6 +451,7 @@ class GroupQuerySet(models.query.QuerySet):
return self.filter(user = user)
def get_by_name(self, group_name = None):
+ from askbot.models.tag import clean_group_name#todo - delete this
return self.get(name = clean_group_name(group_name))
@@ -589,6 +586,7 @@ class Group(AuthGroup):
return 'open'
#relying on a specific method of storage
+ from askbot.utils.forms import email_is_allowed
if email_is_allowed(
user.email,
allowed_emails=self.preapproved_emails,
@@ -619,6 +617,7 @@ class Group(AuthGroup):
self.preapproved_emails = ' ' + '\n'.join(emails) + ' '
domains = functions.split_list(self.preapproved_email_domains)
+ from askbot.forms import DomainNameField
domain_field = DomainNameField()
try:
map(lambda v: domain_field.clean(v), domains)
@@ -648,6 +647,7 @@ class BulkTagSubscriptionManager(BaseQuerySetManager):
tag_name_list = []
if tag_names:
+ from askbot.models.tag import get_tags_by_names
tags, new_tag_names = get_tags_by_names(tag_names)
if new_tag_names:
assert(tag_author)
@@ -655,6 +655,7 @@ class BulkTagSubscriptionManager(BaseQuerySetManager):
tags_id_list= [tag.id for tag in tags]
tag_name_list = [tag.name for tag in tags]
+ from askbot.models.tag import Tag
new_tags = Tag.objects.create_in_bulk(
tag_names=new_tag_names,
user=tag_author
@@ -687,7 +688,7 @@ class BulkTagSubscriptionManager(BaseQuerySetManager):
class BulkTagSubscription(models.Model):
date_added = models.DateField(auto_now_add=True)
- tags = models.ManyToManyField(Tag)
+ tags = models.ManyToManyField('Tag')
users = models.ManyToManyField(User)
groups = models.ManyToManyField(Group)
diff --git a/askbot/search/haystack/__init__.py b/askbot/search/haystack/__init__.py
index 05580bc4..77308180 100644
--- a/askbot/search/haystack/__init__.py
+++ b/askbot/search/haystack/__init__.py
@@ -32,7 +32,7 @@ class PostIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
post_text = indexes.CharField(model_attr='text')
author = indexes.CharField()
- thread_id = indexes.IntegerField(model_attr='thread__pk')
+ thread_id = indexes.IntegerField(model_attr='thread__pk', null=True)
def get_model(self):
diff --git a/askbot/search/state_manager.py b/askbot/search/state_manager.py
index 356c15bb..5fede602 100644
--- a/askbot/search/state_manager.py
+++ b/askbot/search/state_manager.py
@@ -93,7 +93,6 @@ class SearchState(object):
author=None, page=None, page_size=None, user_logged_in=False
):
# INFO: zip(*[('a', 1), ('b', 2)])[0] == ('a', 'b')
-
if (scope not in zip(*const.POST_SCOPE_LIST)[0]) or (scope == 'followed' and not user_logged_in):
if user_logged_in:
self.scope = askbot_settings.DEFAULT_SCOPE_AUTHENTICATED
diff --git a/askbot/skins/loaders.py b/askbot/skins/loaders.py
index afdf758e..1a9e8edb 100644
--- a/askbot/skins/loaders.py
+++ b/askbot/skins/loaders.py
@@ -86,7 +86,8 @@ def load_skins(language_code):
skin_code = skin_name + '-' + language_code
skins[skin_code] = SkinEnvironment(
skin = skin_name,
- extensions=['jinja2.ext.i18n',]
+ extensions=['jinja2.ext.i18n',],
+ globals={'settings': askbot_settings}
)
skins[skin_code].set_language(language_code)
#from askbot.templatetags import extra_filters_jinja as filters
diff --git a/askbot/startup_procedures.py b/askbot/startup_procedures.py
index e3888e53..3adbd781 100644
--- a/askbot/startup_procedures.py
+++ b/askbot/startup_procedures.py
@@ -1054,20 +1054,11 @@ def run_startup_tests():
if 'manage.py test' in ' '.join(sys.argv):
test_settings_for_test_runner()
-@transaction.commit_manually
+#@transaction.commit_manually
def run():
- """runs all the startup procedures"""
try:
if getattr(django_settings, 'ASKBOT_SELF_TEST', True):
run_startup_tests()
except AskbotConfigError, error:
- transaction.rollback()
print error
sys.exit(1)
- try:
- from askbot.models import badges
- badges.init_badges()
- transaction.commit()
- except Exception, error:
- print error
- transaction.rollback()
diff --git a/askbot/tasks.py b/askbot/tasks.py
index 3d3c57a7..ec3e405b 100644
--- a/askbot/tasks.py
+++ b/askbot/tasks.py
@@ -26,6 +26,7 @@ from django.contrib.contenttypes.models import ContentType
from django.template import Context
from django.template.loader import get_template
from django.utils.translation import ugettext as _
+from django.utils.translation import activate as activate_language
from django.utils import simplejson
from celery.decorators import task
from askbot.conf import settings as askbot_settings
@@ -95,7 +96,7 @@ def notify_author_of_published_revision_celery_task(revision):
if revision.post.post_type == 'question':
mailto_link_subject = revision.post.thread.title
else:
- mailto_link_subject = _('An edit for my answer')
+ mailto_link_subject = _('make an edit by email')
#todo: possibly add more mailto thread headers to organize messages
prompt = _('To add to your post EDIT ABOVE THIS LINE')
@@ -111,6 +112,7 @@ def notify_author_of_published_revision_celery_task(revision):
}
#load the template
+ activate_language(revision.post.language_code)
template = get_template('email/notify_author_about_approved_post.html')
#todo: possibly add headers to organize messages in threads
headers = {'Reply-To': append_content_address}
@@ -248,6 +250,7 @@ def send_instant_notifications_about_activity_in_post(
reply_address, alt_reply_address = get_reply_to_addresses(user, post)
+ activate_language(post.language_code)
subject_line, body_text = format_instant_notification_email(
to_user = user,
from_user = update_activity.user,
diff --git a/askbot/templates/404.html b/askbot/templates/404.html
index 565ff164..8388a42f 100644
--- a/askbot/templates/404.html
+++ b/askbot/templates/404.html
@@ -14,7 +14,7 @@
<div style="margin-top:5px">
{% trans %}This might have happened for the following reasons:{% endtrans %}<br/>
<ul>
- <li>{% trans %}this question or answer has been deleted;{% endtrans %}</li>
+ <li>{% trans %}This page has been deleted{% endtrans %}</li>
<li>{% trans %}url has error - please check it;{% endtrans %}</li>
<li>{% trans %}the page you tried to visit is protected or you don't have sufficient points, see{% endtrans %} <a href="{% url faq %}">{% trans %}faq{% endtrans %}</a>;</li>
<li>{% trans %}if you believe this error 404 should not have occured, please{% endtrans %}
@@ -26,11 +26,6 @@
var GOOG_FIXURL_SITE = '{{ site_url }}';
</script>
<script type="text/javascript" src="http://linkhelp.clients.google.com/tbproxy/lh/wm/fixurl.js"></script>
- <ul>
- <li><a href="#" id="linkPrevious">{% trans %}back to previous page{% endtrans %} »</li>
- <li><a href="{% url questions %}">{% trans %}see all questions{% endtrans %} »</a></li>
- <li><a href="{% url tags %}">{% trans %}see all tags{% endtrans %} »</a></li>
- </u>
</div>
</div>
{% endblock %}
diff --git a/askbot/templates/500.html b/askbot/templates/500.html
index 297ae736..3cf6778b 100644
--- a/askbot/templates/500.html
+++ b/askbot/templates/500.html
@@ -6,20 +6,8 @@
<div id="main-body">
<div style="padding:5px 0px 10px 0;line-height:25px">
{% trans %}system error log is recorded, error will be fixed as soon as possible{% endtrans %}<br/>
- {% trans %}please report the error to the site administrators if you wish{% endtrans %}
- <ul>
- <li><a href="#" id="linkPrevious">{% trans %}back to previous page{% endtrans %}</li>
- <li><a href="{% url questions %}">{% trans %}see latest questions{% endtrans %}</a></li>
- <li><a href="{% url tags %}">{% trans %}see tags{% endtrans %}</a></li>
- </u>
+ {% trans %}please report the error to the site administrators{% endtrans %}
</div>
</div>
{% endblock %}
-{% block endjs %}
- <script type="text/javascript">
- $().ready(function(){
- $("#linkPrevious").bind("click", back=function(){history.go(-1);})
- });
- </script>
-{% endblock %}
<!-- end template 500.html -->
diff --git a/askbot/templates/answer_edit.html b/askbot/templates/answer_edit.html
index 3c6b7a4c..c9d8a147 100644
--- a/askbot/templates/answer_edit.html
+++ b/askbot/templates/answer_edit.html
@@ -1,13 +1,14 @@
{% extends "two_column_body.html" %}
{% import "macros.html" as macros %}
<!-- template answer_edit.html -->
-{% block title %}{% spaceless %}{% trans %}Edit answer{% endtrans %}{% endspaceless %}{% endblock %}
+{% block title %}{% spaceless %}{{ settings.WORDS_EDIT_ANSWER|escape }}{% endspaceless %}{% endblock %}
{% block forestyle %}
<link rel="stylesheet" type="text/css" href="{{"/js/wmd/wmd.css"|media}}" />
{% endblock %}
{% block content %}
<div class="section-title">
- {% trans %}Edit answer{% endtrans %} [<a href="{{ answer.thread._question_post().get_absolute_url() }}#{{ answer.id }}">{% trans %}back{% endtrans %}</a>]
+{{ settings.WORDS_EDIT_ANSWER|escape }}
+[<a href="{{ answer.get_absolute_url() }}">{% trans %}back{% endtrans %}</a>]
</div>
<div id="main-body" class="ask-body">
<form id="fmedit" action="{% url edit_answer answer.id %}" method="post" >{% csrf_token %}
diff --git a/askbot/templates/ask.html b/askbot/templates/ask.html
index 64a8a260..bf713a70 100644
--- a/askbot/templates/ask.html
+++ b/askbot/templates/ask.html
@@ -13,29 +13,7 @@
{% endblock %}
{% block content %}
<div class="question-instructions">
- {% if settings.QUESTION_INSTRUCTIONS %}
- {{ settings.QUESTION_INSTRUCTIONS|safe }}
- {% else %}
- <ul>
- {% if not request.user.is_authenticated() %}
- <li class="warning">{% trans %}since you are not logged in right now, you will be asked to sign in or register after posting your question{% endtrans %}</li>
- {% else %}
- {% if settings.EMAIL_VALIDATION %}
- {% if not request.user.email_isvalid %}
- <li class="warning">{% trans email=request.user.email %}Your email, {{ email }} has not yet been validated. To post messages you must verify your email, please see <a href='{{ email_validation_faq_url }}'>more details here</a>. You can submit your question now and validate email after that. Meanwhile, your question will saved as pending.{% endtrans %}</li>
- {% endif %}
- {% endif %}
- {% endif %}
- <li>{% trans %}please, try to make your question interesting to this community{% endtrans %}</li>
- <li>{% trans %}provide enough details{% endtrans %}</li>
- <li>{% trans %}be clear and concise{% endtrans %}</li>
- </ul>
- {% endif %}
- <p class='info-box-follow-up-links'>
- <!-- will be change to a popup windows
- <a href="{% url faq %}" target="_blank" title="{% trans %}see frequently asked questions{% endtrans %}">{% trans %}FAQ{% endtrans %} »</a>
- -->
- </p>
+ {% include "widgets/question_edit_tips.html" %}
</div>
{% include "widgets/ask_form.html" %}
{% endblock %}
diff --git a/askbot/templates/authopenid/changeemail.html b/askbot/templates/authopenid/changeemail.html
deleted file mode 100644
index 37de8369..00000000
--- a/askbot/templates/authopenid/changeemail.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{% extends "one_column_body.html" %}
-{% block title %}{% spaceless %}{% trans %}Change Email{% endtrans %}{% endspaceless %}{% endblock %}
-{% block content %}
-{% if action_type=="validate" %}
- <div id="main-bar" class="headNormal">
- {% trans %}Validate email{% endtrans %}
- </div>
- <p class="message">
- {% trans %}<span class=\"strong big\">An email with a validation link has been sent to
-{{ email }}.</span> Please <strong>follow the emailed link</strong> with your
-web browser. Email validation is necessary to help insure the proper use of
-email on <span class=\"orange\">Q&amp;A</span>. If you would like to use
-<strong>another email</strong>, please <a
-href='{{ change_email_url }}'><strong>change it again</strong></a>.{% endtrans %}
- </p>
-{% elif action_type=="validation_complete" %}
- <div id="main-bar" class="headNormal">
- {% trans %}Email verified{% endtrans %}
- </div>
- <p class="message">
- {% trans %}<span class=\"big strong\">Thank you for verifying your email!</span> Now
-you can <strong>ask</strong> and <strong>answer</strong> questions. Also if
-you find a very interesting question you can <strong>subscribe for the
-updates</strong> - then will be notified about changes <strong>once a day</strong>
-or less frequently.{% endtrans %}
- </p>
-{% endif %}
-{% endblock %}
-<!-- end changeemail.html -->
diff --git a/askbot/templates/authopenid/providers_javascript.html b/askbot/templates/authopenid/providers_javascript.html
index 9d8c34a8..86f1004f 100644
--- a/askbot/templates/authopenid/providers_javascript.html
+++ b/askbot/templates/authopenid/providers_javascript.html
@@ -1,5 +1,5 @@
-<script type='text/javascript' src='{{"/js/jquery.validate.min.js"|media}}'></script>
-<script type="text/javascript" src="{{"/jquery-openid/jquery.openid.js"|media}}"></script>
+<script type='text/javascript' src='{{ "/js/jquery.validate.min.js"|media }}'></script>
+<script type="text/javascript" src="{{ "/jquery-openid/jquery.openid.js"|media }}"></script>
<script type="text/javascript">
askbot['urls']['changePassword'] = '{% url change_password %}';
var extra_token_name = {};
@@ -11,22 +11,22 @@
{% for login_provider in major_login_providers %}
{%if settings['SIGNIN_' + login_provider.name.upper() + '_ENABLED'] == True %}
{% if login_provider.extra_token_name %}
- extra_token_name['{{login_provider.name}}'] = '{{login_provider.extra_token_name}}';
+ extra_token_name['{{login_provider.name}}'] = '{{ login_provider.extra_token_name|escapejs }}';
{% endif %}
{% if login_provider.type == 'password' %}
- create_pw_text['{{login_provider.name}}'] = '{{login_provider.create_password_prompt}}';
- change_pw_text['{{login_provider.name}}'] = '{{login_provider.change_password_prompt}}';
+ create_pw_text['{{login_provider.name}}'] = '{{ login_provider.create_password_prompt|escapejs }}';
+ change_pw_text['{{login_provider.name}}'] = '{{ login_provider.change_password_prompt|escapejs }}';
{% endif %}
{% endif %}
{% endfor %}
{% for login_provider in minor_login_providers %}
{% if settings['SIGNIN_' + login_provider.name.upper() + '_ENABLED'] == True %}
- {% if login_provider.extra_token_name %}
- extra_token_name['{{login_provider.name}}'] = '{{login_provider.extra_token_name}}';
+{% if login_provider.extra_token_name %}
+ extra_token_name['{{login_provider.name}}'] = '{{ login_provider.extra_token_name|escapejs }}';
{% endif %}
{% if login_provider.type == 'password' %}
- create_pw_text['{{login_provider.name}}'] = '{{login_provider.create_password_prompt}}';
- change_pw_text['{{login_provider.name}}'] = '{{login_provider.change_password_prompt}}';
+ create_pw_text['{{login_provider.name}}'] = '{{ login_provider.create_password_prompt|escapejs }}';
+ change_pw_text['{{login_provider.name}}'] = '{{ login_provider.change_password_prompt|escapejs }}';
{% endif %}
{% endif %}
{% endfor %}
@@ -36,6 +36,7 @@
var userIsAuthenticated = false;
{% endif %}
askbot['settings']['signin_always_show_local_login'] = {% if settings.SIGNIN_ALWAYS_SHOW_LOCAL_LOGIN %}true{% else %}false{% endif %};
+ askbot['settings']['useLdapForPasswordLogin'] = {{ settings.USE_LDAP_FOR_PASSWORD_LOGIN|as_js_bool}};
$("body").authenticator();
(function() {
var form = new ChangePasswordForm();
diff --git a/askbot/templates/authopenid/signin.html b/askbot/templates/authopenid/signin.html
index ad003b69..daf5a45a 100644
--- a/askbot/templates/authopenid/signin.html
+++ b/askbot/templates/authopenid/signin.html
@@ -10,20 +10,6 @@
{% if have_buttons or view_subtype == 'email_sent' %}
<h1 class="section-title">{{page_title}}</h1>
{% endif %}
- {% if answer %}
- <div class="message">
- {% trans title=answer.question.title|escape %}
- Your answer to {{title}} will be posted once you log in
- {% endtrans %}
- </div>
- {% endif %}
- {% if question %}
- <div class="message">
- {% trans title=question.title|escape %}Your question
- {{title}} will be posted once you log in
- {% endtrans %}
- </div>
- {% endif %}
{% if not (view_subtype == 'default' and have_buttons) %}
<p id='login-intro'>
{% if view_subtype == 'add_openid' and have_buttons %}
@@ -87,7 +73,7 @@
{% endif %}
>
{{login_form.password_action}}
- {% if user.is_anonymous() %}
+ {% if user.is_anonymous() or settings.USE_LDAP_FOR_PASSWORD_LOGIN %}
{% if have_buttons %}
<h2 id="password-heading">
{% trans %}or enter your <span>user name and password</span>{% endtrans %}
@@ -106,7 +92,13 @@
</tr>
{% endif %}
<tr>
- <td><label for="id_username">{% trans %}Login or email{% endtrans %}</label></td>
+ <td><label for="id_username">
+ {% if settings.USE_LDAP_FOR_PASSWORD_LOGIN %}
+ {% trans %}Login{% endtrans %}
+ {% else %}
+ {% trans %}Login or email{% endtrans %}
+ {% endif %}
+ </label></td>
<td>{{login_form.username}}</td>
</tr>
<tr>
@@ -120,7 +112,7 @@
<a class="create-password-account" style="vertical-align:middle" href="{% url user_signup_with_password %}?login_provider=local">{% trans %}Create a password-protected account{% endtrans %}</a>
{% endif %}
</p>
- {% elif settings.USE_LDAP_FOR_PASSWORD_LOGIN == False %}
+ {% else %}{# change password form #}
<h2 id="password-heading">
{% trans %}To change your password - please enter the new one twice, then submit{% endtrans %}
</h2>
diff --git a/askbot/templates/authopenid/widget_signin.html b/askbot/templates/authopenid/widget_signin.html
index 717aec63..4cedd014 100644
--- a/askbot/templates/authopenid/widget_signin.html
+++ b/askbot/templates/authopenid/widget_signin.html
@@ -14,20 +14,6 @@
{% if have_buttons or view_subtype == 'email_sent' %}
<h1 class="section-title">{{page_title}}</h1>
{% endif %}
- {% if answer %}
- <div class="message">
- {% trans title=answer.question.title|escape %}
- Your answer to {{title}} will be posted once you log in
- {% endtrans %}
- </div>
- {% endif %}
- {% if question %}
- <div class="message">
- {% trans title=question.title|escape %}Your question
- {{title}} will be posted once you log in
- {% endtrans %}
- </div>
- {% endif %}
<p id='login-intro'>
{% if view_subtype == 'default' and have_buttons %}
{% trans %}Choose your favorite service below to sign in using secure OpenID or similar technology. Your external service password always stays confidential and you don't have to rememeber or create another one.{% endtrans %}
diff --git a/askbot/templates/badges.html b/askbot/templates/badges.html
index 112adc61..4f4d0973 100644
--- a/askbot/templates/badges.html
+++ b/askbot/templates/badges.html
@@ -4,7 +4,8 @@
{% block content %}
<h1 class="section-title">{% trans %}Badges{% endtrans %}</h1>
<p>
-{% trans %}Community gives you awards for your questions, answers and votes.{% endtrans %}<br/>
+{{ settings.WORDS_COMMUNITY_GIVES_YOU_AWARDS|escape }}
+<br/>
{% trans %}Below is the list of available badges and number of times each type of badge has been awarded.{% endtrans %}
</p>
<div id="medalList">
diff --git a/askbot/templates/close.html b/askbot/templates/close.html
index bac2b3ee..70d7cc8b 100644
--- a/askbot/templates/close.html
+++ b/askbot/templates/close.html
@@ -1,9 +1,9 @@
{% extends "one_column_body.html" %}
<!-- template close.html -->
-{% block title %}{% spaceless %}{% trans %}Close question{% endtrans %}{% endspaceless %}{% endblock %}
+{% block title %}{% spaceless %}{{ settings.WORDS_CLOSE_QUESTION|escape }}{% endspaceless %}{% endblock %}
{% block content %}
-<h1>{% trans %}Close question{% endtrans %}</h1>
- <p>{% trans %}Close the question{% endtrans %}: <a href="{{ question.get_absolute_url() }}">
+<h1>{{ settings.WORDS_CLOSE_QUESTION|escape }}</h1>
+ <p>{{ settings.WORDS_CLOSE_QUESTION|escape }}: <a href="{{ question.get_absolute_url() }}">
<strong>{{ question.get_question_title()|escape }}</strong></a>
</p>
<form id="fmclose" action="{% url close question.id %}" method="post" >{% csrf_token %}
diff --git a/askbot/templates/email/delayed_email_alert.html b/askbot/templates/email/delayed_email_alert.html
index 3ccacea4..252a2337 100644
--- a/askbot/templates/email/delayed_email_alert.html
+++ b/askbot/templates/email/delayed_email_alert.html
@@ -1,6 +1,6 @@
{% block content %}
<p>{% trans %}Dear {{ name }},{% endtrans %}</p>
-<p>{% trans num=questions|length %}The following question has been updated {{ site_name }}:{% pluralize num %}The following {{ num }} questions have been updated on {{ site_name }}:{% endtrans %}</p>
+<p>{% trans %}{{ site_name }} has these updates, please have a look:{% endtrans %}</p>
<ul>
{% for q in questions %}
<li>
diff --git a/askbot/templates/email/insufficient_rep_to_post_by_email.html b/askbot/templates/email/insufficient_rep_to_post_by_email.html
index df7f797a..deabfbbd 100644
--- a/askbot/templates/email/insufficient_rep_to_post_by_email.html
+++ b/askbot/templates/email/insufficient_rep_to_post_by_email.html
@@ -7,12 +7,12 @@
* site_link - html for the link
#}
{% block headline %}
- {% trans user=username|escape %}{{ username }}, your question could not be posted by email just yet.{% endtrans %}
+ {% trans user=username|escape %}{{ username }}, your content could not be posted by email just yet.{% endtrans %}
{%endblock%}
{% block content %}
<p>
{% trans %}To make posts by email, you need to receive about {{min_upvotes}} upvotes.{% endtrans %}<br/>
- {% trans link=site_link|safe %}At this time, please post your question at {{link}}{% endtrans %}
+ {% trans link=site_link|safe %}At this time, please post your content at {{link}}{% endtrans %}
</p>
{% endblock %}
{% block footer %}
diff --git a/askbot/templates/email/macros.html b/askbot/templates/email/macros.html
index 77345a45..c5b7cfcc 100644
--- a/askbot/templates/email/macros.html
+++ b/askbot/templates/email/macros.html
@@ -1,60 +1,73 @@
+{%- macro mailto_link(user) -%}
+ <a href="mailto:{{ user.email }}">{{ user.email }}</a>
+{%- endmacro -%}
+
{% macro quoted_post(
- post = None,
- quote_level = 0,
- format = None,
- is_leaf_post = False
+ post=None,
+ recipient=None,
+ quote_level=0,
+ format=None,
+ is_leaf_post=False
)
%}
{% spaceless %}
{{ start_quote(quote_level) }}
- {% set author = post.author.username|escape %}
- {% if post.post_type == 'question' %}
- {% if quote_level > 0 %}
- <p style="font-size:10px; font-weight: bold;">
+
+ {% if recipient|can_see_private_user_data(post.author) %}
+ {% set author = post.author.username|escape ~ '/(' ~ mailto_link(post.author) ~ ')' %}
+ {% elif post.is_anonymous %}
+ {% set author = post.author.get_name_of_anonymous_user()|escape %}
{% else %}
- <p style="font-size:20px; font-weight: bold; margin: 10px 0">
+ {% set author = post.author.username|escape %}
{% endif %}
- {% if format == 'parent_subthread' %}
- {% if is_leaf_post %}
- {% trans %}Question by {{ author }}:{% endtrans %}
+
+ {% if post.post_type == 'question' %}
+ {% if quote_level > 0 %}
+ <p style="font-size:10px; font-weight: bold;">
+ {% else %}
+ <p style="font-size:20px; font-weight: bold; margin: 10px 0">
+ {% endif %}
+ {% if format == 'parent_subthread' %}
+ {% if is_leaf_post %}
+ {% trans %}Started by {{ author }}:{% endtrans %}
+ {% else %}
+ {% trans -%}
+ In reply to {{ author }}:
+ {%- endtrans %}
+ {% endif %}
{% else %}
- {% trans -%}
- In reply to {{ author }}'s question:
- {%- endtrans %}
+ {{ settings.WORDS_QUESTION_SINGULAR|title|escape }} :
{% endif %}
- {% else %}
- {% trans %}Question :{% endtrans %}
- {% endif %}
- {{ post.thread.title }}
- </p>
- {% if quote_level > 0 %}
- <p style="font-size:10px; font-weight: bold;">
- {% if format != 'parent_subthread' %}
- {% trans %}Asked by {{ author }}:{% endtrans %}
- {% endif %}
- </p>
- {% endif %}
- {% set tag_names = post.get_tag_names() %}
- {% if tag_names %}
- <p style="font-size:10px; font-style:italic;">
- {% trans %}Tags:{% endtrans %}
- {{ tag_names|join(', ') }}.
- </p>
- {% endif %}
+ {{ post.thread.title }}
+ </p>
+ {% if quote_level > 0 %}
+ <p style="font-size:10px; font-weight: bold;">
+ {% if format != 'parent_subthread' %}
+ {% trans %}Started by {{ author }}:{% endtrans %}
+ {% endif %}
+ </p>
+ {% endif %}
+ {% set tag_names = post.get_tag_names() %}
+ {% if tag_names %}
+ <p style="font-size:10px; font-style:italic;">
+ {% trans %}Tags:{% endtrans %}
+ {{ tag_names|join(', ') }}.
+ </p>
+ {% endif %}
{% elif post.post_type == 'answer' %}
<p style="font-size:10px; font-weight: bold;">
{% if format == 'parent_subthread' %}
{% if is_leaf_post %}
{% trans -%}
- {{ author }}'s answer:
+ {{ author }}'s response:
{%- endtrans %}
{% else %}
{% trans -%}
- In reply to {{ author }}'s answer:
+ In reply to {{ author }}:
{%- endtrans %}
{% endif %}
{% else %}
- {% trans %}Answered by {{ author }}:{% endtrans %}
+ {% trans %}Replied by {{ author }}:{% endtrans %}
{% endif %}
</p>
{% else %}
diff --git a/askbot/templates/email/post_as_subthread.html b/askbot/templates/email/post_as_subthread.html
index 08b35ac5..5c08247f 100644
--- a/askbot/templates/email/post_as_subthread.html
+++ b/askbot/templates/email/post_as_subthread.html
@@ -1,7 +1,7 @@
{% from "email/macros.html" import quoted_post %}
{% if post.post_type in ('question', 'answer') %}
- {{ quoted_post(post) }}
+ {{ quoted_post(post, recipient=recipient) }}
{% set comments = post.get_cached_comments() %}
{% if comments %}
<p>
@@ -12,7 +12,7 @@
{%- endtrans -%}
</p>
{% for comment in comments %}
- {{ quoted_post(comment, quote_level = 1) }}
+ {{ quoted_post(comment, quote_level=1, recipient=recipient) }}
{% endfor %}
{% endif %}
{% endif %}
diff --git a/askbot/templates/email/quoted_post.html b/askbot/templates/email/quoted_post.html
index ecc20ad9..2c3b6046 100644
--- a/askbot/templates/email/quoted_post.html
+++ b/askbot/templates/email/quoted_post.html
@@ -1,5 +1,9 @@
{% from "email/macros.html" import quoted_post %}
{{ quoted_post(
- post, quote_level, is_leaf_post = is_leaf_post, format = format
+ post=post,
+ quote_level=quote_level,
+ recipient=recipient,
+ is_leaf_post=is_leaf_post,
+ format=format
)
}}
diff --git a/askbot/templates/email/re_welcome_lamson_on.html b/askbot/templates/email/re_welcome_lamson_on.html
index f30345d1..af050960 100644
--- a/askbot/templates/email/re_welcome_lamson_on.html
+++ b/askbot/templates/email/re_welcome_lamson_on.html
@@ -4,7 +4,7 @@
{% block content %}
{% if can_post_by_email %}
- <p>{% trans %}You can post questions by emailing them at {{ ask_address }}.{% endtrans %}</p>
+ <p>{{ settings.WORDS_YOU_CAN_POST_QUESTIONS_BY_EMAILING_THEM_AT|escape }} {{ ask_address }}</p>
<p>{% trans %}When you receive update notifications, you will be able to respond to them, also by email.{% endtrans %}</p>
<p>{% trans %}Of course, you can always visit the {{ site_name }} at <a href="{{ site_url }}">{{ site_url }}</a>.{% endtrans %}</p>
{% else %}
diff --git a/askbot/templates/email/welcome_lamson_on.html b/askbot/templates/email/welcome_lamson_on.html
index 3e47f44f..898e4b3d 100644
--- a/askbot/templates/email/welcome_lamson_on.html
+++ b/askbot/templates/email/welcome_lamson_on.html
@@ -11,7 +11,7 @@ of the email code to detect the response signature that will appear under #}
{% trans %}Important: <em>Please reply</em> to this message, without editing it. We need this to determine your email signature and that the email address is valid and was typed correctly.{% endtrans %}
</p>
<p>
- {% trans %}Until we receive the response from you, you will not be able ask or answer questions on {{ site_name }} by email.{% endtrans %}
+ {% trans %}Until we receive the response from you, you will not be able to post content on {{ site_name }} by email.{% endtrans %}
</p>
{% endblock %}
{%block footer %}
diff --git a/askbot/templates/embed/ask_by_widget.html b/askbot/templates/embed/ask_by_widget.html
index fb38ad64..949284e1 100644
--- a/askbot/templates/embed/ask_by_widget.html
+++ b/askbot/templates/embed/ask_by_widget.html
@@ -167,7 +167,7 @@
<div class="title">{{widget.title}}</div>
<form action="." method="POST" accept-charset="utf-8">
{% csrf_token %}
- <label>{%trans%}Please enter your question{%endtrans%}</label>
+ <label>{{ settings.WORDS_PLEASE_ENTER_YOUR_QUESTION|escape }}</label>
<div class="input-title">
{{form.title}}
</div>
@@ -195,7 +195,7 @@
{% if form.ask_anonymously %}
<p>{{form.ask_anonymously.label_tag()}}: {{form.ask_anonymously}}</p>
{%endif%}
- <input type="submit" value="Ask your question" id="submit" />
+ <input type="submit" value="{{ settings.WORDS_ASK_YOUR_QUESTION|escape }}" id="submit" />
</form>
{%endblock%}
{% block endjs %}
diff --git a/askbot/templates/embed/widgets.html b/askbot/templates/embed/widgets.html
index 767ebc2c..7fcfa94b 100644
--- a/askbot/templates/embed/widgets.html
+++ b/askbot/templates/embed/widgets.html
@@ -13,7 +13,7 @@
</thead>
<tbody>
<tr>
- <td>{% trans %}Ask a question{% endtrans %}</td>
+ <td>"{{ settings.WORDS_ASK_YOUR_QUESTION|escape }}"</td>
<td><a href="{% url create_widget 'ask' %}">{% trans %}create{% endtrans %}</a></td>
<td>
{% if ask_widgets > 0 %}
@@ -22,7 +22,7 @@
</td>
</tr>
<tr>
- <td>{% trans %}List of questions{% endtrans %}</td>
+ <td>{{ settings.WORDS_LIST_OF_QUESTIONS|escape }}</td>
<td><a href="{% url create_widget 'question' %}">{% trans %}create{% endtrans %}</a></td>
<td>
{% if question_widgets > 0 %}
diff --git a/askbot/templates/faq_static.html b/askbot/templates/faq_static.html
index 3a2638be..20a090d2 100644
--- a/askbot/templates/faq_static.html
+++ b/askbot/templates/faq_static.html
@@ -18,7 +18,7 @@
{% trans %}Karma system allows users to earn rights to perform a variety of moderation tasks{% endtrans %}
</p>
<h2>{% trans %}How does karma system work?{% endtrans %}</h2>
-<p>{% trans %}When a question or answer is upvoted, the user who posted them will gain some points, which are called \"karma points\". These points serve as a rough measure of the community trust to him/her. Various moderation tasks are gradually assigned to the users based on those points.{% endtrans %}</p>
+<p>{% trans %}When a question or answer is upvoted, the user who posted them will gain some points, which are called "karma points". These points serve as a rough measure of the community trust to him/her. Various moderation tasks are gradually assigned to the users based on those points.{% endtrans %}</p>
<p>{% trans MAX_REP_GAIN_PER_USER_PER_DAY=settings.MAX_REP_GAIN_PER_USER_PER_DAY, REP_GAIN_FOR_RECEIVING_UPVOTE=settings.REP_GAIN_FOR_RECEIVING_UPVOTE, REP_LOSS_FOR_RECEIVING_DOWNVOTE=settings.REP_LOSS_FOR_RECEIVING_DOWNVOTE|absolute_value %}For example, if you ask an interesting question or give a helpful answer, your input will be upvoted. On the other hand if the answer is misleading - it will be downvoted. Each vote in favor will generate <strong>{{REP_GAIN_FOR_RECEIVING_UPVOTE}}</strong> points, each vote against will subtract <strong>{{REP_LOSS_FOR_RECEIVING_DOWNVOTE}}</strong> points. There is a limit of <strong>{{MAX_REP_GAIN_PER_USER_PER_DAY}}</strong> points that can be accumulated for a question or answer per day. The table below explains reputation point requirements for each type of moderation task.{% endtrans %}
</p>
@@ -40,14 +40,11 @@
<tr>
<td class="faq-rep-item"><strong>{{settings.MIN_REP_TO_VOTE_DOWN}}</strong></td>
<td>{% trans %}downvote{% endtrans %}</td>
- </tr><tr>
+ </tr>
+ <tr>
<td class="faq-rep-item"><strong>{{settings.MIN_REP_TO_ACCEPT_OWN_ANSWER}}</strong></td>
<td>{% trans %} accept own answer to own questions{% endtrans %}</td>
</tr>
- </tr><tr>
- <td class="faq-rep-item"><strong>{{settings.MIN_REP_TO_CLOSE_OWN_QUESTIONS}}</strong></td>
- <td>{% trans %}open and close own questions{% endtrans %}</td>
- </tr>
<tr>
<td class="faq-rep-item"><strong>{{settings.MIN_REP_TO_RETAG_OTHERS_QUESTIONS}}</strong></td>
<td>{% trans %}retag other's questions{% endtrans %}</td>
diff --git a/askbot/templates/list_suggested_tags.html b/askbot/templates/list_suggested_tags.html
index 1c9a947d..7c69ddc3 100644
--- a/askbot/templates/list_suggested_tags.html
+++ b/askbot/templates/list_suggested_tags.html
@@ -11,7 +11,7 @@
<th class="tags-col">{% trans %}Tag{% endtrans %}</th>
<th class="users-col">{% trans %}Suggested by{% endtrans %}</th>
<th class="decision-col">{% trans %}Your decision{% endtrans %}</th>
- <th>{% trans %}Suggested tag was used for questions{% endtrans %}</th>
+ <th>{% trans %}Where the tag was used{% endtrans %}</th>
</tr>
</thead>
<tbody>
@@ -35,7 +35,7 @@
<button class="reject">{% trans %}Reject{% endtrans %}</button>
</td>
<td class="thread-links-col">
- <span>{% trans %}There are no questions with this tag yet{% endtrans %}</span>
+ <span>{% trans %}This tag has not yet been used{% endtrans %}</span>
</td>
</tr>
{% else %}
@@ -58,7 +58,7 @@
<tr class="per-tag-controls" data-tag-id="{{ tag.id }}">
<td colspan="4">
{% if tag.threads.count() > 1 %}
- <button class="accept">{% trans name=tag.name %}Apply tag "{{ name }}" to all above questions{% endtrans %}</button>
+ <button class="accept">{% trans name=tag.name %}Apply tag "{{ name }}" to the above{% endtrans %}</button>
<button class="reject">{% trans %}Reject tag{% endtrans %}</button>
{% endif %}
</td>
diff --git a/askbot/templates/livesettings/group_settings.html b/askbot/templates/livesettings/group_settings.html
index a8baa47f..3c28d320 100644
--- a/askbot/templates/livesettings/group_settings.html
+++ b/askbot/templates/livesettings/group_settings.html
@@ -1,7 +1,7 @@
{% extends "one_column_body.html" %}
{% block content %}
<h1 class="section-title">
- {% trans %}Settings{% endtrans %} &rarr; {{ group.super_group.name }} &rarr; {{ group.name }}
+ {% trans %}Settings{% endtrans %} &rarr; {{ settings_group.super_group.name }} &rarr; {{ settings_group.name }}
</h1>
<div class="settings-main">
{% if form.errors %}
@@ -13,7 +13,7 @@
<form method="post" enctype="multipart/form-data">{% csrf_token %}
<table
class="settings"
- summary="{% trans name = group.name %}Settings included in {{ name }}.{% endtrans %}"
+ summary="{% trans name = settings_group.name %}Settings included in {{ name }}.{% endtrans %}"
>
{% for field in form %}
{% if field.is_hidden %}
@@ -57,7 +57,7 @@
<ul>
{% for g in super_group.groups %}
{% if g.keys %}
- {% if g.key == group.key %}
+ {% if g.key == settings_group.key %}
<li class="on">{{g.name}}</li>
{% else %}
<li><a href="{% url "group_settings" g.key %}">{{g.name}}</a></li>
diff --git a/askbot/templates/macros.html b/askbot/templates/macros.html
index c6f40a51..a17c808e 100644
--- a/askbot/templates/macros.html
+++ b/askbot/templates/macros.html
@@ -2,7 +2,7 @@
{%- macro share(site = None, site_label = None, icon = False) -%}
<a class="{{ site }}-share{% if icon == True %} icon{% endif %}"
- title="{% trans %}Share this question on {{site}}{% endtrans %}"
+ title="{% trans %}Share this content on {{site}}{% endtrans %}"
>{% if icon == False %}{% if site_label %}{{ site_label }}{% else %}{{ site }}{% endif %}{% endif %}</a>
{%- endmacro -%}
@@ -59,7 +59,9 @@
{% else %}
{{ user_card(user, karma_mode=karma_mode, badges_mode=badges_mode) }}
{% endif %}
- {{ user_primary_group(user) }}
+ {% if settings.GROUPS_ENABLED %}
+ {{ user_primary_group(user) }}
+ {% endif %}
{%- endmacro -%}
{%- macro post_last_updater_and_creator_info(
@@ -88,11 +90,11 @@ poor design of the data or methods on data objects #}
{% if is_wiki %}
<p>
{%- if post.post_type == 'question' -%}
- {%- trans %}asked{% endtrans %}
+ {{ settings.WORDS_ASKED|escape }}
{% elif post.post_type == 'answer' %}
- {%- trans %}answered{% endtrans %}
+ {{ settings.WORDS_ANSWERED|escape }}
{% else %}
- {%- trans %}posted{% endtrans %}
+ {%- trans %}posted{% endtrans %}
{% endif %}
<strong>{{ timeago(post.added_at) }}</strong>
</p>
@@ -107,9 +109,9 @@ poor design of the data or methods on data objects #}
<p style="line-height:12px;">
{# todo: access to class names needs to be removed here #}
{% if post.post_type == 'question' %}
- {% trans %}asked{% endtrans %}
+ {{ settings.WORDS_ASKED|escape }}
{% elif post.post_type == 'answer' %}
- {% trans %}answered{% endtrans %}
+ {{ settings.WORDS_ANSWERED|escape }}
{% else %}
{% trans %}posted{% endtrans %}
{% endif %}
@@ -311,7 +313,6 @@ poor design of the data or methods on data objects #}
class="tag tag-right{% if css_class %} {{ css_class }}{% endif %}"
{% if is_link %}
href="{{ search_state.add_tag(tag).full_url() }}"
- title="{% trans tag=tag|escape %}see questions tagged '{{ tag }}'{% endtrans %}"
{% endif %}
rel="tag"
data-tag-name="{{ tag|replace('*', '&#10045;')|escape }}"
@@ -768,7 +769,7 @@ for the purposes of the AJAX comment editor #}
{% for num in p.page_numbers %}
{% if num == p.page and p.pages != 1%}
- <span class="curr" title="{% trans %}current page{% endtrans %}">{{ num }}</span>
+ <span class="curr page" title="{% trans %}current page{% endtrans %}"><a>{{ num }}</a></span>
{% else %}
<span class="page"><a href="{{ search_state.change_page(num).full_url() }}" title="{% trans %}page {{num}}{% endtrans %}">{{ num }}</a></span>
{% endif %}
diff --git a/askbot/templates/main_page.html b/askbot/templates/main_page.html
index 207e064d..19c447a2 100644
--- a/askbot/templates/main_page.html
+++ b/askbot/templates/main_page.html
@@ -29,6 +29,10 @@
<script type="text/javascript">
{# cant cache this #}
askbot['settings']['showSortByRelevance'] = {{ show_sort_by_relevance|as_js_bool }};
+ askbot['messages']['questionSingular'] = '{{ settings.WORDS_QUESTION_SINGULAR|escapejs }}';
+ askbot['messages']['answerSingular'] = '{{ settings.WORDS_ANSWER_SINGULAR|escapejs }}';
+ askbot['messages']['acceptOwnAnswer'] = '{{ settings.WORDS_ACCEPT_OR_UNACCEPT_OWN_ANSWER|escapejs }}';
+ askbot['messages']['followQuestions'] = '{{ settings.WORDS_FOLLOW_QUESTIONS|escapejs }}';
</script>
{% include "main_page/javascript.html" %}
{% include "main_page/custom_javascript.html" ignore missing %}
diff --git a/askbot/templates/main_page/headline.html b/askbot/templates/main_page/headline.html
index 11f638e1..f597a114 100644
--- a/askbot/templates/main_page/headline.html
+++ b/askbot/templates/main_page/headline.html
@@ -1,7 +1,7 @@
{% import "macros.html" as macros %}
{% if questions_count > 0 %}
<h1 id="questionCount" class="search-result-summary">
- {% trans cnt=questions_count, q_num=questions_count|intcomma %}{{q_num}} question{% pluralize %}{{q_num}} questions{% endtrans %}
+ {{ questions_count|intcomma }} {{ settings.WORDS_QUESTIONS_COUNTABLE_FORMS|py_pluralize(questions_count) }}
{% if author_name %}
{% trans %}with {{author_name}}'s contributions{% endtrans %}
{% endif %}
diff --git a/askbot/templates/main_page/javascript.html b/askbot/templates/main_page/javascript.html
index 24182708..72d63ed3 100644
--- a/askbot/templates/main_page/javascript.html
+++ b/askbot/templates/main_page/javascript.html
@@ -17,6 +17,7 @@
askbot['urls']['mark_subscribed_tag'] = '{% url mark_subscribed_tag %}';
askbot['urls']['unmark_tag'] = '{% url unmark_tag %}';
askbot['urls']['set_tag_filter_strategy'] = '{% url "set_tag_filter_strategy" %}';
+ askbot['settings']['tag_editor'] = '{{ tag_editor_settings|escapejs }}';
if (Modernizr.history) {
// history management works!
diff --git a/askbot/templates/main_page/nothing_found.html b/askbot/templates/main_page/nothing_found.html
index 98629476..73497df0 100644
--- a/askbot/templates/main_page/nothing_found.html
+++ b/askbot/templates/main_page/nothing_found.html
@@ -1,11 +1,11 @@
{# todo: add tips to widen selection #}
<p class="evenMore" style="padding-top:30px;text-align:center;">
{% if search_state.scope == "unanswered" %}
- {% trans %}There are no unanswered questions here{% endtrans %}
+ {{ settings.WORDS_THERE_ARE_NO_UNANSWERED_QUESTIONS_HERE|escape }}
{% endif %}
{% if search_state.scope == "followed" %}
- {% trans %}No questions here. {% endtrans %}
- {% trans %}Please follow some questions or follow some users.{% endtrans %}
+ {{ settings.WORDS_NO_QUESTIONS_HERE|escape }}
+ {{ settings.WORDS_PLEASE_FOLLOW_QUESTIONS|escape }}
{% endif %}
</p>
{% if search_state.query or search_state.tags or search_state.author %}
@@ -27,5 +27,5 @@
</p>
{% endif %}
<p class="evenMore" style="text-align:center">
-<a href="{% url ask %}">{% trans %}Please always feel free to ask your question!{% endtrans %}</a>
+<a href="{% url ask %}">{{ settings.WORDS_PLEASE_FEEL_FREE_TO_ASK_YOUR_QUESTION|escape }}</a>
</p>
diff --git a/askbot/templates/main_page/questions_loop.html b/askbot/templates/main_page/questions_loop.html
index 80598b67..020649ee 100644
--- a/askbot/templates/main_page/questions_loop.html
+++ b/askbot/templates/main_page/questions_loop.html
@@ -7,7 +7,7 @@
{% endfor %}
{#<div class="evenMore">
{% trans %}Did not find what you were looking for?{% endtrans %}
- <a href="{% url ask %}">{% trans %}Ask your question!{% endtrans %}</a>
+ <a href="{% url ask %}">{{ settings.WORDS_ASK_YOUR_QUESTION }}</a>
</div>#}
{% endif %}
diff --git a/askbot/templates/main_page/tab_bar.html b/askbot/templates/main_page/tab_bar.html
index c0b37955..ef66aebe 100644
--- a/askbot/templates/main_page/tab_bar.html
+++ b/askbot/templates/main_page/tab_bar.html
@@ -8,7 +8,7 @@
{% else %}
href="/feeds/rss/"
{% endif %}
- title="{% trans %}subscribe to the questions feed{% endtrans %}"
+ title="{% trans %}subscribe to the feed{% endtrans %}"
>{% trans %}RSS{% endtrans %}
</a>
{% endif %}
diff --git a/askbot/templates/meta/bottom_scripts.html b/askbot/templates/meta/bottom_scripts.html
index 5a307b19..3f1a6e57 100644
--- a/askbot/templates/meta/bottom_scripts.html
+++ b/askbot/templates/meta/bottom_scripts.html
@@ -33,6 +33,7 @@
askbot['data']['maxCommentLength'] = {{ settings.MAX_COMMENT_LENGTH }};
askbot['settings']['editorType'] = '{{ settings.EDITOR_TYPE }}';
askbot['settings']['commentsEditorType'] = '{{ settings.COMMENTS_EDITOR_TYPE }}';
+ askbot['messages']['askYourQuestion'] = '{{ settings.WORDS_ASK_YOUR_QUESTION }}';
{% if settings.ALLOWED_UPLOAD_FILE_TYPES %}
askbot['settings']['allowedUploadFileTypes'] = [
"{{ settings.ALLOWED_UPLOAD_FILE_TYPES|join('", "')|replace('.','') }}"
diff --git a/askbot/templates/question.html b/askbot/templates/question.html
index 8e834304..e1310e3c 100644
--- a/askbot/templates/question.html
+++ b/askbot/templates/question.html
@@ -15,6 +15,9 @@
//below is pure cross-browser javascript, no jQuery
askbot['data']['userIsThreadModerator'] = {% if user_is_thread_moderator %}true{% else %}false{% endif %};
askbot['data']['oldestAnswerId'] = {% if oldest_answer_id %}{{ oldest_answer_id }}{% else %}-1{% endif %};
+ {% if settings.READ_ONLY_MODE_ENABLED %}
+ askbot['settings']['readOnlyModeEnabled'] = true;
+ {% endif %}
(function(){
var hasClass = function(node, selector) {
@@ -174,7 +177,37 @@
}
}
+ function remove_all_controls(post_id) {
+ var deleteBtn = document.getElementById('post-' + post_id + '-delete');
+ var controls = deleteBtn.parentNode;
+ if (controls.className == 'comment-content') {
+ removeNode(deleteBtn);
+ var convertLinks = findChildrenByClassName(controls, 'convert-comment');
+ if (convertLinks.length) {
+ removeNode(convertLinks[0]);
+ }
+ var editLinks = findChildrenByClassName(controls, 'edit');
+ if (editLinks.length) {
+ removeNode(editLinks[0]);
+ }
+ } else {
+ var buttons = controls.childNodes;
+ var numButtons = buttons.length;
+ for (var i = numButtons - 1; i >= 0; i--) {
+ removeNode(buttons[i]);
+ }
+ }
+ };
+
+
function render_post_controls(post_id){
+
+ //in this case remove all post controls
+ if (askbot['settings']['readOnlyModeEnabled'] === true) {
+ remove_all_controls(post_id);
+ return;
+ }
+
if (data['userIsAdminOrMod']){
return;//all remaining functions stay on
}
@@ -191,8 +224,10 @@
) {
removeNode(deleteBtn);
}
+
+ var canFlagPosts = data['userReputation'] >= {{ settings.MIN_REP_TO_FLAG_OFFENSIVE }};
var flags = findChildrenByClassName(controls, 'question-flag');
- if (flags.length > 0) {
+ if (flags.length > 0 && !canFlagPosts) {
removeNode(flags[0]);
}
var closeBtn = findChildrenByClassName(controls, 'question-close');
@@ -242,12 +277,12 @@
add_answer_btn.className += ' answer-own-question';
add_answer_btn.setAttribute(
'value',
- '{% trans %}Answer Your Own Question{% endtrans %}'
+ '{{ settings.WORDS_ANSWER_YOUR_OWN_QUESTION|escapejs }}'
)
} else {
add_answer_btn.setAttribute(
'value',
- '{% trans %}Post Your Answer{% endtrans %}'
+ '{{ settings.WORDS_POST_YOUR_ANSWER|escapejs }}'
)
}
} else {
@@ -335,6 +370,9 @@
askbot['messages']['addComment'] = '{% trans %}add a comment{% endtrans %}';
askbot['messages']['userNamePrompt'] = '{% trans %}User name:{% endtrans %}';
askbot['messages']['userEmailPrompt'] = '{% trans %}Email address:{% endtrans %}';
+ {% if settings.READ_ONLY_MODE_ENABLED %}
+ askbot['messages']['readOnlyMessage'] = '{{ settings.READ_ONLY_MESSAGE }}';
+ {% endif %}
askbot['settings']['saveCommentOnEnter'] = {{ settings.SAVE_COMMENT_ON_ENTER|as_js_bool }};
askbot['settings']['tagSource'] = '{{ settings.TAG_SOURCE }}';
askbot['settings']['enableSharingGoogle'] = {{ settings.ENABLE_SHARING_GOOGLE|as_js_bool }};
diff --git a/askbot/templates/question/answer_controls.html b/askbot/templates/question/answer_controls.html
index 21aafe47..1c66f147 100644
--- a/askbot/templates/question/answer_controls.html
+++ b/askbot/templates/question/answer_controls.html
@@ -1,5 +1,5 @@
{#<span class="action-link swap-qa">
- <a id="swap-question-with-answer-{{answer.id}}">{% trans %}swap with question{% endtrans %}</a>
+ <a id="swap-question-with-answer-{{answer.id}}">{{ settings.WORDS_SWAP_WITH_QUESTION|escape }}</a>
</span>uncomment if needed#}
<span id='post-{{answer.id}}-edit' class="action-link">
<a class="question-edit" href="{% url edit_answer answer.id %}">{% trans %}edit{% endtrans %}</a>
@@ -68,7 +68,7 @@
<input
type="submit"
class="link"
- value="{% trans %}repost as a question comment{% endtrans %}"
+ value="{{ settings.WORDS_REPOST_AS_A_QUESTION_COMMENT|escape }}"
/>
</form>
</li>
@@ -82,7 +82,7 @@
<input
type="submit"
class="link"
- value="{% trans %}repost as a comment under the older answer{% endtrans %}"
+ value="{{ settings.WORDS_REPOST_AS_A_COMMENT_UNDER_THE_OLDER_ANSWER|escape }}"
/>
</form>
</li>
diff --git a/askbot/templates/question/answer_tab_bar.html b/askbot/templates/question/answer_tab_bar.html
index bebf68b8..917ce6d9 100644
--- a/askbot/templates/question/answer_tab_bar.html
+++ b/askbot/templates/question/answer_tab_bar.html
@@ -1,23 +1,16 @@
<div class="tabBar tabBar-answer">
<h2 id="questionCount">
- {% trans counter=answer_count %}
- {{counter}} Answer
- {% pluralize %}
- {{counter}} Answers
- {% endtrans %}
+ {{ answer_count }} {{ settings.WORDS_ANSWERS_COUNTABLE_FORMS|py_pluralize(answer_count) }}
</h2>
<div class="tabsA">
<span class="label">
{% trans %}Sort by »{% endtrans %}
</span>
<a id="oldest" href="{{ question.get_absolute_url() }}?sort=oldest#sort-top"
- title="{% trans %}oldest answers will be shown first{% endtrans %}"
- ><span>{% trans %}oldest{% endtrans %}</span></a>
+ ><span>{% trans %}oldest{% endtrans %}</span></a>
<a id="latest" href="{{ question.get_absolute_url() }}?sort=latest#sort-top"
- title="{% trans %}newest answers will be shown first{% endtrans %}"
- ><span>{% trans %}newest{% endtrans %}</span></a>
+ ><span>{% trans %}newest{% endtrans %}</span></a>
<a id="votes" href="{{ question.get_absolute_url() }}?sort=votes#sort-top"
- title="{% trans %}most voted answers will be shown first{% endtrans %}"
- ><span>{% trans %}most voted{% endtrans %}</span></a>
+ ><span>{% trans %}most voted{% endtrans %}</span></a>
</div>
</div>
diff --git a/askbot/templates/question/answer_vote_buttons.html b/askbot/templates/question/answer_vote_buttons.html
index 68503310..84c901e0 100644
--- a/askbot/templates/question/answer_vote_buttons.html
+++ b/askbot/templates/question/answer_vote_buttons.html
@@ -4,10 +4,10 @@
<div
id="answer-img-accept-{{ answer.id }}"
class="answer-img-accept"
- {% if answer.accepted() %}
- title="{% trans %}this answer has been selected as correct{% endtrans %}"
- {% else %}
- title="{% trans %}mark this answer as correct (click again to undo){% endtrans %}"
- {% endif %}
+ {% if answer.accepted() %}
+ title="{{ settings.WORDS_THIS_ANSWER_HAS_BEEN_SELECTED_AS_CORRECT|escape }}"
+ {% else %}
+ title="{{ settings.WORDS_MARK_THIS_ANSWER_AS_CORRECT|escape }} {% trans %}(click again to undo){% endtrans %}"
+ {% endif %}
></div>
{% endif %}
diff --git a/askbot/templates/question/closed_question_info.html b/askbot/templates/question/closed_question_info.html
index f6f3f557..33fc9482 100644
--- a/askbot/templates/question/closed_question_info.html
+++ b/askbot/templates/question/closed_question_info.html
@@ -1,5 +1,7 @@
<div class="question-status">
- <h3>{% trans close_reason=thread.get_close_reason_display() %}The question has been closed for the following reason <b>"{{ close_reason }}"</b> <i>by{% endtrans %}
- <a href="{{ thread.closed_by.get_profile_url() }}">{{ thread.closed_by.username|escape }}</a> </i><br>
- {% trans closed_at=thread.closed_at %}close date {{closed_at}}{% endtrans %}</h3>
+ <h3>{% trans %}Closed for the following reason{% endtrans %}
+ <b>{{ thread.get_close_reason_display() }}</b> {% trans %}by{% endtrans %}
+ {% trans close_reason=thread.get_close_reason_display() %}Closed for the following reason <b>"{{ close_reason }}"</b> <i>by{% endtrans %}
+ <a href="{{ thread.closed_by.get_profile_url() }}">{{ thread.closed_by.username|escape }}</a> </i><br>
+ {% trans closed_at=thread.closed_at %}close date {{closed_at}}{% endtrans %}</h3>
</div>
diff --git a/askbot/templates/question/content.html b/askbot/templates/question/content.html
index 6a73ebef..50bfee55 100644
--- a/askbot/templates/question/content.html
+++ b/askbot/templates/question/content.html
@@ -35,8 +35,8 @@
<a
class="button submit"
href="{% url "edit_answer" previous_answer.id %}"
- >{% trans %}Edit Your Previous Answer{% endtrans %}</a>
- <span>{% trans %}(only one answer per user is allowed){% endtrans %}</span>
+ >{{ settings.WORDS_EDIT_YOUR_PREVIOUS_ANSWER|escape }}</a>
+ <span>{{ settings.WORDS_ONLY_ONE_ANSWER_PER_USER_IS_ALLOWED|escape }}</span>
<div class="invisible">
{# hidden because we still need js from the tinymce widget #}
{% include "question/new_answer_form.html" %}
@@ -48,6 +48,6 @@
type="button"
class="submit after-editor answer-own-question"
id="fmanswer_button"
- value="{% trans %}Answer Your Own Question{% endtrans %}"
+ value="{{ settings.WORDS_ANSWER_YOUR_OWN_QUESTION|escape }}"
/>
{% endif %}
diff --git a/askbot/templates/question/new_answer_form.html b/askbot/templates/question/new_answer_form.html
index 473a4bc2..f8b4cd46 100644
--- a/askbot/templates/question/new_answer_form.html
+++ b/askbot/templates/question/new_answer_form.html
@@ -9,34 +9,31 @@
<a
class="button submit"
href="{{settings.LOGIN_URL}}?next={% url question question.id %}"
- >{% trans %}Login/Signup to Answer{% endtrans %}</a>
+ >{{ settings.WORDS_LOGIN_SIGNUP_TO_ANSWER|escape }}</a>
{% endif %}
{% else %}
- {% if not thread.closed %}
+ {% if not thread.closed and settings.READ_ONLY_MODE_ENABLED == False %}
<div>
{% spaceless %}
<h2>
{% if answers %}
- {% trans %}Your answer{% endtrans %}
+ {{ settings.WORDS_YOUR_ANSWER|escape }}
{% else %}
- {% trans %}Be the first one to answer this question!{% endtrans %}
+ {{ settings.WORDS_BE_THE_FIRST_TO_ANSWER_THIS_QUESTION|escape }}
{% endif %}
</h2>
{% endspaceless %}
</div>
+ <p class="message">
{% if request.user.is_anonymous() %}
- <div class="message">{% trans %}<span class='strong big'>Please start posting your answer anonymously</span> - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a <strong>substantial answer</strong>, for discussions, <strong>please use comments</strong> and <strong>please do remember to vote</strong> (after you log in)!{% endtrans %}</div>
- {% else %}
- <p class="message">
- {% if request.user==question.author %}
- {% trans %}<span class='big strong'>You are welcome to answer your own question</span>, but please make sure to give an <strong>answer</strong>. Remember that you can always <strong>revise your original question</strong>. Please <strong>use comments for discussions</strong> and <strong>please don't forget to vote :)</strong> for the answers that you liked (or perhaps did not like)!{% endtrans %}
- {% else %}
- {% trans %}<span class='big strong'>Please try to give a substantial answer</span>. If you wanted to comment on the question or answer, just <strong>use the commenting tool</strong>. Please remember that you can always <strong>revise your answers</strong> - no need to answer the same question twice. Also, please <strong>don't forget to vote</strong> - it really helps to select the best questions and answers!{% endtrans %}
- {% endif %}
- </p>
+ {{ settings.WORDS_INSTRUCTION_TO_POST_ANONYMOUSLY }}
+ {% elif request.user==question.author %}
+ {{ settings.WORDS_INSTRUCTION_TO_ANSWER_OWN_QUESTION }}
{% endif %}
+ {{ settings.WORDS_INSTRUCTION_TO_GIVE_ANSWER }}
+ </p>
<div class="folded-editor{% if editor_is_unfolded %}unfolded{% endif %}" tabindex="6">
- <p class="prompt"><a>{% trans %}Add answer{% endtrans %}</a></p>
+ <p class="prompt"><a>{{ settings.WORDS_ADD_ANSWER|escape }}</a></p>
<div class="editor-proper">
{{ macros.edit_post(
answer,
diff --git a/askbot/templates/question/sidebar.html b/askbot/templates/question/sidebar.html
index c4301b6c..0894b935 100644
--- a/askbot/templates/question/sidebar.html
+++ b/askbot/templates/question/sidebar.html
@@ -5,16 +5,16 @@
</div>
{% endif %}
<div class="box vote-buttons">
- <h2 >{% trans %}Question tools{% endtrans %}</h2>
+ <h2>{{ settings.WORDS_QUESTION_TOOLS|escape }}</h2>
{% if favorited %}
<a class="button followed"
- alt="{% trans %}click to unfollow this question{% endtrans %}">
+ alt="{% trans %}click to unfollow {% endtrans %}">
<div>{% trans %}Following{% endtrans %}</div>
<div class='unfollow'>{% trans %}Unfollow{% endtrans %}</div>
</a>
{% else %}
<a class="button followed"
- alt="{% trans %}click to follow this question{% endtrans %}">
+ alt="{% trans %}click to follow {% endtrans %}">
{%trans %}Follow{%endtrans%}
</a>
{% endif %}
@@ -30,7 +30,7 @@
<p class="rss">
<a
href="{{ base_url }}/feeds/question/{{ question.id }}"
- title="{% trans %}subscribe to this question rss feed{% endtrans %}"
+ title="{% trans %}subscribe to the rss feed{% endtrans %}"
>{% trans %}subscribe to rss feed{% endtrans %}</a>
</p>
{% endif %}
@@ -42,8 +42,7 @@
<div class="box sharing-widget">
{% if thread.is_private() %}
<h2>{% trans %}Invite{% endtrans %}</h2>
- <p style="margin: 16px 0"
- >Invite others to help answer this question</p>
+ <p style="margin: 16px 0">{{ settings.WORDS_INVITE_OTHERS_TO_HELP_ANSWER_THIS_QUESTION|escape }}</p>
<form action="{% url share_question_with_user %}" method="post">{% csrf_token %}
<input id="share_user_name" type="text" class="groups-input" name="recipient_name" />
<input type="hidden" name="thread_id" value="{{ thread.id }}"/>
@@ -78,7 +77,7 @@
{% if shared_users_count or shared_groups_count %}
<p
style="margin:16px 0 4px 0"
- >{% trans %}This question is currently shared only with:{% endtrans %}</p>
+ >{{ settings.WORDS_THIS_QUESTION_IS_CURRENTLY_SHARED_ONLY_WITH|escape }}</p>
{% endif %}
<h3>{% trans %}Individual users{% endtrans %}</h3>
{% set comma = joiner(',') %}
@@ -148,7 +147,7 @@
{% if similar_threads.data() and settings.SIDEBAR_QUESTION_SHOW_RELATED %}
{#% cache 1800 "related_questions" related_questions question.id language_code %#}
<div class="box">
- <h2>{% trans %}Related questions{% endtrans %}</h2>
+ <h2>{{ settings.WORDS_RELATED_QUESTIONS|escape }}</h2>
<div class="questions-related">
{% for thread_dict in similar_threads.data() %}
<p>
diff --git a/askbot/templates/question_edit.html b/askbot/templates/question_edit.html
index 1b119f93..e31050ec 100644
--- a/askbot/templates/question_edit.html
+++ b/askbot/templates/question_edit.html
@@ -1,19 +1,19 @@
{% extends "two_column_body.html" %}
{% import "macros.html" as macros %}
<!-- question_edit.html -->
-{% block title %}{% spaceless %}{% trans %}Edit question{% endtrans %}{% endspaceless %}{% endblock %}
+{% block title %}{% spaceless %}{{ settings.WORDS_EDIT_QUESTION|escape }}{% endspaceless %}{% endblock %}
{% block forestyle %}
<link rel="stylesheet" type="text/css" href="{{"/js/wmd/wmd.css"|media}}" />
{% endblock %}
{% block content %}
-<div class="section-title">{% trans %}Edit question{% endtrans %} [<a href="{{ question.get_absolute_url() }}">{% trans %}back{% endtrans %}</a>]</div>
+<div class="section-title">{{ settings.WORDS_EDIT_QUESTION|escape }} [<a href="{{ question.get_absolute_url() }}">{% trans %}back{% endtrans %}</a>]</div>
<form id="fmedit" action="{% url edit_question question.id %}" method="post" >{% csrf_token %}
{% if revision_form.revision.errors %}{{ revision_form.revision.errors.as_ul() }}{% endif %}
{{ revision_form.revision }}
<input type="hidden" id="select_revision" name="select_revision" value="false"/>
<div class="form-item">
<label for="id_title" >
- {% trans %}Question - in one sentence{% endtrans %}
+ {{ settings.WORDS_QUESTION_IN_ONE_SENTENCE|escape }}
{% if form.title.errors %}
{{ form.title.errors }}
{% endif %}
@@ -66,7 +66,13 @@
{% endblock %}
{% block sidebar %}
-{% include "widgets/question_edit_tips.html" %}
+<div id ="tips" class="box">
+ <h2>{% trans %}Tips{% endtrans %}</h2>
+ {% include "widgets/question_edit_tips.html" %}
+</div>
+{% if settings.EDITOR_TYPE == 'markdown' %}
+ {% include "/widgets/markdown_help.html" %}
+{% endif %}
{% endblock %}
{% block endjs %}
diff --git a/askbot/templates/question_retag.html b/askbot/templates/question_retag.html
index c42b42f8..e1341f7a 100644
--- a/askbot/templates/question_retag.html
+++ b/askbot/templates/question_retag.html
@@ -1,8 +1,8 @@
{% extends "two_column_body.html" %}
<!-- question_retag.html -->
-{% block title %}{% spaceless %}{% trans %}Retag question{% endtrans %}{% endspaceless %}{% endblock %}
+{% block title %}{% spaceless %}{{ settings.WORDS_RETAG_QUESTION|escape }}{% endspaceless %}{% endblock %}
{% block content %}
-<h1>{% trans %}Retag question{% endtrans %} [<a href="{{ question.get_absolute_url() }}">{% trans %}back{% endtrans %}</a>]</h1>
+<h1>{{ settings.WORDS_RETAG_QUESTION|escape }} [<a href="{{ question.get_absolute_url() }}">{% trans %}back{% endtrans %}</a>]</h1>
<form id="fmretag" action="{% url retag_question question.id %}" method="post" >{% csrf_token %}
<h2>
{{ question.thread.get_title()|escape }}
diff --git a/askbot/templates/reopen.html b/askbot/templates/reopen.html
index 4ddd6f31..9c617403 100644
--- a/askbot/templates/reopen.html
+++ b/askbot/templates/reopen.html
@@ -1,15 +1,15 @@
{% extends "two_column_body.html" %}
{% from "macros.html" import timeago %}
<!-- reopen.html -->
-{% block title %}{% spaceless %}{% trans %}Reopen question{% endtrans %}{% endspaceless %}{% endblock %}
+{% block title %}{{ settings.WORDS_REOPEN_QUESTION|escape }}{% endblock %}
{% block content %}
-<h1>{% trans %}Reopen question{% endtrans %}</h1>
+<h1>{{ settings.WORDS_REOPEN_QUESTION|escape }}</h1>
<p>{% trans %}Title{% endtrans %}:
<a href="{{ question.get_absolute_url() }}">
<span class="big">{{ question.get_question_title()|escape }}</span>
</a>
</p>
-<p>{% trans username = closed_by_username|escape %}This question has been closed by
+<p>{% trans username = closed_by_username|escape %}Closed by:
<a href="{{closed_by_profile_url}}">{{username}}</a>
{% endtrans %}
</p>
@@ -19,12 +19,10 @@
<p>
{% trans %}When:{% endtrans %} {{ timeago(question.thread.closed_at) }}
</p>
-<p>
- {% trans %}Reopen this question?{% endtrans %}
-</p>
+<p>{{ settings.WORDS_REOPEN_QUESTION|escape }}?</p>
<form id="fmclose" action="{% url reopen question.id %}" method="post" >{% csrf_token %}
<div id="" style="padding:20px 0 20px 0">
- <input type="submit" value="{% trans %}Reopen this question{% endtrans %}" class="submit" />&nbsp;
+ <input type="submit" value="{{ settings.WORDS_REOPEN_QUESTION|escape }}" class="submit" />&nbsp;
<input id="btBack" type="button" value="{% trans %}Cancel{% endtrans %}" class="submit" />
</div>
</form>
diff --git a/askbot/templates/revisions.html b/askbot/templates/revisions.html
index 1765b728..1617ff25 100644
--- a/askbot/templates/revisions.html
+++ b/askbot/templates/revisions.html
@@ -53,7 +53,7 @@
revision,
contributor_type,
False,
- 0
+ 0,
)
}}
</div>
diff --git a/askbot/templates/search/indexes/auth/user_text.txt b/askbot/templates/search/indexes/auth/user_text.txt
index b0baa3a6..e2b4ecd8 100644
--- a/askbot/templates/search/indexes/auth/user_text.txt
+++ b/askbot/templates/search/indexes/auth/user_text.txt
@@ -3,3 +3,5 @@
{{ object.last_name }}
{{ object.email }}
{{ object.full_name }}
+{{ object.about }}
+{{ object.location }}
diff --git a/askbot/templates/user_profile/user_answers_list.html b/askbot/templates/user_profile/user_answers_list.html
index 4f0c2ff2..0215ee54 100644
--- a/askbot/templates/user_profile/user_answers_list.html
+++ b/askbot/templates/user_profile/user_answers_list.html
@@ -1,8 +1,7 @@
{% for top_answer in top_answers %}
<div class="answer-summary">
<a href="{{ top_answer.get_absolute_url() }}">
- <span class="answer-votes {% if top_answer.accepted() %}answered-accepted{% endif %}"
- title="{% trans answer_score=top_answer.score %}the answer has been voted for {{ answer_score }} times{% endtrans %} {% if top_answer.accepted() %}{% trans %}this answer has been selected as correct{% endtrans %}{%endif%}">
+ <span class="answer-votes {% if top_answer.accepted() %}answered-accepted{% endif %}">
{{ top_answer.score }}
</span>
</a>
@@ -10,11 +9,6 @@
{% spaceless %}
<a href="{% url question top_answer.thread._question_post().id %}{{ top_answer.thread.title|slugify }}#{{top_answer.id}}">{{ top_answer.thread.title|escape }}</a>
{% endspaceless %}
- {% if top_answer.comment_count > 0 %}
- <span>
- {% trans comment_count=top_answer.comment_count %}({{ comment_count }} comment){% pluralize %}the answer has been commented {{ comment_count }} times{% endtrans %}
- </span>
- {% endif %}
</div>
</div>
{% endfor %}
diff --git a/askbot/templates/user_profile/user_email_subscriptions.html b/askbot/templates/user_profile/user_email_subscriptions.html
index 4692456b..fdda03b7 100644
--- a/askbot/templates/user_profile/user_email_subscriptions.html
+++ b/askbot/templates/user_profile/user_email_subscriptions.html
@@ -7,7 +7,7 @@
{% block usercontent %}
<h2>{% trans %}Email subscription settings{% endtrans %}</h2>
<p class="message">
-{% trans %}<span class='big strong'>Adjust frequency of email updates.</span> Receive updates on interesting questions by email, <strong><br/>help the community</strong> by answering questions of your colleagues. If you do not wish to receive emails - select 'no email' on all items below.<br/>Updates are only sent when there is any new activity on selected items.{% endtrans %}</p>
+{% trans %}<span class='big strong'>Adjust frequency of email updates.</span> Receive updates on interesting content by email. If you do not wish to receive emails - select 'no email' on all items below.<br/>Updates are only sent when there is any new activity on selected items.{% endtrans %}</p>
<div>
{% if action_status %}
<p class="action-status"><span>{{action_status}}</span></p>
diff --git a/askbot/templates/user_profile/user_favorites.html b/askbot/templates/user_profile/user_favorites.html
index ffdcbd0d..e94015de 100644
--- a/askbot/templates/user_profile/user_favorites.html
+++ b/askbot/templates/user_profile/user_favorites.html
@@ -1,8 +1,6 @@
{% extends "user_profile/user.html" %}
<!-- user_favorites.html -->
-{% block profilesection %}
- {% trans %}followed questions{% endtrans %}
-{% endblock %}
+{% block profilesection %}{{ settings.WORDS_FOLLOWED_QUESTIONS|escape }}{% endblock %}
{% block usercontent %}
{% include "user_profile/users_questions.html" %}
{% endblock %}
diff --git a/askbot/templates/user_profile/user_info.html b/askbot/templates/user_profile/user_info.html
index 9786d4ec..93f1660f 100644
--- a/askbot/templates/user_profile/user_info.html
+++ b/askbot/templates/user_profile/user_info.html
@@ -52,7 +52,13 @@
{% if view_user.real_name %}
<tr>
<td>{% trans %}real name{% endtrans %}</td>
- <td><b>{{view_user.real_name}}</b></td>
+ <td><b>{{view_user.real_name|escape}}</b></td>
+ </tr>
+ {% endif %}
+ {% if request.user|can_see_private_user_data(view_user) %}
+ <tr>
+ <td>{% trans %}email{% endtrans %}</td>
+ <td>{{view_user.email}}</td>
</tr>
{% endif %}
{% if settings.GROUPS_ENABLED %}
diff --git a/askbot/templates/user_profile/user_stats.html b/askbot/templates/user_profile/user_stats.html
index f62a57e7..7bb97d88 100644
--- a/askbot/templates/user_profile/user_stats.html
+++ b/askbot/templates/user_profile/user_stats.html
@@ -9,12 +9,18 @@
{% include "user_profile/user_info.html" %}
<a name="questions"></a>
{% spaceless %}
- <h2>{% trans counter=question_count %}<span class="count">{{counter}}</span> Question{% pluralize %}<span class="count">{{counter}}</span> Questions{% endtrans %}</h2>
+ <h2>
+ <span class="count">{{ question_count }}</span>
+ {{ settings.WORDS_QUESTIONS_COUNTABLE_FORMS|py_pluralize(question_count)|capitalize }}
+ </h2>
{% endspaceless %}
{% include "user_profile/users_questions.html" %}
<a name="answers"></a>
{% spaceless %}
- <h2 style="clear:both;"><span class="count">{{ top_answer_count }}</span> {% trans counter=top_answer_count %}Answer{% pluralize %}Answers{% endtrans %}</h2>
+ <h2 style="clear:both;">
+ <span class="count">{{ top_answer_count }}</span>
+ {{ settings.WORDS_ANSWERS_COUNTABLE_FORMS|py_pluralize(top_answer_count)|capitalize }}
+ </h2>
{% endspaceless %}
{% include "user_profile/users_answers.html" %}
<a name="votes"></a>
@@ -79,7 +85,6 @@
{% if award.content_object and award.content_object_is_post %}
<li>
<a
- title="{{ award.content_object.get_snippet()|collapse }}"
href="{{ award.content_object.get_absolute_url() }}"
>{% if award.content_type.post_type == 'answer' %}{% trans %}Answer to:{% endtrans %}{% endif %} {{ award.content_object.thread.title|escape }}</a>
</li>
diff --git a/askbot/templates/user_profile/user_tabs.html b/askbot/templates/user_profile/user_tabs.html
index c7df4187..0abb89f7 100644
--- a/askbot/templates/user_profile/user_tabs.html
+++ b/askbot/templates/user_profile/user_tabs.html
@@ -2,50 +2,41 @@
<div class="tabBar tabBar-profile">
<div class="tabsC">
<a id="stats" {% if tab_name=="stats" %}class="on first"{%else%}class="first"{% endif %}
- title="{% trans %}User profile{% endtrans %}"
href="{% url user_profile view_user.id, view_user.username|slugify %}?sort=stats"
><span>{% trans %}overview{% endtrans %}</span></a>
{% if request.user == view_user or request.user|can_moderate_user(view_user) %}
<a id="inbox" {% if tab_name=="inbox" %}class="on"{% endif %}
- title="{% trans %}comments and answers to others questions{% endtrans %}"
href="{% url user_profile view_user.id, view_user.username|slugify %}?sort=inbox"
><span>{% trans %}inbox{% endtrans %}</span></a>
{% endif %}
{% if user_follow_feature_on %}
<a id="network" {% if tab_name=="network" %}class="on"{% endif %}
- title="{% trans %}followers and followed users{% endtrans %}"
href="{% url user_profile view_user.id, view_user.username|slugify %}?sort=network"
><span>{% trans %}network{% endtrans %}</span></a>
{% endif %}
{% if can_show_karma %}
<a id="reputation" {% if tab_name=="reputation" %}class="on"{% endif %}
- title="{% trans %}Graph of user karma{% endtrans %}"
href="{% url user_profile view_user.id, view_user.username|slugify %}?sort=reputation"
><span>{% trans %}karma{% endtrans %}</span></a>
{% endif %}
<a id="favorites" {% if tab_name=="favorites" %}class="on"{% endif %}
- title="{% trans %}questions that user is following{% endtrans %}"
href="{% url user_profile view_user.id, view_user.username|slugify %}?sort=favorites"
- ><span>{% trans %}followed questions{% endtrans %}</span></a>
+ ><span>{{ settings.WORDS_FOLLOWED_QUESTIONS|escape }}</span></a>
<a id="recent" {% if tab_name=="recent" %}class="on"{% endif %}
- title="{% trans %}activity{% endtrans %}"
href="{% url user_profile view_user.id, view_user.username|slugify %}?sort=recent"
><span>{% trans %}activity{% endtrans %}</span></a>
{% if request.user == view_user or request.user|can_moderate_user(view_user) %}
<a id="votes" {% if tab_name=="votes" %}class="on"{% endif %}
- title="{% trans %}user vote record{% endtrans %}"
href="{% url user_profile view_user.id, view_user.username|slugify %}?sort=votes"
><span>{% trans %}votes{% endtrans %}</span></a>
{% endif %}
{% if request.user == view_user or request.user|can_moderate_user(view_user) %}
<a id="email_subscriptions" {% if tab_name=="email_subscriptions" %}class="on"{% endif %}
- title="{% trans %}email subscription settings{% endtrans %}"
href="{% url user_profile view_user.id, view_user.username|slugify %}?sort=email_subscriptions"
><span>{% trans %}subscriptions{% endtrans %}</span></a>
{% endif %}
{% if request.user|can_moderate_user(view_user) %}
<a id="moderation" {% if tab_name=="moderation" %}class="on"{% endif %}
- title="{% trans %}moderate this user{% endtrans %}"
href="{% url user_profile view_user.id, view_user.username|slugify %}?sort=moderation"
><span>{% trans %}moderation{% endtrans %}</span></a>
{% endif %}
diff --git a/askbot/templates/widgets/answer_edit_tips.html b/askbot/templates/widgets/answer_edit_tips.html
index 2bb5b256..fdcd27b4 100644
--- a/askbot/templates/widgets/answer_edit_tips.html
+++ b/askbot/templates/widgets/answer_edit_tips.html
@@ -3,23 +3,11 @@
<h2>{% trans %}Tips{% endtrans %}</h2>
<div id="tips">
<ul >
- <li> <b>{% trans %}give an answer interesting to this community{% endtrans %}</b>
- </li>
- <li>
- {% trans %}try to give an answer, rather than engage into a discussion{% endtrans %}
- </li>
- <li>
- {% trans %}provide enough details{% endtrans %}
- </li>
- <li>
- {% trans %}be clear and concise{% endtrans %}
- </li>
+ <li>{{ settings.WORDS_GIVE_AN_ANSWER_INTERESTING_TO_THIS_COMMUNITY|escape }}</li>
+ <li>{{ settings.WORDS_TRY_TO_GIVE_AN_ANSWER|escape }}</li>
+ <li>{% trans %}provide enough details{% endtrans %}</li>
+ <li>{% trans %}be clear and concise{% endtrans %}</li>
</ul>
- <p class='info-box-follow-up-links'>
-<!-- will be change to a popup windows
- <a href="{% url faq %}" target="_blank" title="{% trans %}see frequently asked questions{% endtrans %}">{% trans %}FAQ{% endtrans %} »</a>
--->
- </p>
</div>
</div>
{% if settings.EDITOR_TYPE == 'markdown' %}
diff --git a/askbot/templates/widgets/ask_button.html b/askbot/templates/widgets/ask_button.html
index f8ea82bd..5d969a00 100644
--- a/askbot/templates/widgets/ask_button.html
+++ b/askbot/templates/widgets/ask_button.html
@@ -5,6 +5,10 @@
<a
id="askButton"
class="button"
- href="{{ search_state.full_ask_url() }}{% if group %}{% if '?' in search_state.full_ask_url() %}&{% else %}?{% endif %}group_id={{ group.id }}{% endif %}"
- >{% if group %}{% trans %}Ask the Group{% endtrans %}{% else %}{% trans %}Ask Your Question{% endtrans %}{% endif %}</a>
+ href="{{ search_state.full_ask_url() }}{% if group %}{% if '?' in search_state.full_ask_url() %}&amp;{% else %}?{% endif %}group_id={{ group.id }}{% endif %}"
+ >{% if group %}
+ {{ settings.WORDS_ASK_THE_GROUP|escape }}
+ {% else %}
+ {{ settings.WORDS_ASK_YOUR_QUESTION|escape }}
+ {% endif %}</a>
{% endif %}
diff --git a/askbot/templates/widgets/ask_form.html b/askbot/templates/widgets/ask_form.html
index 1d2642c7..df37ba3c 100644
--- a/askbot/templates/widgets/ask_form.html
+++ b/askbot/templates/widgets/ask_form.html
@@ -64,7 +64,7 @@
{% if not request.user.is_authenticated() %}
<input type="submit" name="post_anon" value="{% trans %}Login/Signup to Post{% endtrans %}" class="submit" />
{% else %}
- <input type="submit" name="post" value="{% trans %}Ask Your Question{% endtrans %}" class="submit" />
+ <input type="submit" name="post" value="{{ settings.WORDS_ASK_YOUR_QUESTION|escape }}" class="submit" />
{% endif %}
<div class="clean"></div>
</form>
diff --git a/askbot/templates/widgets/group_info.html b/askbot/templates/widgets/group_info.html
index 6a6b788d..05fcff9b 100644
--- a/askbot/templates/widgets/group_info.html
+++ b/askbot/templates/widgets/group_info.html
@@ -43,7 +43,7 @@
data-toggle-url="{% url toggle_group_profile_property %}"
/>
<label for="moderate-email">
- {% trans %}moderate emailed questions{% endtrans %}
+ {% trans %}moderate emailed content{% endtrans %}
</label>
<br/>
{% endif %}
@@ -55,7 +55,7 @@
data-toggle-url="{% url toggle_group_profile_property %}"
/>
<label for="moderate-answers-to-enquirers">
- {% trans %}show only selected answers to enquirers{% endtrans %}
+ {{ settings.WORDS_SHOW_ONLY_SELECTED_ANSWERS_TO_ENQUIRERS|escape }}
</label>
<br/>
@@ -99,7 +99,6 @@
<br/>
<a
id="preapproved-emails"
- title="{% trans %}list of email addresses of pre-approved users{% endtrans %}"
data-object-id="{{group.group_ptr_id}}"
data-model-name="Group"
data-property-name="preapproved_emails"
@@ -110,7 +109,6 @@
<br/>
<a
id="preapproved-email-domains"
- title="{% trans %}list of preapproved email address domain names{% endtrans %}"
data-object-id="{{group.group_ptr_id}}"
data-model-name="Group"
data-property-name="preapproved_email_domains"
diff --git a/askbot/templates/widgets/header.html b/askbot/templates/widgets/header.html
index 52e528bc..50a25564 100644
--- a/askbot/templates/widgets/header.html
+++ b/askbot/templates/widgets/header.html
@@ -16,5 +16,10 @@
</div>
<div class="clean"></div>
</div>
+ {% if settings.READ_ONLY_MODE_ENABLED %}
+ <div class="content-wrapper system-messages">
+ {{ settings.READ_ONLY_MESSAGE }}
+ </div>
+ {% endif %}
</div>
<!-- end template header.html -->
diff --git a/askbot/templates/widgets/question_edit_tips.html b/askbot/templates/widgets/question_edit_tips.html
index f60304c1..636bd38d 100644
--- a/askbot/templates/widgets/question_edit_tips.html
+++ b/askbot/templates/widgets/question_edit_tips.html
@@ -1,22 +1,19 @@
<!-- question_edit_tips.html -->
-<div id ="tips" class="box">
- <h2>{% trans %}Tips{% endtrans %}</h2>
+{% if settings.QUESTION_INSTRUCTIONS %}
+ {{ settings.QUESTION_INSTRUCTIONS|safe }}
+{% else %}
<ul>
- <li> <b>{% trans %}ask a question interesting to this community{% endtrans %}</b>
- </li>
- <li>
- {% trans %}provide enough details{% endtrans %}
- </li>
- <li>
- {% trans %}be clear and concise{% endtrans %}
- </li>
+ {% if not request.user.is_authenticated() %}
+ <li class="warning">{% trans %}since you are not logged in right now, you will be asked to sign in or register after making your post{% endtrans %}</li>
+ {% else %}
+ {% if settings.EMAIL_VALIDATION %}
+ {% if not request.user.email_isvalid %}
+ <li class="warning">{% trans email=request.user.email %}Your email, {{ email }} has not yet been validated. To post messages you must verify your email, please see <a href='{{ email_validation_faq_url }}'>more details here</a>. You can submit your post now and validate email after that.{% endtrans %}</li>
+ {% endif %}
+ {% endif %}
+ {% endif %}
+ <li>{{ settings.WORDS_ASK_A_QUESTION_INTERESTING_TO_THIS_COMMUNITY|escape }}</li>
+ <li>{% trans %}provide enough details{% endtrans %}</li>
+ <li>{% trans %}be clear and concise{% endtrans %}</li>
</ul>
- <p class='info-box-follow-up-links'>
-<!-- will be change to a popup windows
- <a href="{% url faq %}" target="_blank" title="{% trans %}see frequently asked questions{% endtrans %}">{% trans %}FAQ{% endtrans %} »</a>
--->
- </p>
-</div>
-{% if settings.EDITOR_TYPE == 'markdown' %}
- {% include "/widgets/markdown_help.html" %}
{% endif %}
diff --git a/askbot/templates/widgets/question_summary.html b/askbot/templates/widgets/question_summary.html
index 306bd672..9b1168b9 100644
--- a/askbot/templates/widgets/question_summary.html
+++ b/askbot/templates/widgets/question_summary.html
@@ -27,7 +27,7 @@
class="item-count"
>{{ answer_count|humanize_counter }}{% if thread.accepted_answer_id %}{% endif %}</span>
<div>
- {% trans cnt = answer_count %}answer{% pluralize %}answers{% endtrans %}
+ {{ settings.WORDS_ANSWERS_COUNTABLE_FORMS|py_pluralize(answer_count) }}
</div>
</div>
<div class="votes
@@ -44,13 +44,14 @@
<div style="clear:both"></div>
<div class="userinfo">
{{ timeago(thread.last_activity_at) }}
- {% if question.is_anonymous %}
+ {% if question.is_anonymous %}{# todo: here we need to look at the anonymity of the last edit instead #}
<span class="anonymous">{{ thread.last_activity_by.get_anonymous_name() }}</span>
{% else %}
<a href="{% url user_profile thread.last_activity_by.id, thread.last_activity_by.username|slugify %}">{{thread.last_activity_by.username|escape}}</a> {{ user_country_flag(thread.last_activity_by) }}
+ {% if thread.last_activity_by.get_primary_group() %}
+ - {{ user_primary_group(thread.last_activity_by) }}
+ {% endif %}
{% endif %}
- {% if thread.last_activity_by.get_primary_group() %}-{% endif %}
- {{ user_primary_group(thread.last_activity_by) }}
</div>
</div>
<h2><a href="{{ question.get_absolute_url(thread=thread) }}">{{thread.get_title(question)|escape}}</a></h2>
diff --git a/askbot/templates/widgets/scope_nav.html b/askbot/templates/widgets/scope_nav.html
index 254c3b48..155667ac 100644
--- a/askbot/templates/widgets/scope_nav.html
+++ b/askbot/templates/widgets/scope_nav.html
@@ -14,20 +14,20 @@
{% if settings.ALL_SCOPE_ENABLED %}
<a class="scope-selector {% if scope == 'all' %}on{% endif %}"
href="{{ search_state.change_scope('all').full_url() }}"
- title="{% trans %}see all questions{% endtrans %}">{% trans %}ALL{% endtrans %}</a>
+ >{% trans %}ALL{% endtrans %}</a>
{% endif %}
{% if settings.UNANSWERED_SCOPE_ENABLED %}
<a class="scope-selector {% if scope == 'unanswered' %}on{% endif %}"
href="{{ search_state.change_scope('unanswered').change_sort('answers-asc').full_url() }}"
- title="{% trans %}see unanswered questions{% endtrans %}">{% trans %}UNANSWERED{% endtrans %}</a>
+ >{{ settings.WORDS_UNANSWERED|escape }}</a>
{% endif %}
{% if request.user.is_authenticated() and settings.FOLLOWED_SCOPE_ENABLED %}
<a class="scope-selector {% if scope == 'followed' %}on{% endif %}"
href="{{ search_state.change_scope('followed').full_url() }}"
- title="{% trans %}see your followed questions{% endtrans %}">{% trans %}FOLLOWED{% endtrans %}</a>
+ >{% trans %}FOLLOWED{% endtrans %}</a>
{% endif %}
{% else %}
- <div class="scope-selector ask-message">{% trans %}Please ask your question here{% endtrans %}</div>
+ <div class="scope-selector ask-message">{{ settings.WORDS_PLEASE_ASK_YOUR_QUESTION_HERE|escape }}</div>
{% endif %}
{% endif %}
</div>
diff --git a/askbot/templates/widgets/secondary_header.html b/askbot/templates/widgets/secondary_header.html
index 69e5742c..92f34cff 100644
--- a/askbot/templates/widgets/secondary_header.html
+++ b/askbot/templates/widgets/secondary_header.html
@@ -19,28 +19,27 @@
{% endif %}
class="{{ enabled_scopes_class }}"
method="get">
- <div>
- {#
- Some or all contents of this div may be dropped
- over the search bar via negative margins,
- to make sure that the search bar can occupy 100%
- of the content width.
- Search bar may have padding on the left and right
- to accomodate the buttons.
- #}
- <a id="homeButton" href="{% url questions %}"></a>
- {% include "widgets/scope_nav.html" %}
- {#
- three buttons below are in the opposite order because
- they are floated at the right
- #}
- {% if settings.ASK_BUTTON_ENABLED %}
- {% include "widgets/ask_button.html" %}
- {% endif %}
- {# clears button floats #}
- <div class="clearfix"></div>
- </div>
- {% include "widgets/search_bar.html" %} {# include search form widget #}
+ {#
+ A single row table to help the semi-fixed width layout where:
+ * all cells have "tight width" without linebreaks
+ * except that the search bar cell takes the remaining width
+ We had hard time making this layout work without tables.
+ Please suggest if there is a better way.
+ #}
+ <table width="100%">
+ <tr>
+ {# width 1 means that cell will expand just enough to fit the contents #}
+ <td width="1"><a id="homeButton" href="{% url questions %}"></a></td>
+ <td width="1">{% include "widgets/scope_nav.html" %}</td>
+ {# width * means that the cell takes the remaining table width #}
+ <td width="*" class="search-bar">{% include "widgets/search_bar.html" %}</td>
+ {% if settings.ASK_BUTTON_ENABLED %}
+ <td width="1">
+ {% include "widgets/ask_button.html" %}
+ </td>
+ {% endif %}
+ </tr>
+ </table>
</form>
</div>
</div>
diff --git a/askbot/templates/widgets/system_messages.html b/askbot/templates/widgets/system_messages.html
index 10ba4a84..69f6672f 100644
--- a/askbot/templates/widgets/system_messages.html
+++ b/askbot/templates/widgets/system_messages.html
@@ -1,8 +1,10 @@
<div class="notify" style="display:none">
- {% if user_messages %}
- {% for message in user_messages %}
- <p class="notification">{{ message }}</p>
- {% endfor %}
- {% endif %}
- <a id="closeNotify" onclick="notify.close(true)"></a>
+ <div class="content-wrapper">
+ {% if user_messages %}
+ {% for message in user_messages %}
+ <p class="notification">{{ message }}</p>
+ {% endfor %}
+ {% endif %}
+ <a id="closeNotify" onclick="notify.close(true)"></a>
+ </div>
</div>
diff --git a/askbot/templates/widgets/tag_selector.html b/askbot/templates/widgets/tag_selector.html
index ba304d2c..720de4a1 100644
--- a/askbot/templates/widgets/tag_selector.html
+++ b/askbot/templates/widgets/tag_selector.html
@@ -56,7 +56,7 @@
<input id="subscribedTagAdd" type="submit" value="{% trans %}add{% endtrans%}"/>
</div>
{% endif %}
- <h3>{% trans %}Show only questions from{% endtrans%}</h3>
+ <h3>{{ settings.WORDS_SHOW_ONLY_QUESTIONS_FROM|escape }}</h3>
<div id="displayTagFilterControl">
{{
macros.radio_select(
diff --git a/askbot/templates/widgets/three_column_category_selector.html b/askbot/templates/widgets/three_column_category_selector.html
index ab0886c6..c6e10460 100644
--- a/askbot/templates/widgets/three_column_category_selector.html
+++ b/askbot/templates/widgets/three_column_category_selector.html
@@ -1,7 +1,7 @@
{# just a skeleton for the category selector - filled by js #}
<table class="category-selector">
<thead>
- <th colspan="3">{% trans %}Categorize your question using this tag selector or entering text in tag box.{% endtrans %}
+ <th colspan="3">{{ settings.WORDS_INSTRUCTION_FOR_THE_CATEGORY_SELECTOR|escape }}
<a style="display:none;"
class='category-editor-toggle'
data-on-state-text='{% trans %}(done editing){% endtrans %}'
diff --git a/askbot/templates/widgets/user_perms.html b/askbot/templates/widgets/user_perms.html
index 887a712f..33109140 100644
--- a/askbot/templates/widgets/user_perms.html
+++ b/askbot/templates/widgets/user_perms.html
@@ -18,7 +18,7 @@
{% if not user.is_administrator_or_moderator() %}
<p> {% trans %}Currently, you can:{% endtrans %}</p>
<ul>
- <li>{% trans %}Post questions, answers and comments{% endtrans %}</li>
+ <li>{% trans %}Make new posts{% endtrans %}</li>
{% for perm in perms_data %}
{% if user.reputation >= perm[1] %}
<li>{{ perm[0] }}</li>
diff --git a/askbot/templatetags/extra_filters_jinja.py b/askbot/templatetags/extra_filters_jinja.py
index 8a1c4b8e..0d7ab0c8 100644
--- a/askbot/templatetags/extra_filters_jinja.py
+++ b/askbot/templatetags/extra_filters_jinja.py
@@ -23,6 +23,7 @@ from askbot.utils.html import site_url as site_url_func
from askbot.utils import functions
from askbot.utils import url_utils
from askbot.utils.slug import slugify
+from askbot.utils.pluralization import py_pluralize as _py_pluralize
from askbot.shims.django_shims import ResolverMatch
from django_countries import countries
@@ -94,6 +95,13 @@ def strip_path(url):
return url_utils.strip_path(url)
@register.filter
+def can_see_private_user_data(viewer, target):
+ if viewer.is_authenticated() and viewer.is_administrator_or_moderator():
+ #todo: take into account intersection of viewer and target user groups
+ return askbot_settings.SHOW_ADMINS_PRIVATE_USER_DATA
+ return False
+
+@register.filter
def clean_login_url(url):
"""pass through, unless user was originally on the logout page"""
try:
@@ -350,6 +358,10 @@ def humanize_counter(number):
else:
return str(number)
+@register.filter
+def py_pluralize(source, count):
+ plural_forms = source.strip().split('\n')
+ return _py_pluralize(plural_forms, count)
@register.filter
def absolute_value(number):
diff --git a/askbot/tests/db_api_tests.py b/askbot/tests/db_api_tests.py
index 6b08fb65..3e19a1c2 100644
--- a/askbot/tests/db_api_tests.py
+++ b/askbot/tests/db_api_tests.py
@@ -199,10 +199,10 @@ class DBApiTests(AskbotTestCase):
def test_retag_tags_too_long_raises(self):
tags = "aoaoesuouooeueooeuoaeuoeou aostoeuoaethoeastn oasoeoa nuhoasut oaeeots aoshootuheotuoehao asaoetoeatuoasu o aoeuethut aoaoe uou uoetu uouuou ao aouosutoeh"
question = self.post_question(user=self.user)
- self.assertRaises(
- exceptions.ValidationError,
- self.user.retag_question,
- question=question, tags=tags
+ self.user.retag_question(question=question, tags=tags)
+ self.assertEqual(
+ set(question.thread.tagnames.split()),
+ set('aoaoesuouooeueooeuoaeuoeou aostoeuoaethoeastn oasoeoa nuhoasut oaeeots aoshootuheotuoehao asaoetoeatuoasu o aoeuethut aoaoe'.split())
)
def test_search_with_apostrophe_works(self):
diff --git a/askbot/tests/email_alert_tests.py b/askbot/tests/email_alert_tests.py
index e2f328fc..902b810d 100644
--- a/askbot/tests/email_alert_tests.py
+++ b/askbot/tests/email_alert_tests.py
@@ -10,6 +10,7 @@ import django.core.mail
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.test.client import Client
+from django.utils import translation
from askbot.tests import utils
from askbot.tests.utils import with_settings
from askbot import models
@@ -155,6 +156,7 @@ class EmailAlertTests(TestCase):
between the default version (defined in the decorator) and the
desired version in the "real" test
"""
+ translation.activate('en')
pass
def setUpUsers(self):
diff --git a/askbot/tests/form_tests.py b/askbot/tests/form_tests.py
index fed38f87..c21ac5bf 100644
--- a/askbot/tests/form_tests.py
+++ b/askbot/tests/form_tests.py
@@ -311,8 +311,7 @@ class UserNameFieldTest(AskbotTestCase):
#invalid username and username in reserved words
self.assertRaises(django_forms.ValidationError, self.username_field.clean, ' ')
self.assertRaises(django_forms.ValidationError, self.username_field.clean, 'fuck')
- self.assertRaises(django_forms.ValidationError, self.username_field.clean, '......')
-
+ self.assertEqual(self.username_field.clean('......'), '......')
#TODO: test more things
class AnswerEditorFieldTests(AskbotTestCase):
diff --git a/askbot/tests/page_load_tests.py b/askbot/tests/page_load_tests.py
index be54a1dc..1143d056 100644
--- a/askbot/tests/page_load_tests.py
+++ b/askbot/tests/page_load_tests.py
@@ -12,6 +12,7 @@ import coffin
import coffin.template
from bs4 import BeautifulSoup
+import askbot
from askbot import models
from askbot.utils.slug import slugify
from askbot.deployment import package_utils
@@ -53,6 +54,7 @@ class PageLoadTestCase(AskbotTestCase):
#
@classmethod
def setUpClass(cls):
+ super(PageLoadTestCase, cls).setUpClass()
management.call_command('flush', verbosity=0, interactive=False)
activate_language(settings.LANGUAGE_CODE)
management.call_command('askbot_add_test_content', verbosity=0, interactive=False)
@@ -74,6 +76,12 @@ class PageLoadTestCase(AskbotTestCase):
#Disable caching (to not interfere with production cache,
#not sure if that's possible but let's not risk it)
cache.cache = DummyCache('', {})
+ if 'postgresql' in askbot.get_database_engine_name():
+ management.call_command(
+ 'init_postgresql_full_text_search',
+ verbosity=0,
+ interactive=False
+ )
def tearDown(self):
cache.cache = self.old_cache # Restore caching
@@ -196,7 +204,6 @@ class PageLoadTestCase(AskbotTestCase):
"""test all reader views thoroughly
on non-crashiness (no correcteness tests here)
"""
-
self.try_url('sitemap')
self.try_url(
'get_groups_list',
diff --git a/askbot/tests/permission_assertion_tests.py b/askbot/tests/permission_assertion_tests.py
index 9d549450..16a5afde 100644
--- a/askbot/tests/permission_assertion_tests.py
+++ b/askbot/tests/permission_assertion_tests.py
@@ -322,7 +322,6 @@ class CloseQuestionPermissionAssertionTests(utils.AskbotTestCase):
self.create_user(username = 'other_user')
self.question = self.post_question()
self.min_rep = askbot_settings.MIN_REP_TO_CLOSE_OTHERS_QUESTIONS
- self.min_rep_own = askbot_settings.MIN_REP_TO_CLOSE_OWN_QUESTIONS
def assert_can_close(self, user = None):
user.assert_can_close_question(self.question)
@@ -359,11 +358,10 @@ class CloseQuestionPermissionAssertionTests(utils.AskbotTestCase):
def test_low_rep_owner_cannot_close(self):
assert(self.user.reputation < self.min_rep)
- assert(self.user.reputation < self.min_rep_own)
- self.assert_cannot_close(user = self.user)
+ self.assert_can_close(user=self.user)
def test_high_rep_owner_can_close(self):
- self.user.reputation = self.min_rep_own
+ self.user.reputation = self.min_rep
self.assert_can_close(user = self.user)
def test_high_rep_other_can_close(self):
@@ -380,14 +378,9 @@ class CloseQuestionPermissionAssertionTests(utils.AskbotTestCase):
self.other_user.reputation = self.min_rep
self.assert_cannot_close(user = self.other_user)
- def test_medium_rep_blocked_owner_cannot_close(self):
- self.user.set_status('b')
- self.user.reputation = self.min_rep_own
- self.assert_cannot_close(user = self.user)
-
def test_high_rep_blocked_owner_cannot_close(self):
self.user.set_status('b')
- self.user.reputation = self.min_rep
+ self.user.reputation = 2*self.min_rep
self.assert_cannot_close(user = self.user)
def test_low_rep_suspended_cannot_close(self):
@@ -402,12 +395,12 @@ class CloseQuestionPermissionAssertionTests(utils.AskbotTestCase):
def test_medium_rep_suspended_owner_cannot_close(self):
self.user.set_status('s')
- self.user.reputation = self.min_rep_own
+ self.user.reputation = self.min_rep
self.assert_cannot_close(user = self.user)
def test_high_rep_suspended_owner_cannot_close(self):
self.user.set_status('s')
- self.user.reputation = self.min_rep
+ self.user.reputation = 2*self.min_rep
self.assert_cannot_close(user = self.user)
@@ -423,7 +416,7 @@ class ReopenQuestionPermissionAssertionTests(utils.AskbotTestCase):
"""
def setUp(self):
- self.min_rep = askbot_settings.MIN_REP_TO_REOPEN_OWN_QUESTIONS
+ self.min_rep = askbot_settings.MIN_REP_TO_CLOSE_OTHERS_QUESTIONS
self.create_user()
self.create_user(username = 'other_user')
self.question = self.post_question()
@@ -1152,11 +1145,14 @@ class CommentPermissionAssertionTests(PermissionAssertionTestCase):
)
def test_suspended_user_can_comment_own_question(self):
+ #post question
question = self.post_question()
+ #suspend the poster
self.user.set_status('s')
+ #attempt to post a comment under the same question
comment = self.user.post_comment(
- parent_post = question,
- body_text = 'test comment'
+ parent_post=question,
+ body_text='test comment'
)
self.assertTrue(isinstance(comment, models.Post) and comment.is_comment())
self.assertTrue(
diff --git a/askbot/tests/post_model_tests.py b/askbot/tests/post_model_tests.py
index 2e785802..6d9233a2 100644
--- a/askbot/tests/post_model_tests.py
+++ b/askbot/tests/post_model_tests.py
@@ -365,7 +365,7 @@ class ThreadRenderLowLevelCachingTests(AskbotTestCase):
cache.cache = LocMemCache('', {}) # Enable local caching
thread = self.q.thread
- key = Thread.SUMMARY_CACHE_KEY_TPL % thread.id
+ key = Thread.SUMMARY_CACHE_KEY_TPL % (thread.id, 'en')
self.assertTrue(thread.summary_html_cached())
self.assertIsNotNone(thread.get_cached_summary_html())
diff --git a/askbot/tests/utils.py b/askbot/tests/utils.py
index 141f229a..0a207464 100644
--- a/askbot/tests/utils.py
+++ b/askbot/tests/utils.py
@@ -1,8 +1,10 @@
"""utility functions used by Askbot test cases
"""
+from django.core.cache import cache
from django.test import TestCase
from functools import wraps
from askbot import models
+from askbot.models import signals
def with_settings(**settings_dict):
"""a decorator that will run function with settings
@@ -71,7 +73,6 @@ def create_user(
if date_joined is not None:
user.date_joined = date_joined
user.save()
- user.set_status(status)
if notification_schedule == None:
notification_schedule = models.EmailFeedSetting.NO_EMAIL_SCHEDULE
@@ -86,6 +87,10 @@ def create_user(
subscriber = user
)
feed.save()
+
+ signals.user_registered.send(None, user=user)
+ user.set_status(status)
+
return user
@@ -94,6 +99,10 @@ class AskbotTestCase(TestCase):
to django TestCase class
"""
+ @classmethod
+ def setUpClass(cls):
+ cache.clear()
+
def create_user(
self,
username='user',
diff --git a/askbot/tests/widget_tests.py b/askbot/tests/widget_tests.py
index 98c5a8aa..73a5f06e 100644
--- a/askbot/tests/widget_tests.py
+++ b/askbot/tests/widget_tests.py
@@ -4,12 +4,15 @@ from askbot import models
from askbot.tests.utils import AskbotTestCase
from django.test.client import Client
+from django.conf import settings as django_settings
from django.core.urlresolvers import reverse
+from django.utils import translation
class WidgetViewsTests(AskbotTestCase):
def setUp(self):
+ translation.activate(django_settings.LANGUAGE_CODE)
self.client = Client()
self.widget = models.AskWidget.objects.create(title='foo widget')
self.user = self.create_user('user1')
@@ -74,6 +77,7 @@ class WidgetLoginViewTest(AskbotTestCase):
class WidgetCreatorViewsTests(AskbotTestCase):
def setUp(self):
+ translation.activate(django_settings.LANGUAGE_CODE)
self.client = Client()
self.user = self.create_user('user1')
self.user.set_password('testpass')
@@ -136,6 +140,7 @@ class WidgetCreatorViewsTests(AskbotTestCase):
class QuestionWidgetViewsTests(AskbotTestCase):
def setUp(self):
+ translation.activate(django_settings.LANGUAGE_CODE)
self.user = self.create_user('testuser')
self.client = Client()
self.widget = models.QuestionWidget.objects.create(title="foo",
diff --git a/askbot/urls.py b/askbot/urls.py
index bb902508..618562e7 100644
--- a/askbot/urls.py
+++ b/askbot/urls.py
@@ -35,13 +35,24 @@ sitemaps = {
#except those that are namespaced
PREFIX = getattr(settings, 'ASKBOT_SERVICE_URL_PREFIX', '')
+MAIN_PAGE_BASE_URL = getattr(
+ settings,
+ 'ASKBOT_MAIN_PAGE_BASE_URL',
+ _('questions')
+ ).strip('/') + '/'
+QUESTION_PAGE_BASE_URL = getattr(
+ settings,
+ 'ASKBOT_QUESTION_PAGE_BASE_URL',
+ _('question')
+ ).strip('/') + '/'
+
APP_PATH = os.path.dirname(__file__)
urlpatterns = patterns('',
url(r'^$', views.readers.index, name='index'),
# BEGIN Questions (main page) urls. All this urls work both normally and through ajax
url(
# Note that all parameters, even if optional, are provided to the view. Non-present ones have None value.
- (r'^%s' % _('questions') +
+ (r'^%s' % MAIN_PAGE_BASE_URL.strip('/') +
r'(%s)?' % r'/scope:(?P<scope>\w+)' +
r'(%s)?' % r'/sort:(?P<sort>[\w\-]+)' +
r'(%s)?' % r'/tags:(?P<tags>[\w+.#,-]+)' + # Should match: const.TAG_CHARS + ','; TODO: Is `#` char decoded by the time URLs are processed ??
@@ -54,7 +65,7 @@ urlpatterns = patterns('',
name='questions'
),
url(
- r'^%s(?P<id>\d+)/' % _('question/'),
+ r'^%s(?P<id>\d+)/' % QUESTION_PAGE_BASE_URL,
views.readers.question,
name='question'
),
@@ -229,32 +240,32 @@ urlpatterns = patterns('',
name='get_post_html'
),
service_url(
- r'^%s%s$' % (_('questions/'), _('ask/')),
+ r'^%s%s$' % (MAIN_PAGE_BASE_URL, _('ask/')),
views.writers.ask,
name='ask'
),
service_url(
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('edit/')),
+ r'^%s(?P<id>\d+)/%s$' % (MAIN_PAGE_BASE_URL, _('edit/')),
views.writers.edit_question,
name='edit_question'
),
service_url(#this url is both regular and ajax
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('retag/')),
+ r'^%s(?P<id>\d+)/%s$' % (MAIN_PAGE_BASE_URL, _('retag/')),
views.writers.retag_question,
name='retag_question'
),
service_url(
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('close/')),
+ r'^%s(?P<id>\d+)/%s$' % (MAIN_PAGE_BASE_URL, _('close/')),
views.commands.close,
name='close'
),
service_url(
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('reopen/')),
+ r'^%s(?P<id>\d+)/%s$' % (MAIN_PAGE_BASE_URL, _('reopen/')),
views.commands.reopen,
name='reopen'
),
service_url(
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('answer/')),
+ r'^%s(?P<id>\d+)/%s$' % (MAIN_PAGE_BASE_URL, _('answer/')),
views.writers.answer,
name='answer'
),
@@ -264,7 +275,7 @@ urlpatterns = patterns('',
name='vote'
),
service_url(
- r'^%s(?P<id>\d+)/%s$' % (_('questions/'), _('revisions/')),
+ r'^%s(?P<id>\d+)/%s$' % (MAIN_PAGE_BASE_URL, _('revisions/')),
views.readers.revisions,
kwargs = {'post_type': 'question'},
name='question_revisions'
@@ -543,7 +554,7 @@ urlpatterns = patterns('',
name = 'list_widgets'
),
service_url(
- r'^widgets/questions/(?P<widget_id>\d+)/$',
+ r'^widgets/%s(?P<widget_id>\d+)/$' % MAIN_PAGE_BASE_URL,
views.widgets.question_widget,
name='question_widget'
),
diff --git a/askbot/user_messages/context_processors.py b/askbot/user_messages/context_processors.py
index 230e967c..59f348ff 100644
--- a/askbot/user_messages/context_processors.py
+++ b/askbot/user_messages/context_processors.py
@@ -9,7 +9,7 @@ from django.utils.encoding import StrAndUnicode
from askbot.user_messages import get_and_delete_messages
-def user_messages (request):
+def user_messages(request):
"""
Returns session messages for the current session.
@@ -18,16 +18,19 @@ def user_messages (request):
#todo: a hack, for real we need to remove this middleware
#and switch to the new-style session messages
return {}
- messages = request.user.get_and_delete_messages()
- #if request.user.is_authenticated():
- #else:
- # messages = LazyMessages(request)
- #import inspect
- #print inspect.stack()[1]
- #print messages
- return { 'user_messages': messages }
-
-class LazyMessages (StrAndUnicode):
+
+ #the get_and_delete_messages is added to anonymous user by the
+ #ConnectToSessionMessages middleware by the process_request,
+ #however - if the user is logging out via /admin/logout/
+ #the AnonymousUser is installed in the response and thus
+ #the Askbot's session messages hack will fail, so we have
+ #an extra if statement here.
+ if hasattr(request.user, 'get_and_delete_messages'):
+ messages = request.user.get_and_delete_messages()
+ return { 'user_messages': messages }
+ return {}
+
+class LazyMessages(StrAndUnicode):
"""
Lazy message container, so messages aren't actually retrieved from
session and deleted until the template asks for them.
diff --git a/askbot/utils/get_plurals.py b/askbot/utils/get_plurals.py
new file mode 100644
index 00000000..1e30de24
--- /dev/null
+++ b/askbot/utils/get_plurals.py
@@ -0,0 +1,22 @@
+"""reads pluralization formulae from the .po files
+and prints out list of languages for each formula"""
+import sys
+import os.path
+import collections
+
+def find_formula(item):
+ return item.startswith('"Plural-Forms:')
+
+lang_codes = collections.defaultdict(set)
+
+for filename in sys.argv:
+ if not filename.endswith('.po'):
+ continue
+ lines = open(filename).readlines()
+ formula = filter(find_formula, lines)[0]
+ lang = os.path.dirname(os.path.dirname(filename))
+ lang_codes[formula].add(lang.split('/')[-1])
+
+for formula in lang_codes:
+ print lang_codes[formula]
+ print formula
diff --git a/askbot/utils/html.py b/askbot/utils/html.py
index 18a730a8..a9b489f4 100644
--- a/askbot/utils/html.py
+++ b/askbot/utils/html.py
@@ -89,7 +89,7 @@ def urlize_html(html):
#bs4 is weird, so we work around to replace nodes
#maybe there is a better way though
- urlized_text = urlize(node)
+ urlized_text = urlize(node, trim_url_limit=40)
if unicode(node) == urlized_text:
continue
diff --git a/askbot/utils/markup.py b/askbot/utils/markup.py
index 61821bba..ffa1fdde 100644
--- a/askbot/utils/markup.py
+++ b/askbot/utils/markup.py
@@ -202,8 +202,8 @@ def plain_text_input_converter(text):
def markdown_input_converter(text):
"""markdown to html converter"""
text = get_parser().convert(text)
- text = urlize_html(text)
- return sanitize_html(text)
+ text = sanitize_html(text)
+ return urlize_html(text)
def tinymce_input_converter(text):
"""tinymce input to production html converter"""
diff --git a/askbot/utils/pluralization.py b/askbot/utils/pluralization.py
new file mode 100644
index 00000000..74549f10
--- /dev/null
+++ b/askbot/utils/pluralization.py
@@ -0,0 +1,144 @@
+"""pluralization formulae for the supported languages"""
+import logging
+
+def arabic(count):
+ """six forms for arabic:
+ n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"""
+ if count == 0:
+ return 0
+ elif count == 1:
+ return 1
+ elif count == 2:
+ return 2
+ else:
+ rem = count % 100
+ if rem >= 3 and rem <= 10:
+ return 3
+ if rem >= 11 and rem <= 99:
+ return 4
+ return 5
+
+def germannic(count):
+ """two forms for germannic languages"""
+ return int(count != 1)
+
+def francoid(count):
+ """french, portuguese"""
+ return int(count > 1)
+
+def singular(count):
+ return 0
+
+def slavic(count):
+ """'ru', 'sr', 'hr'"""
+ rem10 = count % 10
+ rem100 = count % 100
+ if rem10 == 1 and rem100 != 11:
+ return 0
+ elif rem10 >=2 and rem10 <= 4 and (rem100 < 10 or rem100 >= 20):
+ return 1
+ return 2
+
+def romanian(count):
+ if count == 1:
+ return 0
+ else:
+ rem100 = count % 100
+ if rem100 > 19 or (count and rem100 == 0):
+ return 2
+ return 1
+
+def polish(count):
+ if count == 1:
+ return 0
+ else:
+ rem10 = count % 10
+ rem100 = count % 100
+ if rem10 >=2 and rem10 <= 4 and (rem100 < 10 and rem100 >= 20):
+ return 1
+ return 2
+
+def slovenian(count):
+ rem100 = count % 100
+ if rem100 == 1:
+ return 0
+ elif rem100 == 2:
+ return 1
+ elif rem100 in (3, 4):
+ return 2
+ return 3
+
+def chech(count):
+ if count == 1:
+ return 0
+ elif count >=2 and count <=4:
+ return 1
+ return 2
+
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+
+FORMULAE = {
+ 'arabic': arabic,
+ 'germannic': germannic,
+ 'slavic': slavic,
+ 'singular': singular,
+ 'romanian': romanian,
+ 'slovenian': slovenian,
+ 'chech': chech,
+ 'francoid': francoid
+}
+
+GERMANNIC_FAMILY = (
+ 'en', 'bg', 'bg_BG', 'el', 'nb_NO', 'pt', 'ast', 'ca', 'de',
+ 'it', 'hu', 'hi', 'sv_SE', 'fi', 'he_IL', 'gl', 'es', 'bn_IN'
+)
+
+FRANCOID_FAMILY = ('fr', 'pt', 'pt_BR')
+
+SLAVIC_FAMILY = (
+ 'ru', 'sr', 'hr'
+)
+
+ROMANIAN_FAMILY = ('ro',)
+POLISH_FAMILY = ('pl',)
+SLOVENIAN_FAMILY = ('sl',)
+CHECH_FAMILY = ('cs', 'cs_CZ')
+
+SINGULAR_FAMILY = (
+ 'zh_HK', 'fa_IR', 'zh_CN', 'id_ID', 'zh_TW', 'ko', 'ms_MY', 'tr', 'tr_TR', 'vi', 'ja'
+)
+
+def get_formula(lang):
+ """returns pluralization formula, default to germannic"""
+ if lang == 'ar':
+ return arabic
+ elif lang in GERMANNIC_FAMILY:
+ return germannic
+ elif lang in SINGULAR_FAMILY:
+ return singular
+ elif lang in SLAVIC_FAMILY:
+ return slavic
+ elif lang in FRANCOID_FAMILY:
+ return francoid
+ elif lang in ROMANIAN_FAMILY:
+ return romanian
+ elif lang in POLISH_FAMILY:
+ return polish
+ elif lang in SLOVENIAN_FAMILY:
+ return slovenian
+ elif lang in SINGULAR_FAMILY:
+ return singular
+ logging.critical('language %s not supported by askbot.utils.pluralization' % lang)
+ return germannic
+
+def py_pluralize(plural_forms, count):
+ from django.utils.translation import get_language
+ lang = get_language()
+ formula = get_formula(lang)
+ num_forms = len(plural_forms)
+ form_number = formula(count)
+ if form_number >= num_forms:
+ template = 'not enough plural forms for %s in language %s'
+ logging.critical(template % (str(plural_forms), lang))
+ form_number = num_forms - 1
+ return plural_forms[form_number]
diff --git a/askbot/utils/slug.py b/askbot/utils/slug.py
index 1c95e1d4..c27c8b79 100644
--- a/askbot/utils/slug.py
+++ b/askbot/utils/slug.py
@@ -17,6 +17,12 @@ from django.utils.encoding import smart_unicode
# Extra characters outside of alphanumerics that we'll allow.
SLUG_OK = '-_~'
+def slugify_camelcase(camel):
+ """Converts CamelCase to camel-case"""
+ def subf(match):
+ return '-' + match.groups(1)[0].lower()
+ return re.sub('([A-Z])', subf, camel).strip('-')
+
def unicode_slugify(s, ok=SLUG_OK, lower=True, spaces=False):
"""Function copied from https://github.com/mozilla/unicode-slugify
@@ -67,4 +73,4 @@ def slugify(input_text, max_length=150):
#apply the cut-off directly
slug = slug[:max_length]
break
- return slug
+ return slug or '_'
diff --git a/askbot/views/commands.py b/askbot/views/commands.py
index 8e08c3c4..2ade1b36 100644
--- a/askbot/views/commands.py
+++ b/askbot/views/commands.py
@@ -283,9 +283,10 @@ def vote(request):
else:
raise exceptions.PermissionDenied(
- _('Sorry, but anonymous users cannot accept answers')
- )
-
+ _('Sorry, but anonymous users cannot %(perform_action)s') % {
+ 'perform_action': askbot_settings.WORDS_ACCEPT_OR_UNACCEPT_THE_BEST_ANSWER
+ }
+ )
elif vote_type in ('1', '2', '5', '6'):#Q&A up/down votes
###############################
@@ -376,14 +377,17 @@ def vote(request):
question = get_object_or_404(models.Post, post_type='question', id=id)
vote_type = request.POST.get('type')
- #accept answer
if vote_type == '4':
+ #follow question
fave = request.user.toggle_favorite_question(question)
response_data['count'] = models.FavoriteQuestion.objects.filter(thread = question.thread).count()
if fave == False:
response_data['status'] = 1
elif vote_type == '11':#subscribe q updates
+ #todo: this branch is not used anymore
+ #now we just follow question, we don't have the
+ #separate "subscribe" function
user = request.user
if user.is_authenticated():
if user not in question.thread.followed_by.all():
@@ -998,7 +1002,7 @@ def delete_post(request):
@csrf.csrf_exempt
def read_message(request):#marks message a read
if request.method == "POST":
- if request.POST['formdata'] == 'required':
+ if request.POST.get('formdata') == 'required':
request.session['message_silent'] = 1
if request.user.is_authenticated():
request.user.delete_messages()
diff --git a/askbot/views/context.py b/askbot/views/context.py
index 2b9ef5ea..eda8f6a7 100644
--- a/askbot/views/context.py
+++ b/askbot/views/context.py
@@ -13,13 +13,15 @@ def get_for_tag_editor():
#data for the tag editor
data = {
'tag_regex': const.TAG_REGEX,
+ 'tag_forbidden_first_chars': const.TAG_FORBIDDEN_FIRST_CHARS,
'tags_are_required': askbot_settings.TAGS_ARE_REQUIRED,
'max_tags_per_post': askbot_settings.MAX_TAGS_PER_POST,
'max_tag_length': askbot_settings.MAX_TAG_LENGTH,
'force_lowercase_tags': askbot_settings.FORCE_LOWERCASE_TAGS,
'messages': {
'required': _(msg.TAGS_ARE_REQUIRED_MESSAGE),
- 'wrong_chars': _(msg.TAG_WRONG_CHARS_MESSAGE)
+ 'wrong_chars': _(msg.TAG_WRONG_CHARS_MESSAGE),
+ 'wrong_first_char': _(msg.TAG_WRONG_FIRST_CHAR_MESSAGE),
}
}
return {'tag_editor_settings': simplejson.dumps(data)}
diff --git a/askbot/views/meta.py b/askbot/views/meta.py
index 692216da..6e80957c 100644
--- a/askbot/views/meta.py
+++ b/askbot/views/meta.py
@@ -9,7 +9,10 @@ from django.core.paginator import Paginator, EmptyPage, InvalidPage
from django.shortcuts import render
from django.template import RequestContext, Template
from django.template.loader import get_template
-from django.http import HttpResponseRedirect, HttpResponse, Http404
+from django.http import Http404
+from django.http import HttpResponse
+from django.http import HttpResponseForbidden
+from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy
@@ -21,13 +24,16 @@ from askbot.conf import settings as askbot_settings
from askbot.forms import FeedbackForm
from askbot.utils.url_utils import get_login_url
from askbot.utils.forms import get_next_url
-from askbot.mail import mail_moderators
+from askbot.mail import mail_moderators, send_mail
from askbot.models import BadgeData, Award, User, Tag
from askbot.models import badges as badge_data
from askbot.skins.loaders import render_text_into_skin
from askbot.utils.decorators import admins_only
from askbot.utils.forms import get_next_url
from askbot.utils import functions
+from recaptcha_works.decorators import fix_recaptcha_remote_ip
+
+import re
def generic_view(request, template = None, page_class = None):
"""this may be not necessary, since it is just a rewrite of render"""
@@ -35,13 +41,18 @@ def generic_view(request, template = None, page_class = None):
return render_to_response('django_error.html')
return render(request, template, {'page_class': page_class})
+PUBLIC_VARIABLES = ('CUSTOM_CSS', 'CUSTOM_JS')
+
def config_variable(request, variable_name = None, mimetype = None):
"""Print value from the configuration settings
as response content. All parameters are required.
"""
- #todo add http header-based caching here!!!
- output = getattr(askbot_settings, variable_name, '')
- return HttpResponse(output, mimetype = mimetype)
+ if variable_name in PUBLIC_VARIABLES:
+ #todo add http header-based caching here!!!
+ output = getattr(askbot_settings, variable_name, '')
+ return HttpResponse(output, mimetype = mimetype)
+ else:
+ return HttpResponseForbidden()
def about(request, template='about.html'):
title = _('About %(site)s') % {'site': askbot_settings.APP_SHORT_NAME}
@@ -82,6 +93,7 @@ def faq(request):
return render(request, 'faq_static.html', data)
@csrf.csrf_protect
+@fix_recaptcha_remote_ip
def feedback(request):
data = {'page_class': 'meta'}
form = None
@@ -113,12 +125,21 @@ def feedback(request):
headers = {}
if data['email']:
headers = {'Reply-To': data['email']}
-
- mail_moderators(
- _('Q&A forum feedback'),
- message,
- headers=headers
- )
+ subject = _('Q&A forum feedback')
+ if askbot_settings.FEEDBACK_EMAILS:
+ recipients = re.split('\s*,\s*', askbot_settings.FEEDBACK_EMAILS)
+ send_mail(
+ subject_line=subject,
+ body_text=message,
+ headers=headers,
+ recipient_list=recipients,
+ )
+ else:
+ mail_moderators(
+ subject_line=subject,
+ body_text=message,
+ headers=headers
+ )
msg = _('Thanks for the feedback!')
request.user.message_set.create(message=msg)
return HttpResponseRedirect(get_next_url(request))
diff --git a/askbot/views/readers.py b/askbot/views/readers.py
index 8bf2cea9..155be946 100644
--- a/askbot/views/readers.py
+++ b/askbot/views/readers.py
@@ -154,6 +154,7 @@ def questions(request, **kwargs):
if request.is_ajax():
q_count = paginator.count
+ #todo: words
question_counter = ungettext('%(q_num)s question', '%(q_num)s questions', q_count)
question_counter = question_counter % {'q_num': humanize.intcomma(q_count),}
@@ -262,7 +263,9 @@ def questions(request, **kwargs):
request,
template_data
)
+
template_data.update(extra_context)
+ template_data.update(context.get_for_tag_editor())
#and one more thing:) give admin user heads up about
#setting the domain name if they have not done that yet
@@ -738,8 +741,6 @@ def get_perms_data(request):
'MIN_REP_TO_UPLOAD_FILES',
'MIN_REP_TO_INSERT_LINK',
'MIN_REP_TO_SUGGEST_LINK',
- 'MIN_REP_TO_CLOSE_OWN_QUESTIONS',
- 'MIN_REP_TO_REOPEN_OWN_QUESTIONS',
'MIN_REP_TO_CLOSE_OTHERS_QUESTIONS',
'MIN_REP_TO_RETAG_OTHERS_QUESTIONS',
'MIN_REP_TO_EDIT_WIKI',
diff --git a/askbot/views/users.py b/askbot/views/users.py
index 14aad336..57397457 100644
--- a/askbot/views/users.py
+++ b/askbot/views/users.py
@@ -283,7 +283,6 @@ def user_moderate(request, subject, context):
'active_tab': 'users',
'page_class': 'user-profile-page',
'tab_name': 'moderation',
- 'tab_description': _('moderate this user'),
'page_title': _('moderate user'),
'change_user_status_form': user_status_form,
'change_user_reputation_form': user_rep_form,
@@ -529,7 +528,6 @@ def user_stats(request, user, context):
'page_class': 'user-profile-page',
'support_custom_avatars': ('avatar' in django_settings.INSTALLED_APPS),
'tab_name' : 'stats',
- 'tab_description' : _('user profile'),
'page_title' : _('user profile overview'),
'user_status_for_display': user.get_status_display(soft = True),
'questions' : questions,
@@ -653,7 +651,6 @@ def user_recent(request, user, context):
'active_tab': 'users',
'page_class': 'user-profile-page',
'tab_name' : 'recent',
- 'tab_description' : _('recent user activity'),
'page_title' : _('profile - recent activity'),
'activities' : activities
}
@@ -685,7 +682,6 @@ def show_group_join_requests(request, user, context):
'inbox_section': 'group-join-requests',
'page_class': 'user-profile-page',
'tab_name' : 'join_requests',
- 'tab_description' : _('group joining requests'),
'page_title' : _('profile - moderation'),
'groups_dict': groups_dict,
'join_requests': join_requests
@@ -742,7 +738,6 @@ def user_responses(request, user, context):
'page_class': 'user-profile-page',
'tab_name' : 'inbox',
'inbox_section': section,
- 'tab_description' : _('private messages'),
'page_title' : _('profile - messages')
}
context.update(data)
@@ -822,7 +817,6 @@ def user_responses(request, user, context):
'page_class': 'user-profile-page',
'tab_name' : 'inbox',
'inbox_section': section,
- 'tab_description' : _('comments and answers to others questions'),
'page_title' : _('profile - responses'),
'post_reject_reasons': reject_reasons,
'responses' : filtered_response_list,
@@ -864,7 +858,6 @@ def user_votes(request, user, context):
'active_tab':'users',
'page_class': 'user-profile-page',
'tab_name' : 'votes',
- 'tab_description' : _('user vote record'),
'page_title' : _('profile - votes'),
'votes' : votes[:const.USER_VIEW_DATA_SIZE]
}
@@ -886,7 +879,6 @@ def user_reputation(request, user, context):
'active_tab':'users',
'page_class': 'user-profile-page',
'tab_name': 'reputation',
- 'tab_description': _('user karma'),
'page_title': _("Profile - User's Karma"),
'reputation': reputes,
'reps': reps
@@ -922,8 +914,7 @@ def user_favorites(request, user, context):
'active_tab':'users',
'page_class': 'user-profile-page',
'tab_name' : 'favorites',
- 'tab_description' : _('users favorite questions'),
- 'page_title' : _('profile - favorite questions'),
+ 'page_title' : _('profile - favorites'),
'questions' : questions,
'q_paginator_context': q_paginator_context,
'question_count': question_count,
@@ -996,7 +987,6 @@ def user_email_subscriptions(request, user, context):
'subscribed_tag_names': user.get_marked_tag_names('subscribed'),
'page_class': 'user-profile-page',
'tab_name': 'email_subscriptions',
- 'tab_description': _('email subscription settings'),
'page_title': _('profile - email subscriptions'),
'email_feeds_form': email_feeds_form,
'tag_filter_selection_form': tag_filter_form,
diff --git a/askbot/views/widgets.py b/askbot/views/widgets.py
index 5c4042fa..c049f91d 100644
--- a/askbot/views/widgets.py
+++ b/askbot/views/widgets.py
@@ -60,6 +60,10 @@ def ask_widget(request, widget_id):
widget = get_object_or_404(models.AskWidget, id=widget_id)
if request.method == "POST":
+
+ if askbot_settings.READ_ONLY_MODE_ENABLED:
+ return redirect('ask_by_widget')
+
form = forms.AskWidgetForm(
include_text=widget.include_text_field,
data=request.POST,
diff --git a/askbot/views/writers.py b/askbot/views/writers.py
index 7df425ee..9234c37f 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -205,13 +205,7 @@ def import_data(request):
#@login_required #actually you can post anonymously, but then must register
@csrf.csrf_protect
-@decorators.check_authorization_to_post(ugettext_lazy(
- "<span class=\"strong big\">You are welcome to start submitting your question "
- "anonymously</span>. When you submit the post, you will be redirected to the "
- "login/signup page. Your question will be saved in the current session and "
- "will be published after you log in. Login/signup process is very simple. "
- "Login takes about 30 seconds, initial signup takes a minute or less."
-))
+@decorators.check_authorization_to_post(ugettext_lazy('Please log in to make posts'))
@decorators.check_spam('text')
def ask(request):#view used to ask a new question
"""a view to ask a new question
@@ -226,6 +220,9 @@ def ask(request):#view used to ask a new question
request.user.message_set.create(message=_('Sorry, but you have only read access'))
return HttpResponseRedirect(referer)
+ if askbot_settings.READ_ONLY_MODE_ENABLED:
+ return HttpResponseRedirect(reverse('index'))
+
form = forms.AskForm(request.REQUEST, user=request.user)
if request.method == 'POST':
if form.is_valid():
@@ -390,8 +387,13 @@ def edit_question(request, id):
"""edit question view
"""
question = get_object_or_404(models.Post, id=id)
+
+ if askbot_settings.READ_ONLY_MODE_ENABLED:
+ return HttpResponseRedirect(question.get_absolute_url())
+
revision = question.get_latest_revision()
revision_form = None
+
try:
request.user.assert_can_edit_question(question)
if request.method == 'POST':
@@ -492,6 +494,10 @@ def edit_question(request, id):
@decorators.check_spam('text')
def edit_answer(request, id):
answer = get_object_or_404(models.Post, id=id)
+
+ if askbot_settings.READ_ONLY_MODE_ENABLED:
+ return HttpResponseRedirect(answer.get_absolute_url())
+
revision = answer.get_latest_revision()
class_path = getattr(settings, 'ASKBOT_EDIT_ANSWER_FORM', None)
@@ -579,7 +585,7 @@ def edit_answer(request, id):
return HttpResponseRedirect(answer.get_absolute_url())
#todo: rename this function to post_new_answer
-@decorators.check_authorization_to_post(ugettext_lazy('Please log in to answer questions'))
+@decorators.check_authorization_to_post(ugettext_lazy('Please log in to make posts'))
@decorators.check_spam('text')
def answer(request, id, form_class=forms.AnswerForm):#process a new answer
"""view that posts new answer
@@ -590,6 +596,10 @@ def answer(request, id, form_class=forms.AnswerForm):#process a new answer
authenticated users post directly
"""
question = get_object_or_404(models.Post, post_type='question', id=id)
+
+ if askbot_settings.READ_ONLY_MODE_ENABLED:
+ return HttpResponseRedirect(question.get_absolute_url())
+
if request.method == "POST":
#this check prevents backward compatilibility
@@ -727,6 +737,10 @@ def post_comments(request):#generic ajax handler to load comments to an object
'<a href="%(sign_in_url)s">sign in</a>.') % \
{'sign_in_url': url_utils.get_login_url()}
raise exceptions.PermissionDenied(msg)
+
+ if askbot_settings.READ_ONLY_MODE_ENABLED:
+ raise exceptions.PermissionDenied(askbot_settings.READ_ONLY_MESSAGE)
+
comment = user.post_comment(
parent_post=post, body_text=form.cleaned_data['comment']
)
@@ -741,13 +755,16 @@ def post_comments(request):#generic ajax handler to load comments to an object
return response
-#@csrf.csrf_exempt
+@csrf.csrf_exempt
@decorators.ajax_only
#@decorators.check_spam('comment')
def edit_comment(request):
if request.user.is_anonymous():
raise exceptions.PermissionDenied(_('Sorry, anonymous users cannot edit comments'))
+ if askbot_settings.READ_ONLY_MODE_ENABLED:
+ raise exceptions.PermissionDenied(askbot_settings.READ_ONLY_MESSAGE)
+
form = forms.EditCommentForm(request.POST)
if form.is_valid() == False:
raise exceptions.PermissionDenied('This content is forbidden')
@@ -811,6 +828,9 @@ def delete_comment(request):
comment = get_object_or_404(models.Post, post_type='comment', id=comment_id)
request.user.assert_can_delete_comment(comment)
+ if askbot_settings.READ_ONLY_MODE_ENABLED:
+ raise exceptions.PermissionDenied(askbot_settings.READ_ONLY_MESSAGE)
+
parent = comment.parent
comment.delete()
#attn: recalc denormalized field
@@ -831,17 +851,24 @@ def delete_comment(request):
@decorators.post_only
def comment_to_answer(request):
- comment_id = request.POST.get('comment_id')
- if comment_id:
- comment_id = int(comment_id)
- comment = get_object_or_404(models.Post,
- post_type='comment', id=comment_id)
- request.user.repost_comment_as_answer(comment)
- return HttpResponseRedirect(comment.get_absolute_url())
- else:
+ try:
+ comment_id = int(request.POST.get('comment_id'))
+ except (ValueError, TypeError):
+ #type or value error is raised is int() fails
raise Http404
+ comment = get_object_or_404(
+ models.Post,
+ post_type='comment',
+ id=comment_id
+ )
+
+ if askbot_settings.READ_ONLY_MODE_ENABLED is False:
+ request.user.repost_comment_as_answer(comment)
+
+ return HttpResponseRedirect(comment.get_absolute_url())
+
@decorators.post_only
@csrf.csrf_protect
#todo: change the urls config for this
@@ -858,6 +885,9 @@ def repost_answer_as_comment(request, destination=None):
answer = get_object_or_404(models.Post,
post_type = 'answer', id=answer_id)
+ if askbot_settings.READ_ONLY_MODE_ENABLED:
+ return HttpResponseRedirect(answer.get_absolute_url())
+
if destination == 'comment_under_question':
destination_post = answer.thread._question_post()
else:
@@ -873,8 +903,8 @@ def repost_answer_as_comment(request, destination=None):
if len(answer.text) <= askbot_settings.MAX_COMMENT_LENGTH:
answer.post_type = 'comment'
answer.parent = destination_post
- #can we trust this?
- old_comment_count = answer.comment_count
+
+ new_comment_count = answer.comments.count() + 1
answer.comment_count = 0
answer_comments = models.Post.objects.get_comments().filter(parent=answer)
@@ -884,7 +914,7 @@ def repost_answer_as_comment(request, destination=None):
answer.parse_and_save(author=answer.author)
answer.thread.update_answer_count()
- answer.parent.comment_count = 1 + old_comment_count
+ answer.parent.comment_count += new_comment_count
answer.parent.save()
answer.thread.invalidate_cached_data()