summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.gitignore2
-rw-r--r--askbot/__init__.py9
-rw-r--r--askbot/admin.py5
-rw-r--r--askbot/auth.py2
-rw-r--r--askbot/conf/__init__.py10
-rw-r--r--askbot/conf/access_control.py2
-rw-r--r--askbot/conf/badges.py2
-rw-r--r--askbot/conf/email.py2
-rw-r--r--askbot/conf/external_keys.py2
-rw-r--r--askbot/conf/flatpages.py18
-rw-r--r--askbot/conf/forum_data_rules.py16
-rw-r--r--askbot/conf/group_settings.py2
-rw-r--r--askbot/conf/karma_and_badges_visibility.py2
-rw-r--r--askbot/conf/ldap.py12
-rw-r--r--askbot/conf/leading_sidebar.py2
-rw-r--r--askbot/conf/license.py2
-rw-r--r--askbot/conf/login_providers.py9
-rw-r--r--askbot/conf/markup.py2
-rw-r--r--askbot/conf/minimum_reputation.py2
-rw-r--r--askbot/conf/moderation.py16
-rw-r--r--askbot/conf/reputation_changes.py2
-rw-r--r--askbot/conf/sidebar_main.py2
-rw-r--r--askbot/conf/sidebar_profile.py2
-rw-r--r--askbot/conf/sidebar_question.py17
-rw-r--r--askbot/conf/site_modes.py2
-rw-r--r--askbot/conf/site_settings.py2
-rw-r--r--askbot/conf/skin_general_settings.py2
-rw-r--r--askbot/conf/social_sharing.py24
-rw-r--r--askbot/conf/spam_and_moderation.py2
-rw-r--r--askbot/conf/super_groups.py2
-rw-r--r--askbot/conf/user_settings.py2
-rw-r--r--askbot/conf/vote_rules.py2
-rw-r--r--askbot/const/__init__.py18
-rw-r--r--askbot/const/message_keys.py5
-rw-r--r--askbot/context.py5
-rw-r--r--askbot/deployment/__init__.py158
-rw-r--r--askbot/deployment/messages.py12
-rw-r--r--askbot/deployment/path_utils.py19
-rw-r--r--askbot/deps/django_authopenid/backends.py2
-rw-r--r--askbot/deps/django_authopenid/forms.py28
-rw-r--r--askbot/deps/django_authopenid/urls.py12
-rw-r--r--askbot/deps/django_authopenid/util.py100
-rw-r--r--askbot/deps/django_authopenid/views.py149
-rw-r--r--askbot/deps/group_messaging/__init__.py (renamed from group_messaging/__init__.py)3
-rw-r--r--askbot/deps/group_messaging/migrations/0001_initial.py (renamed from group_messaging/migrations/0001_initial.py)0
-rw-r--r--askbot/deps/group_messaging/migrations/0002_auto__add_lastvisittime__add_unique_lastvisittime_user_message__add_fi.py (renamed from group_messaging/migrations/0002_auto__add_lastvisittime__add_unique_lastvisittime_user_message__add_fi.py)0
-rw-r--r--askbot/deps/group_messaging/migrations/__init__.py (renamed from group_messaging/migrations/__init__.py)0
-rw-r--r--askbot/deps/group_messaging/models.py438
-rw-r--r--askbot/deps/group_messaging/tests.py363
-rw-r--r--askbot/deps/group_messaging/urls.py (renamed from group_messaging/urls.py)5
-rw-r--r--askbot/deps/group_messaging/views.py (renamed from group_messaging/views.py)92
-rw-r--r--askbot/deps/livesettings/functions.py4
-rw-r--r--askbot/deps/livesettings/models.py6
-rw-r--r--askbot/deps/livesettings/values.py13
-rw-r--r--askbot/doc/source/changelog.rst35
-rw-r--r--askbot/doc/source/contributors.rst5
-rw-r--r--askbot/doc/source/initial-configuration.rst2
-rw-r--r--askbot/doc/source/management-commands.rst2
-rw-r--r--askbot/feed.py24
-rw-r--r--askbot/forms.py112
-rw-r--r--askbot/importers/stackexchange/management/commands/load_stackexchange.py140
-rw-r--r--askbot/locale/es/LC_MESSAGES/django.mobin137973 -> 137966 bytes
-rw-r--r--askbot/locale/es/LC_MESSAGES/django.po2
-rw-r--r--askbot/locale/hr/LC_MESSAGES/django.mobin0 -> 159291 bytes
-rw-r--r--askbot/locale/hr/LC_MESSAGES/django.po6215
-rw-r--r--askbot/locale/hr/LC_MESSAGES/djangojs.mobin0 -> 4865 bytes
-rw-r--r--askbot/locale/hr/LC_MESSAGES/djangojs.po295
-rw-r--r--askbot/locale/ko/LC_MESSAGES/django.mobin2439 -> 170304 bytes
-rw-r--r--askbot/locale/ko/LC_MESSAGES/django.po3973
-rw-r--r--askbot/locale/ko/LC_MESSAGES/djangojs.mobin440 -> 5446 bytes
-rw-r--r--askbot/locale/ko/LC_MESSAGES/djangojs.po172
-rw-r--r--askbot/mail/__init__.py77
-rw-r--r--askbot/mail/lamson_handlers.py17
-rw-r--r--askbot/mail/messages.py4
-rw-r--r--askbot/mail/parsing.py85
-rw-r--r--askbot/management/commands/askbot_add_test_content.py10
-rw-r--r--askbot/management/commands/askbot_create_test_fixture.py76
-rw-r--r--askbot/management/commands/fix_revisionless_posts.py6
-rw-r--r--askbot/management/commands/send_accept_answer_reminders.py4
-rw-r--r--askbot/management/commands/send_unanswered_question_reminders.py4
-rw-r--r--askbot/media/images/ajax-loader.gifbin0 -> 723 bytes
-rw-r--r--askbot/media/images/delete.pngbin434 -> 431 bytes
-rw-r--r--askbot/media/images/edit2.pngbin498 -> 571 bytes
-rw-r--r--askbot/media/images/flag.pngbin515 -> 519 bytes
-rw-r--r--askbot/media/images/link.pngbin601 -> 513 bytes
-rw-r--r--askbot/media/images/sprites.pngbin12478 -> 18549 bytes
-rw-r--r--askbot/media/jquery-openid/images/launchpad.gifbin0 -> 2017 bytes
-rw-r--r--askbot/media/jquery-openid/images/launchpad.xcfbin0 -> 22408 bytes
-rw-r--r--askbot/media/jquery-openid/jquery.openid.js7
-rw-r--r--askbot/media/js/group_messaging.js123
-rw-r--r--askbot/media/js/live_search.js1078
-rw-r--r--askbot/media/js/live_search_new_thread.js4
-rw-r--r--askbot/media/js/post.js104
-rw-r--r--askbot/media/js/tag_moderation.js14
-rw-r--r--askbot/media/js/tag_selector.js11
-rw-r--r--askbot/media/js/utils.js164
-rw-r--r--askbot/media/style/style.css745
-rw-r--r--askbot/media/style/style.less720
-rw-r--r--askbot/middleware/forum_mode.py12
-rw-r--r--askbot/migrations/0013_add_response_count__to_user.py17
-rw-r--r--askbot/migrations/0014_rename_schema_from_forum_to_askbot.py21
-rw-r--r--askbot/migrations/0018_add___status__field_to_user_model.py16
-rw-r--r--askbot/migrations/0026_add_seen_and_new_response_counts_to_user.py8
-rw-r--r--askbot/migrations/0033_add__consecutive_days_visit_count__to__auth_user.py16
-rw-r--r--askbot/migrations/0035_add_country_fields_to_user.py8
-rw-r--r--askbot/migrations/0037_add_marked_tags_to_user_profile.py12
-rw-r--r--askbot/migrations/0038_add_tag_filter_strategies.py32
-rw-r--r--askbot/migrations/0043_add_temporal_extra_column_for_datamigration.py6
-rw-r--r--askbot/migrations/0122_auth_user__add_subscribed_tag_field.py8
-rw-r--r--askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py15
-rw-r--r--askbot/migrations/0125_add_show_tags_field_to_user.py18
-rw-r--r--askbot/migrations/0126_add_field__auth_user__is_fake.py11
-rw-r--r--askbot/migrations/0156_add_message_model_in_new_django.py388
-rw-r--r--askbot/migrations/0157_auto__del_field_anonymousquestion_summary__del_field_anonymousanswer_s.py387
-rw-r--r--askbot/migrations/0158_add_title_search_indices_for_postgresql_and_mysql.py405
-rw-r--r--askbot/migrations/0159_auto__add_field_thread_language_code.py380
-rw-r--r--askbot/migrations/0160_add_model_BulkTagSubscription.py424
-rw-r--r--askbot/migrations/0161_add_field__user_languages.py393
-rw-r--r--askbot/migrations/0162_auto__add_field_post_language_code.py391
-rw-r--r--askbot/migrations/0163_update_postgres_multilingual_search.py402
-rw-r--r--askbot/migrations/0164_update_postgres_user_search.py399
-rw-r--r--askbot/migrations/0165_update_thread_search.py399
-rw-r--r--askbot/migrations/0166_auto__add_field_thread_deleted.py391
-rw-r--r--askbot/migrations/0167_populate_thread_deleted_field.py397
-rw-r--r--askbot/migrations/__init__.py5
-rw-r--r--askbot/migrations_api/__init__.py41
-rw-r--r--askbot/models/__init__.py299
-rw-r--r--askbot/models/base.py1
-rw-r--r--askbot/models/message.py28
-rw-r--r--askbot/models/post.py209
-rw-r--r--askbot/models/question.py153
-rw-r--r--askbot/models/reply_by_email.py13
-rw-r--r--askbot/models/repute.py2
-rw-r--r--askbot/models/tag.py9
-rw-r--r--askbot/models/user.py98
-rw-r--r--askbot/models/widgets.py6
-rw-r--r--askbot/patches/__init__.py3
-rw-r--r--askbot/patches/django_patches.py13
-rw-r--r--askbot/search/mysql.py11
-rw-r--r--askbot/search/postgresql/__init__.py56
-rw-r--r--askbot/search/postgresql/thread_and_post_models_01022013.plsql298
-rw-r--r--askbot/search/postgresql/thread_and_post_models_10032013.plsql304
-rw-r--r--askbot/search/postgresql/thread_and_post_models_27112012.plsql240
-rw-r--r--askbot/search/postgresql/user_profile_search_02262013.plsql102
-rw-r--r--askbot/search/state_manager.py6
-rw-r--r--askbot/setup_templates/settings.py6
-rw-r--r--askbot/setup_templates/settings.py.mustache33
-rw-r--r--askbot/setup_templates/urls.py23
-rw-r--r--askbot/skins/loaders.py52
-rw-r--r--askbot/skins/utils.py16
-rw-r--r--askbot/startup_procedures.py181
-rw-r--r--askbot/tasks.py22
-rw-r--r--askbot/templates/404.html49
-rw-r--r--askbot/templates/404.jinja.html44
-rw-r--r--askbot/templates/500.html (renamed from askbot/templates/500.jinja.html)0
-rw-r--r--askbot/templates/answer_edit.html5
-rw-r--r--askbot/templates/ask.html38
-rw-r--r--askbot/templates/authopenid/complete.html33
-rw-r--r--askbot/templates/authopenid/logout.html21
-rw-r--r--askbot/templates/authopenid/providers_javascript.html16
-rw-r--r--askbot/templates/authopenid/signup_with_password.html12
-rw-r--r--askbot/templates/badges.html17
-rw-r--r--askbot/templates/base.html15
-rw-r--r--askbot/templates/debug_header.html3
-rw-r--r--askbot/templates/email/base_mail.html12
-rw-r--r--askbot/templates/email/macros.html20
-rw-r--r--askbot/templates/embed/ask_by_widget.html18
-rwxr-xr-xaskbot/templates/embed/askbot_widget.js6
-rw-r--r--askbot/templates/embed/delete_widget.html2
-rw-r--r--askbot/templates/embed/list_widgets.html21
-rw-r--r--askbot/templates/embed/widget_form.html2
-rw-r--r--askbot/templates/group_messaging/email_alert.html18
-rw-r--r--askbot/templates/group_messaging/home_thread_details.html16
-rw-r--r--askbot/templates/group_messaging/senders_list.html18
-rw-r--r--askbot/templates/group_messaging/threads_list.html14
-rw-r--r--askbot/templates/list_suggested_tags.html24
-rw-r--r--askbot/templates/macros.html63
-rw-r--r--askbot/templates/main_page/javascript.html10
-rw-r--r--askbot/templates/main_page/tab_bar.html6
-rw-r--r--askbot/templates/meta/bottom_scripts.html42
-rw-r--r--askbot/templates/meta/fonts.html23
-rw-r--r--askbot/templates/meta/html_head_javascript.html1
-rw-r--r--askbot/templates/meta/html_head_stylesheets.html7
-rw-r--r--askbot/templates/question.html91
-rw-r--r--askbot/templates/question/answer_controls.html92
-rw-r--r--askbot/templates/question/content.html13
-rw-r--r--askbot/templates/question/javascript.html6
-rw-r--r--askbot/templates/question/question_controls.html28
-rw-r--r--askbot/templates/question/sidebar.html10
-rw-r--r--askbot/templates/question_edit.html9
-rw-r--r--askbot/templates/revisions.html2
-rw-r--r--askbot/templates/tags/form_bulk_tag_subscription.html21
-rw-r--r--askbot/templates/tags/header.html25
-rw-r--r--askbot/templates/tags/list_bulk_tag_subscription.html62
-rw-r--r--askbot/templates/user_inbox/base.html2
-rw-r--r--askbot/templates/user_inbox/messages.html13
-rw-r--r--askbot/templates/user_inbox/responses_and_flags.html4
-rw-r--r--askbot/templates/user_profile/user_email_subscriptions.html46
-rw-r--r--askbot/templates/user_profile/user_info.html2
-rw-r--r--askbot/templates/user_profile/user_stats.html5
-rw-r--r--askbot/templates/users.html8
-rw-r--r--askbot/templates/widget_base.html2
-rw-r--r--askbot/templates/widgets/ask_form.html18
-rw-r--r--askbot/templates/widgets/edit_post.html3
-rw-r--r--askbot/templates/widgets/footer.html2
-rw-r--r--askbot/templates/widgets/language_nav.html14
-rw-r--r--askbot/templates/widgets/markdown_help.html2
-rw-r--r--askbot/templates/widgets/scope_nav.html2
-rw-r--r--askbot/templates/widgets/search_bar.html25
-rw-r--r--askbot/templates/widgets/secondary_header.html45
-rw-r--r--askbot/templates/widgets/user_long_score_and_badge_summary.html7
-rw-r--r--askbot/templates/widgets/user_navigation.html8
-rw-r--r--askbot/templatetags/extra_filters_jinja.py5
-rw-r--r--askbot/templatetags/extra_tags.py10
-rw-r--r--askbot/tests/badge_tests.py3
-rw-r--r--askbot/tests/db_api_tests.py4
-rw-r--r--askbot/tests/email_alert_tests.py47
-rw-r--r--askbot/tests/email_parsing_tests.py43
-rw-r--r--askbot/tests/page_load_tests.py107
-rw-r--r--askbot/tests/post_model_tests.py14
-rw-r--r--askbot/tests/question_views_tests.py8
-rw-r--r--askbot/tests/reply_by_email_tests.py6
-rw-r--r--askbot/tests/skin_tests.py20
-rw-r--r--askbot/tests/test_data.json12264
-rw-r--r--askbot/tests/user_model_tests.py25
-rw-r--r--askbot/urls.py67
-rw-r--r--askbot/utils/console.py61
-rw-r--r--askbot/utils/forms.py13
-rw-r--r--askbot/utils/functions.py12
-rw-r--r--askbot/utils/html.py2
-rw-r--r--askbot/views/avatar_views.py14
-rw-r--r--askbot/views/commands.py195
-rw-r--r--askbot/views/meta.py66
-rw-r--r--askbot/views/readers.py67
-rw-r--r--askbot/views/users.py125
-rw-r--r--askbot/views/widgets.py59
-rw-r--r--askbot/views/writers.py135
-rw-r--r--askbot_requirements.txt3
-rw-r--r--askbot_requirements_dev.txt6
-rw-r--r--group_messaging/models.py249
-rw-r--r--group_messaging/tests.py118
-rw-r--r--setup.py5
242 files changed, 20506 insertions, 17418 deletions
diff --git a/.gitignore b/.gitignore
index 425fd569..b8629b7b 100755
--- a/.gitignore
+++ b/.gitignore
@@ -12,7 +12,9 @@ run
nbproject
settings_local.py
settings.py
+tinymce
.idea
+.coverage
*.iml
lint
env
diff --git a/askbot/__init__.py b/askbot/__init__.py
index 3107c689..cf850e33 100644
--- a/askbot/__init__.py
+++ b/askbot/__init__.py
@@ -7,13 +7,13 @@ basic actions on behalf of the forum application
import os
import platform
-VERSION = (0, 7, 43)
+VERSION = (0, 7, 48)
#keys are module names used by python imports,
#values - the package qualifier to use for pip
REQUIREMENTS = {
'akismet': 'akismet',
- 'django': 'django==1.3.1',
+ 'django': 'django>=1.3.1,<1.5',
'jinja2': 'Jinja2',
'coffin': 'Coffin>=0.3',
'south': 'South>=0.7.1',
@@ -23,10 +23,11 @@ REQUIREMENTS = {
'keyedcache': 'django-keyedcache',
'threaded_multihost': 'django-threaded-multihost',
'robots': 'django-robots',
+ 'sanction': 'sanction',
'unidecode': 'unidecode',
'django_countries': 'django-countries==1.0.5',
- 'djcelery': 'django-celery==2.2.7',
- 'djkombu': 'django-kombu==0.9.2',
+ 'djcelery': 'django-celery==3.0.11',
+ 'djkombu': 'django-kombu==0.9.4',
'followit': 'django-followit',
'recaptcha_works': 'django-recaptcha-works',
'openid': 'python-openid',
diff --git a/askbot/admin.py b/askbot/admin.py
index 8e97a89d..85c0d75c 100644
--- a/askbot/admin.py
+++ b/askbot/admin.py
@@ -4,7 +4,7 @@
To make more models accessible in the Django admin interface, add more classes subclassing ``django.contrib.admin.Model``
-Names of the classes must be like `SomeModelAdmin`, where `SomeModel` must
+Names of the classes must be like `SomeModelAdmin`, where `SomeModel` must
exactly match name of the model used in the project
"""
from django.contrib import admin
@@ -33,7 +33,7 @@ class ReputeAdmin(admin.ModelAdmin):
class ActivityAdmin(admin.ModelAdmin):
""" admin class"""
-
+
admin.site.register(models.Post)
admin.site.register(models.Tag, TagAdmin)
admin.site.register(models.Vote, VoteAdmin)
@@ -42,3 +42,4 @@ admin.site.register(models.PostRevision, PostRevisionAdmin)
admin.site.register(models.Award, AwardAdmin)
admin.site.register(models.Repute, ReputeAdmin)
admin.site.register(models.Activity, ActivityAdmin)
+admin.site.register(models.BulkTagSubscription)
diff --git a/askbot/auth.py b/askbot/auth.py
index 846445b4..2d8f5d43 100644
--- a/askbot/auth.py
+++ b/askbot/auth.py
@@ -111,7 +111,7 @@ def onUnFlaggedItem(post, user, timestamp=None):
flagged_user = post.author
flagged_user.receive_reputation(
- - askbot_settings.REP_LOSS_FOR_RECEIVING_FLAG
+ askbot_settings.REP_LOSS_FOR_RECEIVING_FLAG
)
flagged_user.save()
diff --git a/askbot/conf/__init__.py b/askbot/conf/__init__.py
index 3e80877c..fd62bc88 100644
--- a/askbot/conf/__init__.py
+++ b/askbot/conf/__init__.py
@@ -1,4 +1,5 @@
#import these to compile code and install values
+from askbot import const
import askbot
import askbot.conf.minimum_reputation
import askbot.conf.vote_rules
@@ -38,9 +39,16 @@ def should_show_sort_by_relevance():
return ('postgresql_psycopg2' in askbot.get_database_engine_name())
def get_tag_display_filter_strategy_choices():
- from askbot import const
from askbot.conf import settings as askbot_settings
if askbot_settings.SUBSCRIBED_TAG_SELECTOR_ENABLED:
return const.TAG_DISPLAY_FILTER_STRATEGY_CHOICES
else:
return const.TAG_DISPLAY_FILTER_STRATEGY_MINIMAL_CHOICES
+
+def get_tag_email_filter_strategy_choices():
+ """returns the set of choices appropriate for the configuration"""
+ from askbot.conf import settings as askbot_settings
+ if askbot_settings.SUBSCRIBED_TAG_SELECTOR_ENABLED:
+ return const.TAG_EMAIL_FILTER_ADVANCED_STRATEGY_CHOICES
+ else:
+ return const.TAG_EMAIL_FILTER_SIMPLE_STRATEGY_CHOICES
diff --git a/askbot/conf/access_control.py b/askbot/conf/access_control.py
index 5da88936..0e3dcb54 100644
--- a/askbot/conf/access_control.py
+++ b/askbot/conf/access_control.py
@@ -1,7 +1,7 @@
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import LOGIN_USERS_COMMUNICATION
from askbot.deps import livesettings
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
ACCESS_CONTROL = livesettings.ConfigurationGroup(
'ACCESS_CONTROL',
diff --git a/askbot/conf/badges.py b/askbot/conf/badges.py
index ac510055..61dd61cf 100644
--- a/askbot/conf/badges.py
+++ b/askbot/conf/badges.py
@@ -6,7 +6,7 @@ users or others
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import REP_AND_BADGES
from askbot.deps.livesettings import ConfigurationGroup, IntegerValue
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
BADGES = ConfigurationGroup(
'BADGES',
diff --git a/askbot/conf/email.py b/askbot/conf/email.py
index 9330e638..3847b18a 100644
--- a/askbot/conf/email.py
+++ b/askbot/conf/email.py
@@ -5,7 +5,7 @@ from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import LOGIN_USERS_COMMUNICATION
from askbot.deps import livesettings
from askbot import const
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from django.conf import settings as django_settings
EMAIL_SUBJECT_PREFIX = getattr(django_settings, 'EMAIL_SUBJECT_PREFIX', '')
diff --git a/askbot/conf/external_keys.py b/askbot/conf/external_keys.py
index 24a43265..3837b7ae 100644
--- a/askbot/conf/external_keys.py
+++ b/askbot/conf/external_keys.py
@@ -3,7 +3,7 @@ from askbot import const
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import EXTERNAL_SERVICES
from askbot.deps import livesettings
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from django.conf import settings as django_settings
EXTERNAL_KEYS = livesettings.ConfigurationGroup(
diff --git a/askbot/conf/flatpages.py b/askbot/conf/flatpages.py
index 543da67d..60106f6f 100644
--- a/askbot/conf/flatpages.py
+++ b/askbot/conf/flatpages.py
@@ -4,11 +4,11 @@ Q&A forum flatpages (about, etc.)
from askbot.conf.settings_wrapper import settings
from askbot.deps.livesettings import ConfigurationGroup, LongStringValue
from askbot.conf.super_groups import CONTENT_AND_UI
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
FLATPAGES = ConfigurationGroup(
'FLATPAGES',
- _('Flatpages - about, privacy policy, etc.'),
+ _('Messages and pages - about, privacy policy, etc.'),
super_group = CONTENT_AND_UI
)
@@ -38,6 +38,19 @@ settings.register(
)
)
+settings.register(
+ LongStringValue(
+ FLATPAGES,
+ 'QUESTION_INSTRUCTIONS',
+ description=_('Instructions on how to ask questions'),
+ help_text=\
+ _(
+ 'HTML is allowed. Save, then <a href="http://validator.w3.org/">'
+ 'use HTML validator</a> on the "ask" page to check your input.'
+ )
+
+ )
+)
settings.register(
LongStringValue(
@@ -59,6 +72,7 @@ settings.register(#this field is not editable manually
'CATEGORY_TREE',
description = 'Category tree',#no need to translate
default = '',#empty array of arrays in json
+ help_text=_('Do not edit this field manually!!!')
#hidden = True
)
)
diff --git a/askbot/conf/forum_data_rules.py b/askbot/conf/forum_data_rules.py
index 46a1fe08..e8a2b539 100644
--- a/askbot/conf/forum_data_rules.py
+++ b/askbot/conf/forum_data_rules.py
@@ -5,7 +5,7 @@ from askbot.conf.settings_wrapper import settings
from askbot.deps import livesettings
from askbot import const
from askbot.conf.super_groups import DATA_AND_FORMATTING
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
FORUM_DATA_RULES = livesettings.ConfigurationGroup(
'FORUM_DATA_RULES',
@@ -154,20 +154,6 @@ settings.register(
)
)
-settings.register(
- livesettings.BooleanValue(
- FORUM_DATA_RULES,
- 'ENABLE_TAG_MODERATION',
- default = False,
- description = _('Enable tag moderation'),
- help_text = _(
- '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.'
- )
- )
-)
-
TAG_SOURCE_CHOICES = (
('category-tree', _('category tree')),
('user-input', _('user input')),
diff --git a/askbot/conf/group_settings.py b/askbot/conf/group_settings.py
index 04be618f..804b5502 100644
--- a/askbot/conf/group_settings.py
+++ b/askbot/conf/group_settings.py
@@ -2,7 +2,7 @@
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import LOGIN_USERS_COMMUNICATION
from askbot.deps import livesettings
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
GROUP_SETTINGS = livesettings.ConfigurationGroup(
'GROUP_SETTINGS',
diff --git a/askbot/conf/karma_and_badges_visibility.py b/askbot/conf/karma_and_badges_visibility.py
index 4c75cb22..49d7e211 100644
--- a/askbot/conf/karma_and_badges_visibility.py
+++ b/askbot/conf/karma_and_badges_visibility.py
@@ -2,7 +2,7 @@
Settings for making the karma and badge systems visible to
the users at a different degree
"""
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from askbot.conf.settings_wrapper import settings
from askbot.deps import livesettings
from askbot.conf.super_groups import REP_AND_BADGES
diff --git a/askbot/conf/ldap.py b/askbot/conf/ldap.py
index 5c37adb1..34b6ec87 100644
--- a/askbot/conf/ldap.py
+++ b/askbot/conf/ldap.py
@@ -2,7 +2,7 @@
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import EXTERNAL_SERVICES
from askbot.deps import livesettings
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
LDAP_SETTINGS = livesettings.ConfigurationGroup(
'LDAP_SETTINGS',
@@ -10,12 +10,20 @@ LDAP_SETTINGS = livesettings.ConfigurationGroup(
super_group = EXTERNAL_SERVICES
)
+def enable_ldap_callback(current_value, new_value):
+ """enables local login form when ldap is on"""
+ if new_value == True:
+ settings.update('SIGNIN_LOCAL_ENABLED', True)
+
+ return new_value
+
settings.register(
livesettings.BooleanValue(
LDAP_SETTINGS,
'USE_LDAP_FOR_PASSWORD_LOGIN',
description=_('Use LDAP authentication for the password login'),
- defaut=False
+ defaut=False,
+ update_callback=enable_ldap_callback
)
)
diff --git a/askbot/conf/leading_sidebar.py b/askbot/conf/leading_sidebar.py
index b3909961..3fdef401 100644
--- a/askbot/conf/leading_sidebar.py
+++ b/askbot/conf/leading_sidebar.py
@@ -4,7 +4,7 @@ Sidebar 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 as _
+from django.utils.translation import ugettext_lazy as _
from askbot.conf.super_groups import CONTENT_AND_UI
LEADING_SIDEBAR = ConfigurationGroup(
diff --git a/askbot/conf/license.py b/askbot/conf/license.py
index 453213c4..d538d2cb 100644
--- a/askbot/conf/license.py
+++ b/askbot/conf/license.py
@@ -5,7 +5,7 @@ from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import CONTENT_AND_UI
from askbot.deps import livesettings
from askbot.skins import utils as skin_utils
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from django.conf import settings as django_settings
LICENSE_SETTINGS = livesettings.ConfigurationGroup(
diff --git a/askbot/conf/login_providers.py b/askbot/conf/login_providers.py
index 23f1a86d..2ee59e2a 100644
--- a/askbot/conf/login_providers.py
+++ b/askbot/conf/login_providers.py
@@ -4,7 +4,7 @@ External service key settings
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import LOGIN_USERS_COMMUNICATION
from askbot.deps import livesettings
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from django.conf import settings as django_settings
from askbot.skins import utils as skin_utils
@@ -81,6 +81,11 @@ providers = (
'Verisign',
'Yahoo',
'identi.ca',
+ 'LaunchPad'
+)
+
+DISABLED_BY_DEFAULT = (
+ 'LaunchPad'
)
need_extra_setup = ('Twitter', 'Facebook', 'LinkedIn', 'identi.ca',)
@@ -88,7 +93,7 @@ need_extra_setup = ('Twitter', 'Facebook', 'LinkedIn', 'identi.ca',)
for provider in providers:
kwargs = {
'description': _('Activate %(provider)s login') % {'provider': provider},
- 'default': True,
+ 'default': not (provider in DISABLED_BY_DEFAULT)
}
if provider in need_extra_setup:
kwargs['help_text'] = _(
diff --git a/askbot/conf/markup.py b/askbot/conf/markup.py
index 09ce4543..75a612e4 100644
--- a/askbot/conf/markup.py
+++ b/askbot/conf/markup.py
@@ -7,7 +7,7 @@ from askbot.conf.super_groups import DATA_AND_FORMATTING
from askbot.deps.livesettings import ConfigurationGroup
from askbot.deps.livesettings import BooleanValue, StringValue, LongStringValue
from askbot import const
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
import re
MARKUP = ConfigurationGroup(
diff --git a/askbot/conf/minimum_reputation.py b/askbot/conf/minimum_reputation.py
index fee880ac..799aebcc 100644
--- a/askbot/conf/minimum_reputation.py
+++ b/askbot/conf/minimum_reputation.py
@@ -5,7 +5,7 @@ a variety of actions on the askbot askbot
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import REP_AND_BADGES
from askbot.deps import livesettings
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
MIN_REP = livesettings.ConfigurationGroup(
'MIN_REP',
diff --git a/askbot/conf/moderation.py b/askbot/conf/moderation.py
index 8e77385f..b537663f 100644
--- a/askbot/conf/moderation.py
+++ b/askbot/conf/moderation.py
@@ -5,7 +5,7 @@ from askbot.conf.super_groups import DATA_AND_FORMATTING
from askbot.deps.livesettings import ConfigurationGroup
from askbot.deps.livesettings import BooleanValue
from django.core.cache import cache
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
def empty_cache_callback(old_value, new_value):
"""used to clear cache on change of certain values"""
@@ -29,3 +29,17 @@ settings.register(
update_callback = empty_cache_callback
)
)
+
+settings.register(
+ BooleanValue(
+ MODERATION,
+ 'ENABLE_TAG_MODERATION',
+ default = False,
+ description = _('Enable tag moderation'),
+ help_text = _(
+ '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.'
+ )
+ )
+)
diff --git a/askbot/conf/reputation_changes.py b/askbot/conf/reputation_changes.py
index 996d7cce..8a9e8114 100644
--- a/askbot/conf/reputation_changes.py
+++ b/askbot/conf/reputation_changes.py
@@ -5,7 +5,7 @@ users or others
"""
from askbot.conf.settings_wrapper import settings
from askbot.deps.livesettings import ConfigurationGroup, IntegerValue
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from askbot.conf.super_groups import REP_AND_BADGES
REP_CHANGES = ConfigurationGroup(
diff --git a/askbot/conf/sidebar_main.py b/askbot/conf/sidebar_main.py
index a45fdc3c..8fa4bdf0 100644
--- a/askbot/conf/sidebar_main.py
+++ b/askbot/conf/sidebar_main.py
@@ -4,7 +4,7 @@ Sidebar 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 as _
+from django.utils.translation import ugettext_lazy as _
from askbot.conf.super_groups import CONTENT_AND_UI
SIDEBAR_MAIN = ConfigurationGroup(
diff --git a/askbot/conf/sidebar_profile.py b/askbot/conf/sidebar_profile.py
index e635629a..948daa4a 100644
--- a/askbot/conf/sidebar_profile.py
+++ b/askbot/conf/sidebar_profile.py
@@ -4,7 +4,7 @@ Sidebar 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 as _
+from django.utils.translation import ugettext_lazy as _
from askbot.conf.super_groups import CONTENT_AND_UI
SIDEBAR_PROFILE = ConfigurationGroup(
diff --git a/askbot/conf/sidebar_question.py b/askbot/conf/sidebar_question.py
index bb71be7e..ffe2f783 100644
--- a/askbot/conf/sidebar_question.py
+++ b/askbot/conf/sidebar_question.py
@@ -4,7 +4,7 @@ Sidebar 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 as _
+from django.utils.translation import ugettext_lazy as _
from askbot.conf.super_groups import CONTENT_AND_UI
SIDEBAR_QUESTION = ConfigurationGroup(#shitty name - why sidebar?
'SIDEBAR_QUESTION',
@@ -29,6 +29,21 @@ settings.register(
settings.register(
values.LongStringValue(
SIDEBAR_QUESTION,
+ 'QUESTION_PAGE_ANSWER_BANNER',
+ description = _('Answers banner'),
+ default = '',
+ help_text = _(
+ '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.'
+ )
+ )
+)
+
+settings.register(
+ values.LongStringValue(
+ SIDEBAR_QUESTION,
'SIDEBAR_QUESTION_HEADER',
description = _('Custom sidebar header'),
default = '',
diff --git a/askbot/conf/site_modes.py b/askbot/conf/site_modes.py
index 8ed86f12..06cd8d13 100644
--- a/askbot/conf/site_modes.py
+++ b/askbot/conf/site_modes.py
@@ -7,7 +7,7 @@ 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 django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
LARGE_SITE_MODE_SETTINGS = {
#minimum reputation settins.
diff --git a/askbot/conf/site_settings.py b/askbot/conf/site_settings.py
index c64ea952..edd16c5c 100644
--- a/askbot/conf/site_settings.py
+++ b/askbot/conf/site_settings.py
@@ -5,7 +5,7 @@ keywords
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import CONTENT_AND_UI
from askbot.deps import livesettings
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
QA_SITE_SETTINGS = livesettings.ConfigurationGroup(
'QA_SITE_SETTINGS',
diff --git a/askbot/conf/skin_general_settings.py b/askbot/conf/skin_general_settings.py
index 323550ce..f14b3733 100644
--- a/askbot/conf/skin_general_settings.py
+++ b/askbot/conf/skin_general_settings.py
@@ -4,7 +4,7 @@ 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 as _
+from django.utils.translation import ugettext_lazy as _
from django.conf import settings as django_settings
from askbot.skins import utils as skin_utils
from askbot import const
diff --git a/askbot/conf/social_sharing.py b/askbot/conf/social_sharing.py
index 9a0f8ad4..e57dec28 100644
--- a/askbot/conf/social_sharing.py
+++ b/askbot/conf/social_sharing.py
@@ -3,18 +3,36 @@ Social sharing settings
"""
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import EXTERNAL_SERVICES
-from askbot.deps.livesettings import ConfigurationGroup, BooleanValue
-from django.utils.translation import ugettext as _
+from askbot.deps.livesettings import ConfigurationGroup, BooleanValue, StringValue
+from django.utils.translation import ugettext_lazy as _
SOCIAL_SHARING = ConfigurationGroup(
'SOCIAL_SHARING',
- _('Sharing content on social networks'),
+ _('Content sharing'),
super_group = EXTERNAL_SERVICES
)
settings.register(
BooleanValue(
SOCIAL_SHARING,
+ 'RSS_ENABLED',
+ default=True,
+ description=_('Check to enable RSS feeds')
+ )
+)
+
+settings.register(
+ StringValue(
+ SOCIAL_SHARING,
+ 'SHARING_SUFFIX_TEXT',
+ default='',
+ description=_('Hashtag or suffix to sharing messages')
+ )
+)
+
+settings.register(
+ BooleanValue(
+ SOCIAL_SHARING,
'ENABLE_SHARING_TWITTER',
default=True,
description=_('Check to enable sharing of questions on Twitter')
diff --git a/askbot/conf/spam_and_moderation.py b/askbot/conf/spam_and_moderation.py
index 23cb9596..969fbaf9 100644
--- a/askbot/conf/spam_and_moderation.py
+++ b/askbot/conf/spam_and_moderation.py
@@ -1,5 +1,5 @@
"""Settings for content moderation and spam control"""
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from askbot import const
from askbot.deps import livesettings
from askbot.conf.settings_wrapper import settings
diff --git a/askbot/conf/super_groups.py b/askbot/conf/super_groups.py
index 19b8c20a..a792e7eb 100644
--- a/askbot/conf/super_groups.py
+++ b/askbot/conf/super_groups.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from askbot.deps.livesettings import SuperGroup
from askbot.deps.livesettings import config_register_super_group
diff --git a/askbot/conf/user_settings.py b/askbot/conf/user_settings.py
index adbdd5ff..a2d8d386 100644
--- a/askbot/conf/user_settings.py
+++ b/askbot/conf/user_settings.py
@@ -6,7 +6,7 @@ from askbot.conf.super_groups import LOGIN_USERS_COMMUNICATION
from askbot.deps import livesettings
from django.conf import settings as django_settings
from askbot.skins import utils as skin_utils
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from askbot import const
USER_SETTINGS = livesettings.ConfigurationGroup(
diff --git a/askbot/conf/vote_rules.py b/askbot/conf/vote_rules.py
index 7bafe32f..6626753f 100644
--- a/askbot/conf/vote_rules.py
+++ b/askbot/conf/vote_rules.py
@@ -7,7 +7,7 @@ For example number of times a person can vote each day, etc.
from askbot.conf.settings_wrapper import settings
from askbot.conf.super_groups import REP_AND_BADGES
from askbot.deps.livesettings import ConfigurationGroup, IntegerValue
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
VOTE_RULES = ConfigurationGroup(
'VOTE_RULES',
diff --git a/askbot/const/__init__.py b/askbot/const/__init__.py
index 977cf0c5..0240d7f5 100644
--- a/askbot/const/__init__.py
+++ b/askbot/const/__init__.py
@@ -4,7 +4,7 @@ All constants could be used in other modules
For reasons that models, views can't have unicode
text in this project, all unicode text go here.
"""
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
import re
CLOSE_REASONS = (
@@ -316,11 +316,23 @@ TAG_DISPLAY_FILTER_STRATEGY_CHOICES = \
TAG_DISPLAY_FILTER_STRATEGY_MINIMAL_CHOICES + \
((INCLUDE_SUBSCRIBED, _('only subscribed tags')),)
+TAG_EMAIL_FILTER_SIMPLE_STRATEGY_CHOICES = (
+ (INCLUDE_ALL, _('email for all tags')),
+ (EXCLUDE_IGNORED, _('exclude ignored tags')),
+ (INCLUDE_INTERESTING, _('only interesting tags')),
+)
+
+TAG_EMAIL_FILTER_ADVANCED_STRATEGY_CHOICES = (
+ (INCLUDE_ALL, _('email for all tags')),
+ (EXCLUDE_IGNORED, _('exclude ignored tags')),
+ (INCLUDE_SUBSCRIBED, _('only subscribed tags')),
+)
-TAG_EMAIL_FILTER_STRATEGY_CHOICES = (
+TAG_EMAIL_FILTER_FULL_STRATEGY_CHOICES = (
(INCLUDE_ALL, _('email for all tags')),
(EXCLUDE_IGNORED, _('exclude ignored tags')),
- (INCLUDE_INTERESTING, _('only subscribed tags')),
+ (INCLUDE_INTERESTING, _('only interesting tags')),
+ (INCLUDE_SUBSCRIBED, _('only subscribed tags')),
)
NOTIFICATION_DELIVERY_SCHEDULE_CHOICES = (
diff --git a/askbot/const/message_keys.py b/askbot/const/message_keys.py
index 74fcbf7f..291381cb 100644
--- a/askbot/const/message_keys.py
+++ b/askbot/const/message_keys.py
@@ -54,7 +54,4 @@ def get_i18n_message(key):
'Please contact the forum administrator to reach a resolution.'
)
}
- if key in messages:
- return messages.get(key)
- else:
- raise KeyError(key)
+ return messages[key]
diff --git a/askbot/context.py b/askbot/context.py
index 61f833cb..fba17b5f 100644
--- a/askbot/context.py
+++ b/askbot/context.py
@@ -6,6 +6,7 @@ import sys
from django.conf import settings
from django.core.urlresolvers import reverse
from django.utils import simplejson
+from django.utils.translation import get_language
import askbot
from askbot import api
@@ -29,6 +30,8 @@ def application_settings(request):
return {}
my_settings = askbot_settings.as_dict()
my_settings['LANGUAGE_CODE'] = getattr(request, 'LANGUAGE_CODE', settings.LANGUAGE_CODE)
+ my_settings['MULTILINGUAL'] = getattr(settings, 'ASKBOT_MULTILINGUAL', False)
+ my_settings['LANGUAGES_DICT'] = dict(getattr(settings, 'LANGUAGES', []))
my_settings['ALLOWED_UPLOAD_FILE_TYPES'] = \
settings.ASKBOT_ALLOWED_UPLOAD_FILE_TYPES
my_settings['ASKBOT_URL'] = settings.ASKBOT_URL
@@ -43,6 +46,7 @@ def application_settings(request):
'ASKBOT_USE_LOCAL_FONTS',
False
)
+ my_settings['CSRF_COOKIE_NAME'] = settings.CSRF_COOKIE_NAME
my_settings['DEBUG'] = settings.DEBUG
my_settings['USING_RUNSERVER'] = 'runserver' in sys.argv
my_settings['ASKBOT_VERSION'] = askbot.get_version()
@@ -52,6 +56,7 @@ def application_settings(request):
my_settings['USE_ASKBOT_LOGIN_SYSTEM'] = 'askbot.deps.django_authopenid' \
in settings.INSTALLED_APPS
context = {
+ 'current_language_code': get_language(),
'settings': my_settings,
'skin': get_skin(request),
'moderation_items': api.get_info_on_moderation_items(request.user),
diff --git a/askbot/deployment/__init__.py b/askbot/deployment/__init__.py
index 8832cd01..5477b284 100644
--- a/askbot/deployment/__init__.py
+++ b/askbot/deployment/__init__.py
@@ -5,10 +5,13 @@ import os.path
import sys
import django
from optparse import OptionParser
-from askbot.utils import console
from askbot.deployment import messages
from askbot.deployment.messages import print_message
from askbot.deployment import path_utils
+from askbot.utils import console
+from askbot.utils.functions import generate_random_key
+
+DATABASE_ENGINE_CHOICES = ('1', '2', '3', '4')
def askbot_setup():
"""basic deployment procedure
@@ -35,6 +38,16 @@ def askbot_setup():
)
parser.add_option(
+ '-e', '--db-engine',
+ dest='database_engine',
+ action='store',
+ type='choice',
+ choices=DATABASE_ENGINE_CHOICES,
+ default=None,
+ help='Database engine, type 1 for postgresql, 2 for sqlite, 3 for mysql'
+ )
+
+ parser.add_option(
"-d", "--db-name",
dest = "database_name",
default = None,
@@ -71,82 +84,153 @@ def askbot_setup():
parser.add_option(
"--force",
- dest = "force",
- action = 'store_true',
+ dest="force",
+ action='store_true',
+ default=False,
help = "Force overwrite settings.py file"
)
try:
options = parser.parse_args()[0]
- #ask
+
+ #ask users to give missing parameters
+ #todo: make this more explicit here
if options.verbosity >= 1:
print messages.DEPLOY_PREAMBLE
directory = path_utils.clean_directory(options.dir_name)
while directory is None:
- directory = path_utils.get_install_directory(force = options.force)
+ directory = path_utils.get_install_directory(force=options.force)
+ options.dir_name = directory
+
+ if options.database_engine not in DATABASE_ENGINE_CHOICES:
+ options.database_engine = console.choice_dialog(
+ 'Please select database engine:\n1 - for postgresql, '
+ '2 - for sqlite, 3 - for mysql, 4 - oracle',
+ choices=DATABASE_ENGINE_CHOICES
+ )
+
+ options_dict = vars(options)
+ if options.force is False:
+ options_dict = collect_missing_options(options_dict)
+
+ database_engine_codes = {
+ '1': 'postgresql_psycopg2',
+ '2': 'sqlite3',
+ '3': 'mysql',
+ '4': 'oracle'
+ }
+ database_engine = database_engine_codes[options.database_engine]
+ options_dict['database_engine'] = database_engine
+
+ deploy_askbot(options_dict)
+
+ if database_engine == 'postgresql_psycopg2':
+ try:
+ import psycopg2
+ except ImportError:
+ print '\nNEXT STEPS: install python binding for postgresql'
+ print 'pip install psycopg2\n'
+ elif database_engine == 'mysql':
+ try:
+ import _mysql
+ except ImportError:
+ print '\nNEXT STEP: install python binding for mysql'
+ print 'pip install mysql-python\n'
- deploy_askbot(directory, options)
except KeyboardInterrupt:
print "\n\nAborted."
sys.exit(1)
#separated all the directory creation process to make it more useful
-
-def deploy_askbot(directory, options):
+def deploy_askbot(options):
"""function that creates django project files,
all the neccessary directories for askbot,
and the log file
"""
-
- help_file = path_utils.get_path_to_help_file()
- context = {
- 'database_name': options.database_name,
- 'database_password': options.database_password,
- 'database_user': options.database_user,
- 'domain_name': options.domain_name,
- 'local_settings': options.local_settings,
- }
- if not options.force:
- for key in context.keys():
- if context[key] == None:
- input_message = 'Please enter a value for %s:' \
- % (key.replace('_', ' '))
- new_value = raw_input(input_message)
- context[key] = new_value
-
create_new_project = False
- if os.path.exists(directory):
- if path_utils.has_existing_django_project(directory):
+ if os.path.exists(options['dir_name']):
+ if path_utils.has_existing_django_project(options['dir_name']):
create_new_project = bool(options.force)
else:
create_new_project = True
else:
create_new_project = True
- path_utils.create_path(directory)
+ path_utils.create_path(options['dir_name'])
- if django.VERSION[0] == 1 and django.VERSION[1] < 3:
+ if django.VERSION[0] > 1:
+ raise Exception(
+ 'Django framework with major version > 1 is not supported'
+ )
+
+ if django.VERSION[1] < 3:
#force people install the django-staticfiles app
- context['staticfiles_app'] = ''
+ options['staticfiles_app'] = ''
+ else:
+ options['staticfiles_app'] = "'django.contrib.staticfiles',"
+
+ if django.VERSION[1] <=3:
+ auth_context_processor = 'django.core.context_processors.auth'
else:
- context['staticfiles_app'] = "'django.contrib.staticfiles',"
+ auth_context_processor = 'django.contrib.auth.context_processors.auth'
+ options['auth_context_processor'] = auth_context_processor
+
+ verbosity = options['verbosity']
path_utils.deploy_into(
- directory,
- new_project = create_new_project,
- verbosity = options.verbosity,
- context = context
+ options['dir_name'],
+ new_project=create_new_project,
+ verbosity=verbosity,
+ context=options
)
+ help_file = path_utils.get_path_to_help_file()
+
if create_new_project:
print_message(
messages.HOW_TO_DEPLOY_NEW % {'help_file': help_file},
- options.verbosity
+ verbosity
)
else:
print_message(
messages.HOW_TO_ADD_ASKBOT_TO_DJANGO % {'help_file': help_file},
- options.verbosity
+ verbosity
)
+
+def collect_missing_options(options_dict):
+ options_dict['secret_key'] = generate_random_key()
+ if options_dict['database_engine'] == '2':#sqlite
+ while True:
+ value = console.simple_dialog(
+ 'Please enter database file name'
+ )
+ database_file_name = None
+ if os.path.isfile(value):
+ message = 'file %s exists, use it anyway?' % value
+ if console.get_yes_or_no(message) == 'yes':
+ database_file_name = value
+ elif os.path.isdir(value):
+ print '%s is a directory, choose another name' % value
+ elif value in path_utils.FILES_TO_CREATE:
+ print 'name %s cannot be used for the database name' % value
+ elif value == path_utils.LOG_DIR_NAME:
+ print 'name %s cannot be used for the database name' % value
+ else:
+ database_file_name = value
+
+ if database_file_name:
+ options_dict['database_name'] = database_file_name
+ return options_dict
+
+ else:#others
+ for key in ('database_name', 'database_user', 'database_password'):
+ if options_dict[key] is None:
+ key_name = key.replace('_', ' ')
+ value = console.simple_dialog(
+ '\nPlease enter %s' % key_name,
+ required=True
+ )
+ options_dict[key] = value
+ return options_dict
diff --git a/askbot/deployment/messages.py b/askbot/deployment/messages.py
index 44dde979..f2c512bc 100644
--- a/askbot/deployment/messages.py
+++ b/askbot/deployment/messages.py
@@ -7,19 +7,19 @@ DEPLOY_PREAMBLE = """
Deploying Askbot - Django Q&A forum application
Problems installing? -> please email admin@askbot.org
-To CANCEL - hit Ctr-C at any time"""
-
-WHERE_TO_DEPLOY = 'In which directory to deploy the forum?'
+To CANCEL - hit Ctr-C at any time
+"""
-WHERE_TO_DEPLOY_QUIT = 'Where deploy the forum (directory)? Ctrl-C to quit.'
+WHERE_TO_DEPLOY = """Enter directory path (absolute or relative) to deploy
+askbot. To choose current directory - enter "."
+>"""
CANT_INSTALL_INTO_FILE = '%(path)s is a file\ncannot install there'
SHOULD_ADD_APP_HERE = 'Directory %(path)s?\nalready has a Django ' \
+ 'project - do you want to add askbot app to that project?'
-HOW_TO_DEPLOY_NEW = 'Done. Please find further instructions in the file below:'\
- + '\n%(help_file)s'
+HOW_TO_DEPLOY_NEW = 'Done. Please find further instructions at http://askbot.org/doc/'
HOW_TO_ADD_ASKBOT_TO_DJANGO = HOW_TO_DEPLOY_NEW
diff --git a/askbot/deployment/path_utils.py b/askbot/deployment/path_utils.py
index caefa2a9..1229cf1b 100644
--- a/askbot/deployment/path_utils.py
+++ b/askbot/deployment/path_utils.py
@@ -15,6 +15,11 @@ from askbot.utils import console
from askbot.deployment.template_loader import SettingsTemplate
+FILES_TO_CREATE = ('__init__.py', 'manage.py', 'urls.py', 'django.wsgi')
+BLANK_FILES = ('__init__.py', 'manage.py')
+LOG_DIR_NAME = 'log'
+
+
def split_at_break_point(directory):
"""splits directory path into two pieces
first that exists and secon - that does not
@@ -154,8 +159,8 @@ def deploy_into(directory, new_project = False, verbosity = 1, context = None):
"""
assert(isinstance(new_project, bool))
if new_project:
- copy_files = ('__init__.py', 'manage.py', 'urls.py', 'django.wsgi')
- blank_files = ('__init__.py', 'manage.py')
+ copy_files = FILES_TO_CREATE
+ blank_files = BLANK_FILES
if verbosity >= 1:
print 'Copying files: '
for file_name in copy_files:
@@ -176,8 +181,8 @@ def deploy_into(directory, new_project = False, verbosity = 1, context = None):
print '* %s ' % file_name
shutil.copy(src, directory)
#copy log directory
- src = os.path.join(SOURCE_DIR, 'setup_templates', 'log')
- log_dir = os.path.join(directory, 'log')
+ src = os.path.join(SOURCE_DIR, 'setup_templates', LOG_DIR_NAME)
+ log_dir = os.path.join(directory, LOG_DIR_NAME)
create_path(log_dir)
touch(os.path.join(log_dir, 'askbot.log'))
@@ -252,8 +257,12 @@ def get_install_directory(force = False):
using a directory with an existing django project.
"""
from askbot.deployment import messages
- where_to_deploy_msg = messages.WHERE_TO_DEPLOY_QUIT
+ where_to_deploy_msg = messages.WHERE_TO_DEPLOY
directory = raw_input(where_to_deploy_msg + ' ')
+
+ if directory.strip() == '':
+ return None
+
directory = clean_directory(directory)
if directory is None:
diff --git a/askbot/deps/django_authopenid/backends.py b/askbot/deps/django_authopenid/backends.py
index 1e8626ac..f719e811 100644
--- a/askbot/deps/django_authopenid/backends.py
+++ b/askbot/deps/django_authopenid/backends.py
@@ -145,7 +145,7 @@ class AuthBackend(object):
return None
elif method == 'oauth':
- if login_providers[provider_name]['type'] == 'oauth':
+ if login_providers[provider_name]['type'] in ('oauth', 'oauth2'):
try:
assoc = UserAssociation.objects.get(
openid_url = oauth_user_id,
diff --git a/askbot/deps/django_authopenid/forms.py b/askbot/deps/django_authopenid/forms.py
index fbc5c6ff..332496b5 100644
--- a/askbot/deps/django_authopenid/forms.py
+++ b/askbot/deps/django_authopenid/forms.py
@@ -33,12 +33,14 @@ import logging
from django import forms
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
-from django.conf import settings
+from django.utils.translation import ugettext_lazy
+from django.conf import settings as django_settings
from askbot.conf import settings as askbot_settings
from askbot import const as askbot_const
from django.utils.safestring import mark_safe
from recaptcha_works.fields import RecaptchaField
from askbot.utils.forms import NextUrlField, UserNameField, UserEmailField, SetPasswordForm
+from askbot.utils.loading import load_module
# needed for some linux distributions like debian
try:
@@ -105,7 +107,7 @@ class OpenidSigninForm(forms.Form):
if 'openid_url' in self.cleaned_data:
openid_url = self.cleaned_data['openid_url']
if xri.identifierScheme(openid_url) == 'XRI' and getattr(
- settings, 'OPENID_DISALLOW_INAMES', False
+ django_settings, 'OPENID_DISALLOW_INAMES', False
):
raise forms.ValidationError(_('i-names are not supported'))
return self.cleaned_data['openid_url']
@@ -211,7 +213,8 @@ class LoginForm(forms.Form):
self.cleaned_data['login_type'] = 'openid'
elif provider_type == 'oauth':
self.cleaned_data['login_type'] = 'oauth'
- pass
+ elif provider_type == 'oauth2':
+ self.cleaned_data['login_type'] = 'oauth2'
elif provider_type == 'facebook':
self.cleaned_data['login_type'] = 'facebook'
#self.do_clean_oauth_fields()
@@ -332,7 +335,7 @@ class SafeClassicRegisterForm(ClassicRegisterForm):
class ChangePasswordForm(SetPasswordForm):
""" change password form """
oldpw = forms.CharField(widget=forms.PasswordInput(attrs={'class':'required'}),
- label=mark_safe(_('Current password')))
+ label=mark_safe(ugettext_lazy('Current password')))
def __init__(self, data=None, user=None, *args, **kwargs):
if user is None:
@@ -432,7 +435,12 @@ class DeleteForm(forms.Form):
class EmailPasswordForm(forms.Form):
""" send new password form """
- username = UserNameField(skip_clean=True,label=mark_safe(_('Your user name (<i>required</i>)')))
+ username = UserNameField(
+ skip_clean=True,
+ label=mark_safe(
+ ugettext_lazy('Your user name (<i>required</i>)')
+ )
+ )
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
initial=None):
@@ -449,3 +457,13 @@ class EmailPasswordForm(forms.Form):
except:
raise forms.ValidationError(_("sorry, there is no such user name"))
return self.cleaned_data['username']
+
+def get_registration_form_class():
+ """returns class for the user registration form
+ user has a chance to specify the form via setting `REGISTRATION_FORM`
+ """
+ custom_class = getattr(django_settings, 'REGISTRATION_FORM', None)
+ if custom_class:
+ return load_module(custom_class)
+ else:
+ return OpenidRegisterForm
diff --git a/askbot/deps/django_authopenid/urls.py b/askbot/deps/django_authopenid/urls.py
index 1b7d0b01..f9098995 100644
--- a/askbot/deps/django_authopenid/urls.py
+++ b/askbot/deps/django_authopenid/urls.py
@@ -1,6 +1,11 @@
# -*- coding: utf-8 -*-
+from django.conf import settings as django_settings
from django.conf.urls.defaults import patterns, url
-from django.utils.translation import ugettext as _
+
+if django_settings.ASKBOT_TRANSLATE_URL == True:
+ from django.utils.translation import ugettext as _
+else:
+ _ = lambda val: val
urlpatterns = patterns('askbot.deps.django_authopenid.views',
# yadis rdf
@@ -19,6 +24,11 @@ urlpatterns = patterns('askbot.deps.django_authopenid.views',
'complete_oauth_signin',
name='user_complete_oauth_signin'
),
+ url(
+ r'^signin/complete-oauth2/',
+ 'complete_oauth2_signin',
+ name='user_complete_oauth2_signin'
+ ),
url(r'^%s$' % _('register/'), 'register', name='user_register'),
url(
r'^%s$' % _('signup/'),
diff --git a/askbot/deps/django_authopenid/util.py b/askbot/deps/django_authopenid/util.py
index 8d37b9e5..7e78da16 100644
--- a/askbot/deps/django_authopenid/util.py
+++ b/askbot/deps/django_authopenid/util.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import cgi
import urllib
-import urllib2
+import urlparse
import functools
import re
import random
@@ -9,10 +9,11 @@ from openid.store.interface import OpenIDStore
from openid.association import Association as OIDAssociation
from openid.extensions import sreg
from openid import store as openid_store
-import oauth2 as oauth
+import oauth2 as oauth # OAuth1 protocol
from django.db.models.query import Q
from django.conf import settings
+from django.core.urlresolvers import reverse
from django.utils import simplejson
from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext as _
@@ -386,12 +387,23 @@ def get_enabled_major_login_providers():
'password_changeable': True
}
+ def get_facebook_user_id(client):
+ """returns facebook user id given the access token"""
+ profile = client.request('me')
+ return profile['id']
+
if askbot_settings.FACEBOOK_KEY and askbot_settings.FACEBOOK_SECRET:
data['facebook'] = {
'name': 'facebook',
'display_name': 'Facebook',
- 'type': 'facebook',
+ 'type': 'oauth2',
+ 'auth_endpoint': 'https://www.facebook.com/dialog/oauth/',
+ 'token_endpoint': 'https://graph.facebook.com/oauth/access_token',
+ 'resource_endpoint': 'https://graph.facebook.com/',
'icon_media_path': '/jquery-openid/images/facebook.gif',
+ 'get_user_id_function': get_facebook_user_id,
+ 'response_parser': lambda data: dict(urlparse.parse_qsl(data))
+
}
if askbot_settings.TWITTER_KEY and askbot_settings.TWITTER_SECRET:
data['twitter'] = {
@@ -481,6 +493,14 @@ def get_enabled_major_login_providers():
'icon_media_path': '/jquery-openid/images/aol.gif',
'openid_endpoint': 'http://openid.aol.com/%(username)s'
}
+ data['launchpad'] = {
+ 'name': 'launchpad',
+ 'display_name': 'LaunchPad',
+ 'type': 'openid-direct',
+ 'icon_media_path': '/jquery-openid/images/launchpad.gif',
+ 'tooltip_text': _('Sign in with LaunchPad'),
+ 'openid_endpoint': 'https://login.launchpad.net/'
+ }
data['openid'] = {
'name': 'openid',
'display_name': 'OpenID',
@@ -666,8 +686,11 @@ def get_oauth_parameters(provider_name):
elif provider_name == 'identi.ca':
consumer_key = askbot_settings.IDENTICA_KEY
consumer_secret = askbot_settings.IDENTICA_SECRET
+ elif provider_name == 'facebook':
+ consumer_key = askbot_settings.FACEBOOK_KEY
+ consumer_secret = askbot_settings.FACEBOOK_SECRET
else:
- raise ValueError('sorry, only linkedin and twitter oauth for now')
+ raise ValueError('unexpected oauth provider %s' % provider_name)
data['consumer_key'] = consumer_key
data['consumer_secret'] = consumer_secret
@@ -781,62 +804,21 @@ class OAuthConnection(object):
return auth_url
-class FacebookError(Exception):
- """Raised when there's something not right
- with FacebookConnect
- """
- pass
+def get_oauth2_starter_url(provider_name, csrf_token):
+ """returns redirect url for the oauth2 protocol for a given provider"""
+ from sanction.client import Client
-def urlsafe_b64decode(input):
- length = len(input)
- return base64.urlsafe_b64decode(
- input.ljust(length + length % 4, '=')
+ providers = get_enabled_login_providers()
+ params = providers[provider_name]
+ client_id = getattr(askbot_settings, provider_name.upper() + '_KEY')
+ redirect_uri = askbot_settings.APP_URL + reverse('user_complete_oauth2_signin')
+ client = Client(
+ auth_endpoint=params['auth_endpoint'],
+ client_id=client_id,
+ redirect_uri=redirect_uri
)
+ return client.auth_uri(state=csrf_token)
-def parse_signed_facebook_request(signed_request, secret):
- """
- Parse signed_request given by Facebook (usually via POST),
- decrypt with app secret.
-
- Arguments:
- signed_request -- Facebook's signed request given through POST
- secret -- Application's app_secret required to decrpyt signed_request
-
- slightly edited copy from https://gist.github.com/1190267
- """
-
- if "." in signed_request:
- esig, payload = signed_request.split(".")
- else:
- return {}
-
- sig = urlsafe_b64decode(str(esig))
- data = simplejson.loads(urlsafe_b64decode(str(payload)))
-
- if not isinstance(data, dict):
- raise ValueError("Pyload is not a json string!")
- return {}
-
- if data["algorithm"].upper() == "HMAC-SHA256":
- if hmac.new(str(secret), str(payload), hashlib.sha256).digest() == sig:
- return data
- else:
- raise ValueError("Not HMAC-SHA256 encrypted!")
-
- return {}
-
-def get_facebook_user_id(request):
- try:
- key = askbot_settings.FACEBOOK_KEY
- fb_cookie = request.COOKIES['fbsr_%s' % key]
- if not fb_cookie:
- raise ValueError('cannot access facebook cookie')
-
- secret = askbot_settings.FACEBOOK_SECRET
- response = parse_signed_facebook_request(fb_cookie, secret)
- return response['user_id']
- except Exception, e:
- raise FacebookError(e)
def ldap_check_password(username, password):
import ldap
@@ -848,7 +830,3 @@ def ldap_check_password(username, password):
except ldap.LDAPError, e:
logging.critical(unicode(e))
return False
-
-def generate_random_key():
- random.seed()
- return '%032x' % random.getrandbits(128)
diff --git a/askbot/deps/django_authopenid/views.py b/askbot/deps/django_authopenid/views.py
index 05e0cdc5..8f33e8c0 100644
--- a/askbot/deps/django_authopenid/views.py
+++ b/askbot/deps/django_authopenid/views.py
@@ -33,6 +33,7 @@
import datetime
from django.http import HttpResponseRedirect, get_host, Http404
from django.http import HttpResponse
+from django.http import HttpResponseBadRequest
from django.template import RequestContext, Context
from django.conf import settings as django_settings
from askbot.conf import settings as askbot_settings
@@ -41,17 +42,20 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate
from django.core.urlresolvers import reverse
from django.forms.util import ErrorList
+from django.shortcuts import render
+from django.template.loader import get_template
from django.views.decorators import csrf
from django.utils.encoding import smart_unicode
+from askbot.utils.functions import generate_random_key
from django.utils.html import escape
from django.utils.translation import ugettext as _
from django.utils.safestring import mark_safe
from askbot.mail import send_mail
from recaptcha_works.decorators import fix_recaptcha_remote_ip
-from askbot.skins.loaders import render_into_skin, get_template
from askbot.deps.django_authopenid.ldap_auth import ldap_create_user
from askbot.deps.django_authopenid.ldap_auth import ldap_authenticate
from askbot.utils.loading import load_module
+from sanction.client import Client as OAuth2Client
from urlparse import urlparse
from openid.consumer.consumer import Consumer, \
@@ -169,7 +173,7 @@ def logout_page(request):
'page_class': 'meta',
'have_federated_login_methods': util.have_enabled_federated_login_methods()
}
- return render_into_skin('authopenid/logout.html', data, request)
+ return render(request, 'authopenid/logout.html', data)
def get_url_host(request):
if request.is_secure():
@@ -263,6 +267,72 @@ def not_authenticated(func):
return func(request, *args, **kwargs)
return decorated
+def complete_oauth2_signin(request):
+ if 'next_url' in request.session:
+ next_url = request.session['next_url']
+ del request.session['next_url']
+ else:
+ next_url = reverse('index')
+
+ if 'error' in request.GET:
+ return HttpResponseRedirect(reverse('index'))
+
+ csrf_token = request.GET.get('state', None)
+ if csrf_token is None or csrf_token != request.session.pop('oauth2_csrf_token'):
+ return HttpResponseBadRequest()
+
+ providers = util.get_enabled_login_providers()
+ provider_name = request.session.pop('provider_name')
+ params = providers[provider_name]
+ assert(params['type'] == 'oauth2')
+
+ client_id = getattr(
+ askbot_settings,
+ provider_name.upper() + '_KEY'
+ )
+
+ client_secret = getattr(
+ askbot_settings,
+ provider_name.upper() + '_SECRET'
+ )
+
+ client = OAuth2Client(
+ token_endpoint=params['token_endpoint'],
+ resource_endpoint=params['resource_endpoint'],
+ redirect_uri=askbot_settings.APP_URL + reverse('user_complete_oauth2_signin'),
+ client_id=client_id,
+ client_secret=client_secret
+ )
+
+ client.request_token(
+ code=request.GET['code'],
+ parser=params['response_parser']
+ )
+
+ #todo: possibly set additional parameters here
+ user_id = params['get_user_id_function'](client)
+
+ user = authenticate(
+ oauth_user_id = user_id,
+ provider_name = provider_name,
+ method = 'oauth'
+ )
+
+ logging.debug('finalizing oauth signin')
+
+ request.session['email'] = ''#todo: pull from profile
+ request.session['username'] = ''#todo: pull from profile
+
+ return finalize_generic_signin(
+ request = request,
+ user = user,
+ user_identifier = user_id,
+ login_provider_name = provider_name,
+ redirect_url = next_url
+ )
+
+
+
def complete_oauth_signin(request):
if 'next_url' in request.session:
next_url = request.session['next_url']
@@ -478,12 +548,10 @@ def signin(request, template_name='authopenid/signin.html'):
elif login_form.cleaned_data['login_type'] == 'oauth':
try:
#this url may need to have "next" piggibacked onto
- callback_url = reverse('user_complete_oauth_signin')
-
connection = util.OAuthConnection(
- provider_name,
- callback_url = callback_url
- )
+ provider_name,
+ callback_url=reverse('user_complete_oauth_signin')
+ )
connection.start()
@@ -502,37 +570,28 @@ def signin(request, template_name='authopenid/signin.html'):
) % {'provider': provider_name}
request.user.message_set.create(message = msg)
- elif login_form.cleaned_data['login_type'] == 'facebook':
- #have to redirect for consistency
- #there is a requirement that 'complete_signin'
+ elif login_form.cleaned_data['login_type'] == 'oauth2':
try:
- #this call may raise FacebookError
- user_id = util.get_facebook_user_id(request)
-
- user = authenticate(
- method = 'facebook',
- facebook_user_id = user_id
- )
-
- return finalize_generic_signin(
- request = request,
- user = user,
- user_identifier = user_id,
- login_provider_name = provider_name,
- redirect_url = next_url
- )
-
- except util.FacebookError, e:
+ csrf_token = generate_random_key(length=32)
+ redirect_url = util.get_oauth2_starter_url(provider_name, csrf_token)
+ request.session['oauth2_csrf_token'] = csrf_token
+ request.session['provider_name'] = provider_name
+ return HttpResponseRedirect(redirect_url)
+ except util.OAuthError, e:
logging.critical(unicode(e))
msg = _('Unfortunately, there was some problem when '
'connecting to %(provider)s, please try again '
'or use another provider'
- ) % {'provider': 'Facebook'}
+ ) % {'provider': provider_name}
request.user.message_set.create(message = msg)
elif login_form.cleaned_data['login_type'] == 'wordpress_site':
#here wordpress_site means for a self hosted wordpress blog not a wordpress.com blog
- wp = Client(askbot_settings.WORDPRESS_SITE_URL, login_form.cleaned_data['username'], login_form.cleaned_data['password'])
+ wp = Client(
+ askbot_settings.WORDPRESS_SITE_URL,
+ login_form.cleaned_data['username'],
+ login_form.cleaned_data['password']
+ )
try:
wp_user = wp.call(GetUserInfo())
custom_wp_openid_url = '%s?user_id=%s' % (wp.url, wp_user.user_id)
@@ -547,7 +606,7 @@ def signin(request, template_name='authopenid/signin.html'):
user_identifier = custom_wp_openid_url,
login_provider_name = provider_name,
redirect_url = next_url
- )
+ )
except WpFault, e:
logging.critical(unicode(e))
msg = _('The login password combination was not correct')
@@ -721,7 +780,7 @@ def show_signin_view(
data['major_login_providers'] = major_login_providers.values()
data['minor_login_providers'] = minor_login_providers.values()
- return render_into_skin(template_name, data, request)
+ return render(request, template_name, data)
@login_required
def delete_login_method(request):
@@ -901,7 +960,8 @@ def register(request, login_provider_name=None, user_identifier=None):
email = request.session.get('email', '')
logging.debug('request method is %s' % request.method)
- register_form = forms.OpenidRegisterForm(
+ form_class = forms.get_registration_form_class()
+ register_form = form_class(
initial={
'next': next_url,
'username': request.session.get('username', ''),
@@ -929,9 +989,10 @@ def register(request, login_provider_name=None, user_identifier=None):
login_provider_name = request.session['login_provider_name']
logging.debug('trying to create new account associated with openid')
- register_form = forms.OpenidRegisterForm(request.POST)
+ form_class = forms.get_registration_form_class()
+ register_form = form_class(request.POST)
if not register_form.is_valid():
- logging.debug('OpenidRegisterForm is INVALID')
+ logging.debug('registration form is INVALID')
else:
username = register_form.cleaned_data['username']
email = register_form.cleaned_data['email']
@@ -963,7 +1024,7 @@ def register(request, login_provider_name=None, user_identifier=None):
else:
request.session['username'] = username
request.session['email'] = email
- key = util.generate_random_key()
+ key = generate_random_key()
email = request.session['email']
send_email_key(email, key, handler_url_name='verify_email_and_register')
request.session['validation_code'] = key
@@ -993,7 +1054,7 @@ def register(request, login_provider_name=None, user_identifier=None):
'login_type':'openid',
'gravatar_faq_url':reverse('faq') + '#gravatar',
}
- return render_into_skin('authopenid/complete.html', data, request)
+ return render(request, 'authopenid/complete.html', data)
def signin_failure(request, message):
"""
@@ -1052,7 +1113,7 @@ def verify_email_and_register(request):
return HttpResponseRedirect(reverse('index'))
else:
data = {'page_class': 'validate-email-page'}
- return render_into_skin('authopenid/verify_email.html', data, request)
+ return render(request, 'authopenid/verify_email.html', data)
@not_authenticated
@decorators.valid_password_login_provider_required
@@ -1106,7 +1167,7 @@ def signup_with_password(request):
request.session['email'] = email
request.session['password'] = password
#todo: generate a key and save it in the session
- key = util.generate_random_key()
+ key = generate_random_key()
email = request.session['email']
send_email_key(email, key, handler_url_name='verify_email_and_register')
request.session['validation_code'] = key
@@ -1138,10 +1199,10 @@ def signup_with_password(request):
'minor_login_providers': minor_login_providers.values(),
'login_form': login_form
}
- return render_into_skin(
+ return render(
+ request,
'authopenid/signup_with_password.html',
- context_data,
- request
+ context_data
)
#what if request is not posted?
@@ -1201,11 +1262,11 @@ def send_email_key(email, key, handler_url_name='user_account_recover'):
'?validation_code=' + key
}
template = get_template('authopenid/email_validation.html')
- message = template.render(data)
+ message = template.render(data)#todo: inject language preference
send_mail(subject, message, django_settings.DEFAULT_FROM_EMAIL, [email])
def send_user_new_email_key(user):
- user.email_key = util.generate_random_key()
+ user.email_key = generate_random_key()
user.save()
send_email_key(user.email, user.email_key)
@@ -1273,4 +1334,4 @@ def validation_email_sent(request):
'change_email_url': reverse('user_changeemail'),
'action_type': 'validate'
}
- return render_into_skin('authopenid/changeemail.html', data, request)
+ return render(request, 'authopenid/changeemail.html', data)
diff --git a/group_messaging/__init__.py b/askbot/deps/group_messaging/__init__.py
index 642ad5c8..ed3d73ff 100644
--- a/group_messaging/__init__.py
+++ b/askbot/deps/group_messaging/__init__.py
@@ -11,4 +11,7 @@ the group should be named `'_personal_1'`.
Only one person must be a member of a personal group and
each user must have such group.
+
+TODO: decouple this application
+first step is to package send_mail separately
"""
diff --git a/group_messaging/migrations/0001_initial.py b/askbot/deps/group_messaging/migrations/0001_initial.py
index 7d907dc1..7d907dc1 100644
--- a/group_messaging/migrations/0001_initial.py
+++ b/askbot/deps/group_messaging/migrations/0001_initial.py
diff --git a/group_messaging/migrations/0002_auto__add_lastvisittime__add_unique_lastvisittime_user_message__add_fi.py b/askbot/deps/group_messaging/migrations/0002_auto__add_lastvisittime__add_unique_lastvisittime_user_message__add_fi.py
index 5e92ef2b..5e92ef2b 100644
--- a/group_messaging/migrations/0002_auto__add_lastvisittime__add_unique_lastvisittime_user_message__add_fi.py
+++ b/askbot/deps/group_messaging/migrations/0002_auto__add_lastvisittime__add_unique_lastvisittime_user_message__add_fi.py
diff --git a/group_messaging/migrations/__init__.py b/askbot/deps/group_messaging/migrations/__init__.py
index e69de29b..e69de29b 100644
--- a/group_messaging/migrations/__init__.py
+++ b/askbot/deps/group_messaging/migrations/__init__.py
diff --git a/askbot/deps/group_messaging/models.py b/askbot/deps/group_messaging/models.py
new file mode 100644
index 00000000..4442170f
--- /dev/null
+++ b/askbot/deps/group_messaging/models.py
@@ -0,0 +1,438 @@
+"""models for the ``group_messaging`` app
+"""
+import copy
+import datetime
+import urllib
+from askbot.mail import send_mail #todo: remove dependency?
+from django.template.loader import get_template
+from django.db import models
+from django.db.models import signals
+from django.conf import settings as django_settings
+from django.contrib.auth.models import Group
+from django.contrib.auth.models import User
+from django.contrib.sites.models import Site
+from django.utils.importlib import import_module
+from django.utils.translation import ugettext as _
+
+MAX_HEADLINE_LENGTH = 80
+MAX_SENDERS_INFO_LENGTH = 64
+MAX_SUBJECT_LINE_LENGTH = 30
+
+#dummy parse message function
+parse_message = lambda v: v
+
+GROUP_NAME_TPL = '_personal_%s'
+
+def get_recipient_names(recipient_groups):
+ """returns list of user names if groups are private,
+ or group names, otherwise"""
+ names = set()
+ for group in recipient_groups:
+ if group.name.startswith('_personal_'):
+ names.add(group.user_set.all()[0].username)
+ else:
+ names.add(group.name)
+ return names
+
+
+def get_personal_group_by_user_id(user_id):
+ return Group.objects.get(name=GROUP_NAME_TPL % user_id)
+
+
+def get_personal_groups_for_users(users):
+ """for a given list of users return their personal groups"""
+ group_names = [(GROUP_NAME_TPL % user.id) for user in users]
+ return Group.objects.filter(name__in=group_names)
+
+
+def get_personal_group(user):
+ """returns personal group for the user"""
+ return get_personal_group_by_user_id(user.id)
+
+
+def create_personal_group(user):
+ """creates a personal group for the user"""
+ group = Group(name=GROUP_NAME_TPL % user.id)
+ group.save()
+ return group
+
+
+class LastVisitTime(models.Model):
+ """just remembers when a user has
+ last visited a given thread
+ """
+ user = models.ForeignKey(User)
+ message = models.ForeignKey('Message')
+ at = models.DateTimeField(auto_now_add=True)
+
+ class Meta:
+ unique_together = ('user', 'message')
+
+
+class SenderListManager(models.Manager):
+ """model manager for the :class:`SenderList`"""
+
+ def get_senders_for_user(self, user=None):
+ """returns query set of :class:`User`"""
+ user_groups = user.groups.all()
+ lists = self.filter(recipient__in=user_groups)
+ user_ids = lists.values_list(
+ 'senders__id', flat=True
+ ).distinct()
+ return User.objects.filter(id__in=user_ids)
+
+class SenderList(models.Model):
+ """a model to store denormalized data
+ about who sends messages to any given person
+ sender list is populated automatically
+ as new messages are created
+ """
+ recipient = models.ForeignKey(Group, unique=True)
+ senders = models.ManyToManyField(User)
+ objects = SenderListManager()
+
+
+class MessageMemo(models.Model):
+ """A bridge between message recipients and messages
+ these records are only created when user sees a message.
+ The idea is that using groups as recipients, we can send
+ messages to massive numbers of users, without cluttering
+ the database.
+
+ Instead we'll be creating a "seen" message after user
+ reads the message.
+ """
+ SEEN = 0
+ ARCHIVED = 1
+ STATUS_CHOICES = (
+ (SEEN, 'seen'),
+ (ARCHIVED, 'archived')
+ )
+ user = models.ForeignKey(User)
+ message = models.ForeignKey('Message', related_name='memos')
+ status = models.SmallIntegerField(
+ choices=STATUS_CHOICES, default=SEEN
+ )
+
+ class Meta:
+ unique_together = ('user', 'message')
+
+
+class MessageManager(models.Manager):
+ """model manager for the :class:`Message`"""
+
+ def get_sent_threads(self, sender=None):
+ """returns list of threads for the "sent" mailbox
+ this function does not deal with deleted=True
+ """
+ responses = self.filter(sender=sender)
+ responded_to = models.Q(descendants__in=responses, root=None)
+ seen_filter = models.Q(
+ memos__status=MessageMemo.SEEN,
+ memos__user=sender
+ )
+ seen_responses = self.filter(responded_to & seen_filter)
+ unseen_responses = self.filter(responded_to & ~models.Q(memos__user=sender))
+ return (
+ self.get_threads(sender=sender) \
+ | seen_responses.distinct() \
+ | unseen_responses.distinct()
+ ).distinct()
+
+ def get_threads(self, recipient=None, sender=None, deleted=False):
+ """returns query set of first messages in conversations,
+ based on recipient, sender and whether to
+ load deleted messages or not"""
+
+ if sender and sender == recipient:
+ raise ValueError('sender cannot be the same as recipient')
+
+ filter_kwargs = {
+ 'root': None,
+ 'message_type': Message.STORED
+ }
+ if recipient:
+ filter_kwargs['recipients__in'] = recipient.groups.all()
+ else:
+ #todo: possibly a confusing hack - for this branch -
+ #sender but no recipient in the args - we need "sent" origin threads
+ recipient = sender
+
+ user_thread_filter = models.Q(**filter_kwargs)
+
+ filter = user_thread_filter
+ if sender:
+ filter = filter & models.Q(sender=sender)
+
+ if deleted:
+ deleted_filter = models.Q(
+ memos__status=MessageMemo.ARCHIVED,
+ memos__user=recipient
+ )
+ return self.filter(filter & deleted_filter)
+ else:
+ #rather a tricky query (may need to change the idea to get rid of this)
+ #select threads that have a memo for the user, but the memo is not ARCHIVED
+ #in addition, select threads that have zero memos for the user
+ marked_as_non_deleted_filter = models.Q(
+ memos__status=MessageMemo.SEEN,
+ memos__user=recipient
+ )
+ #part1 - marked as non-archived
+ part1 = self.filter(filter & marked_as_non_deleted_filter)
+ #part2 - messages for the user without an attached memo
+ part2 = self.filter(filter & ~models.Q(memos__user=recipient))
+ return (part1 | part2).distinct()
+
+ def create(self, **kwargs):
+ """creates a message"""
+ root = kwargs.get('root', None)
+ if root is None:
+ parent = kwargs.get('parent', None)
+ if parent:
+ if parent.root:
+ root = parent.root
+ else:
+ root = parent
+ kwargs['root'] = root
+
+ headline = kwargs.get('headline', kwargs['text'])
+ kwargs['headline'] = headline[:MAX_HEADLINE_LENGTH]
+ kwargs['html'] = parse_message(kwargs['text'])
+
+ message = super(MessageManager, self).create(**kwargs)
+ #creator of message saw it by definition
+ #crate a "seen" memo for the sender, because we
+ #don't want to inform the user about his/her own post
+ sender = kwargs['sender']
+ MessageMemo.objects.create(
+ message=message, user=sender, status=MessageMemo.SEEN
+ )
+ return message
+
+ def create_thread(self, sender=None, recipients=None, text=None):
+ """creates a stored message and adds recipients"""
+ message = self.create(
+ message_type=Message.STORED,
+ sender=sender,
+ senders_info=sender.username,
+ text=text,
+ )
+ now = datetime.datetime.now()
+ LastVisitTime.objects.create(message=message, user=sender, at=now)
+ names = get_recipient_names(recipients)
+ message.add_recipient_names_to_senders_info(recipients)
+ message.save()
+ message.add_recipients(recipients)
+ message.send_email_alert()
+ return message
+
+ def create_response(self, sender=None, text=None, parent=None):
+ message = self.create(
+ parent=parent,
+ message_type=Message.STORED,
+ sender=sender,
+ text=text,
+ )
+ #recipients are parent's recipients + sender
+ #creator of response gets memo in the "read" status
+ recipients = set(parent.recipients.all())
+
+ if sender != parent.sender:
+ senders_group = get_personal_group(parent.sender)
+ parent.add_recipients([senders_group])
+ recipients.add(senders_group)
+
+ message.add_recipients(recipients)
+ #add author of the parent as a recipient to parent
+ #update headline
+ message.root.headline = text[:MAX_HEADLINE_LENGTH]
+ #mark last active timestamp for the root message
+ message.root.last_active_at = datetime.datetime.now()
+ #update senders info - stuff that is shown in the thread heading
+ message.root.update_senders_info()
+ #unarchive the thread for all recipients
+ message.root.unarchive()
+ message.send_email_alert()
+ return message
+
+
+class Message(models.Model):
+ """the message model allowing users to send
+ messages to other users and groups, via
+ personal groups.
+ """
+ STORED = 0
+ TEMPORARY = 1
+ ONE_TIME = 2
+ MESSAGE_TYPE_CHOICES = (
+ (STORED, 'email-like message, stored in the inbox'),
+ (ONE_TIME, 'will be shown just once'),
+ (TEMPORARY, 'will be shown until certain time')
+ )
+
+ message_type = models.SmallIntegerField(
+ choices=MESSAGE_TYPE_CHOICES,
+ default=STORED,
+ )
+
+ sender = models.ForeignKey(User, related_name='sent_messages')
+
+ senders_info = models.CharField(
+ max_length=MAX_SENDERS_INFO_LENGTH,
+ default=''
+ )#comma-separated list of a few names
+
+ recipients = models.ManyToManyField(Group)
+
+ root = models.ForeignKey(
+ 'self', null=True,
+ blank=True, related_name='descendants'
+ )
+
+ parent = models.ForeignKey(
+ 'self', null=True,
+ blank=True, related_name='children'
+ )
+
+ headline = models.CharField(max_length=MAX_HEADLINE_LENGTH)
+
+ text = models.TextField(
+ null=True, blank=True,
+ help_text='source text for the message, e.g. in markdown format'
+ )
+
+ html = models.TextField(
+ null=True, blank=True,
+ help_text='rendered html of the message'
+ )
+
+ sent_at = models.DateTimeField(auto_now_add=True)
+ last_active_at = models.DateTimeField(auto_now_add=True)
+ active_until = models.DateTimeField(blank=True, null=True)
+
+ objects = MessageManager()
+
+ def add_recipient_names_to_senders_info(self, recipient_groups):
+ names = get_recipient_names(recipient_groups)
+ old_names = set(self.senders_info.split(','))
+ names |= old_names
+ self.senders_info = ','.join(names)
+
+ def add_recipients(self, recipients):
+ """adds recipients to the message
+ and updates the sender lists for all recipients
+ todo: sender lists may be updated in a lazy way - per user
+ """
+ self.recipients.add(*recipients)
+ for recipient in recipients:
+ sender_list, created = SenderList.objects.get_or_create(recipient=recipient)
+ sender_list.senders.add(self.sender)
+
+ def get_absolute_url(self, user=None):
+ """returns absolute url to the thread"""
+ assert(user != None)
+ settings = django_settings.GROUP_MESSAGING
+ func_path = settings['BASE_URL_GETTER_FUNCTION']
+ path_bits = func_path.split('.')
+ url_getter = getattr(
+ import_module('.'.join(path_bits[:-1])),
+ path_bits[-1]
+ )
+ params = copy.copy(settings['BASE_URL_PARAMS'])
+ params['thread_id'] = self.id
+ url = url_getter(user) + '?' + urllib.urlencode(params)
+ #if include_domain_name: #don't need this b/c
+ # site = Site.objects.get_current()
+ # url = 'http://' + site.domain + url
+ return url
+
+ def get_email_subject_line(self):
+ """forms subject line based on the root message
+ and prepends 'Re': if message is non-root
+ """
+ subject = self.get_root_message().text[:MAX_SUBJECT_LINE_LENGTH]
+ if self.root:
+ subject = _('Re: ') + subject
+ return subject
+
+ def get_root_message(self):
+ """returns root message or self
+ if current message is root
+ """
+ return self.root or self
+
+ def get_recipients_users(self):
+ """returns query set of users"""
+ groups = self.recipients.all()
+ return User.objects.filter(
+ groups__in=groups
+ ).exclude(
+ id=self.sender.id
+ ).distinct()
+
+ def get_timeline(self):
+ """returns ordered query set of messages in the thread
+ with the newest first"""
+ root = self.get_root_message()
+ root_qs = Message.objects.filter(id=root.id)
+ return (root.descendants.all() | root_qs).order_by('-sent_at')
+
+
+ def send_email_alert(self):
+ """signal handler for the message post-save"""
+ root_message = self.get_root_message()
+ data = {'messages': self.get_timeline()}
+ template = get_template('group_messaging/email_alert.html')
+ body_text = template.render(data)
+ subject = self.get_email_subject_line()
+ for user in self.get_recipients_users():
+ #todo change url scheme so that all users have the same
+ #urls within their personal areas of the user profile
+ #so that we don't need to have loops like this one
+ thread_url = root_message.get_absolute_url(user)
+ thread_url = thread_url.replace('&', '&amp;')
+ #in the template we have a placeholder to be replaced like this:
+ body_text = body_text.replace('THREAD_URL_HOLE', thread_url)
+ send_mail(
+ subject,
+ body_text,
+ django_settings.DEFAULT_FROM_EMAIL,
+ [user.email,],
+ )
+
+
+ def update_senders_info(self):
+ """update the contributors info,
+ meant to be used on a root message only
+ """
+ senders_names = self.senders_info.split(',')
+
+ if self.sender.username in senders_names:
+ senders_names.remove(self.sender.username)
+ senders_names.insert(0, self.sender.username)
+
+ self.senders_info = (','.join(senders_names))[:64]
+ self.save()
+
+ def unarchive(self, user=None):
+ """unarchive message for all recipients"""
+ archived_filter = {'status': MessageMemo.ARCHIVED}
+ if user:
+ archived_filter['user'] = user
+ memos = self.memos.filter(**archived_filter)
+ memos.update(status=MessageMemo.SEEN)
+
+ def set_status_for_user(self, status, user):
+ """set specific status to the message for the user"""
+ memo, created = MessageMemo.objects.get_or_create(user=user, message=self)
+ memo.status = status
+ memo.save()
+
+ def archive(self, user):
+ """mark message as archived"""
+ self.set_status_for_user(MessageMemo.ARCHIVED, user)
+
+ def mark_as_seen(self, user):
+ """mark message as seen"""
+ self.set_status_for_user(MessageMemo.SEEN, user)
diff --git a/askbot/deps/group_messaging/tests.py b/askbot/deps/group_messaging/tests.py
new file mode 100644
index 00000000..bcf764db
--- /dev/null
+++ b/askbot/deps/group_messaging/tests.py
@@ -0,0 +1,363 @@
+import datetime
+import time
+import urlparse
+from bs4 import BeautifulSoup
+from django.test import TestCase
+from django.contrib.auth.models import User, Group
+from group_messaging.models import Message
+from group_messaging.models import MessageMemo
+from group_messaging.models import SenderList
+from group_messaging.models import LastVisitTime
+from group_messaging.models import get_personal_group
+from group_messaging.models import create_personal_group
+from group_messaging.views import ThreadsList
+from mock import Mock
+
+MESSAGE_TEXT = 'test message text'
+
+def create_user(name):
+ """creates a user and a personal group,
+ returns the created user"""
+ user = User.objects.create_user(name, name + '@example.com')
+ #note that askbot will take care of three lines below automatically
+ try:
+ group = get_personal_group(user)
+ except Group.DoesNotExist:
+ group = create_personal_group(user)
+ group_name = '_personal_%d' % user.id
+ group, created = Group.objects.get_or_create(name=group_name)
+ user.groups.add(group)
+ return user
+
+def get_html_message(mail_message):
+ """mail message is an item from the django.core.mail.outbox"""
+ return mail_message.alternatives[0][0]
+
+class GroupMessagingTests(TestCase):
+ """base class for the test cases in this app"""
+
+ def setUp(self):
+ self.sender = create_user('sender')
+ self.recipient = create_user('recipient')
+
+ def create_thread(self, sender, recipient_groups):
+ return Message.objects.create_thread(
+ sender=sender, recipients=recipient_groups,
+ text=MESSAGE_TEXT
+ )
+
+ def create_thread_for_user(self, sender, recipient):
+ group = get_personal_group(recipient)
+ return self.create_thread(sender, [group])
+
+ def setup_three_message_thread(self, original_poster=None, responder=None):
+ """talk in this order: sender, recipient, sender"""
+ original_poster = original_poster or self.sender
+ responder = responder or self.recipient
+
+ root_message = self.create_thread_for_user(original_poster, responder)
+ response = Message.objects.create_response(
+ sender=responder,
+ text='some response',
+ parent=root_message
+ )
+ response2 = Message.objects.create_response(
+ sender=original_poster,
+ text='some response2',
+ parent=response
+ )
+ return root_message, response, response2
+
+
+class ViewsTests(GroupMessagingTests):
+
+ def get_view_context(self, view_class, data=None, user=None, method='GET'):
+ spec = ['REQUEST', 'user']
+ assert(method in ('GET', 'POST'))
+ spec.append(method)
+ request = Mock(spec=spec)
+ request.REQUEST = data
+ setattr(request, method, data)
+ request.user = user
+ return view_class().get_context(request)
+
+ def test_new_response_marks_thread_heading_as_new(self):
+ root = self.create_thread_for_user(self.sender, self.recipient)
+ response = Message.objects.create_response(
+ sender=self.recipient,
+ text='some response',
+ parent=root
+ )
+ #response must show as "new" to the self.sender
+ context = self.get_view_context(
+ ThreadsList,
+ data={'sender_id': '-1'},
+ user=self.sender
+ )
+ self.assertEqual(context['threads_data'][root.id]['status'], 'new')
+ #"visit" the thread: todo - make a method
+ last_visit_time, created = LastVisitTime.objects.get_or_create(
+ user=self.sender,
+ message=root
+ )
+ last_visit_time.at = datetime.datetime.now()
+ last_visit_time.save()
+ time.sleep(1.5)
+
+ #response must show as "seen"
+ context = self.get_view_context(
+ ThreadsList,
+ data={'sender_id': '-1'},
+ user=self.sender
+ )
+ self.assertEqual(context['threads_data'][root.id]['status'], 'seen')
+ #self.recipient makes another response
+ response = Message.objects.create_response(
+ sender=self.recipient,
+ text='some response',
+ parent=response
+ )
+ #thread must be "new" again
+ context = self.get_view_context(
+ ThreadsList,
+ data={'sender_id': '-1'},
+ user=self.sender
+ )
+ self.assertEqual(context['threads_data'][root.id]['status'], 'new')
+
+ def test_answer_to_deleted_thread_undeletes_thread(self):
+ #setup: message, reply, responder deletes thread
+ root_message = self.create_thread_for_user(self.sender, self.recipient)
+ response = Message.objects.create_response(
+ sender=self.recipient,
+ text='some response',
+ parent=root_message
+ )
+ memo1, created = MessageMemo.objects.get_or_create(
+ message=root_message,
+ user=self.recipient,
+ status=MessageMemo.ARCHIVED
+ )
+ #OP sends reply to reply
+ response2 = Message.objects.create_response(
+ sender=self.sender,
+ text='some response2',
+ parent=response
+ )
+
+ context = self.get_view_context(
+ ThreadsList,
+ data={'sender_id': '-1'},
+ user=self.recipient
+ )
+
+ self.assertEqual(len(context['threads']), 1)
+ thread_id = context['threads'][0].id
+ thread_data = context['threads_data'][thread_id]
+ self.assertEqual(thread_data['status'], 'new')
+
+ def test_emailed_message_url_works_for_post_recipient(self):
+ root = self.create_thread_for_user(self.sender, self.recipient)
+ from django.core.mail import outbox
+ html_message = get_html_message(outbox[0])
+ link = BeautifulSoup(html_message).find('a', attrs={'class': 'thread-link'})
+ url = link['href'].replace('&amp;', '&')
+ parsed_url = urlparse.urlparse(url)
+ url_data = urlparse.parse_qsl(parsed_url.query)
+ self.client.login(user_id=self.recipient.id, method='force')
+ response = self.client.get(parsed_url.path, url_data)
+ dom = BeautifulSoup(response.content)
+ threads = dom.find_all('ul', attrs={'class': 'thread'})
+ self.assertEquals(len(threads), 1)
+ thread_lists = dom.find_all('table', attrs={'class': 'threads-list'})
+ self.assertEquals(len(thread_lists), 0)
+
+ def test_sent_thread_is_visited_by_sender(self):
+ root = self.create_thread_for_user(self.sender, self.recipient)
+ context = self.get_view_context(
+ ThreadsList,
+ data={'sender_id': str(self.sender.id)},
+ user=self.sender
+ )
+ thread_data = context['threads_data'][root.id]
+ self.assertEqual(thread_data['status'], 'seen')
+
+class ModelsTests(GroupMessagingTests):
+ """test cases for the `private_messaging` models"""
+
+ def test_create_thread_for_user(self):
+ """the basic create thread with one recipient
+ tests that the recipient is there"""
+ message = self.create_thread_for_user(self.sender, self.recipient)
+ #message type is stored
+ self.assertEqual(message.message_type, Message.STORED)
+ #recipient is in the list of recipients
+ recipients = set(message.recipients.all())
+ recipient_group = get_personal_group(self.recipient)
+ #sender_group = get_personal_group(self.sender) #maybe add this too
+ expected_recipients = set([recipient_group])
+ self.assertEqual(recipients, expected_recipients)
+ #self.assertRaises(
+ # MessageMemo.DoesNotExist,
+ # MessageMemo.objects.get,
+ # message=message
+ #)
+ #make sure that the original senders memo to the root
+ #message is marke ad seen
+ memos = MessageMemo.objects.filter(
+ message=message,
+ user=self.sender
+ )
+ self.assertEquals(memos.count(), 1)
+ self.assertEqual(memos[0].status, MessageMemo.SEEN)
+
+ def test_get_senders_for_user(self):
+ """this time send thread to a real group test that
+ member of the group has updated the sender list"""
+ group = Group.objects.create(name='somegroup')
+ self.recipient.groups.add(group)
+ message = self.create_thread(self.sender, [group])
+ senders = SenderList.objects.get_senders_for_user(self.recipient)
+ self.assertEqual(set(senders), set([self.sender]))
+
+ def test_create_thread_response(self):
+ """create a thread with one response,
+ then load thread for the user
+ test that only the root message is retrieved"""
+ root_message = self.create_thread_for_user(self.sender, self.recipient)
+ response = Message.objects.create_response(
+ sender=self.recipient,
+ text='some response',
+ parent=root_message
+ )
+ self.assertEqual(response.message_type, Message.STORED)
+
+ #assert that there is only one "seen" memo for the response
+ memos = MessageMemo.objects.filter(message=response)
+ self.assertEqual(memos.count(), 1)
+ self.assertEqual(memos[0].user, self.recipient)
+ self.assertEqual(memos[0].status, MessageMemo.SEEN)
+
+ #assert that recipients are the two people who are part of
+ #this conversation
+ recipients = set(response.recipients.all())
+ sender_group = get_personal_group(self.sender)
+ recipient_group = get_personal_group(self.recipient)
+ expected_recipients = set([sender_group, recipient_group])
+ self.assertEqual(recipients, expected_recipients)
+
+ def test_get_threads(self):
+ root_message = self.create_thread_for_user(self.sender, self.recipient)
+ threads = set(Message.objects.get_threads(recipient=self.sender))
+ self.assertEqual(threads, set([]))
+ threads = set(Message.objects.get_threads(recipient=self.recipient))
+ self.assertEqual(threads, set([root_message]))
+
+ response = Message.objects.create_response(
+ sender=self.recipient,
+ text='some response',
+ parent=root_message
+ )
+ threads = set(Message.objects.get_threads(recipient=self.sender))
+ self.assertEqual(threads, set([root_message]))
+ threads = set(Message.objects.get_threads(recipient=self.recipient))
+ self.assertEqual(threads, set([root_message]))
+
+ def test_deleting_thread_is_user_specific(self):
+ """when one user deletes thread, that same thread
+ should not end up deleted by another user
+ """
+ root, response, response2 = self.setup_three_message_thread()
+
+ threads = Message.objects.get_threads(recipient=self.sender)
+ self.assertEquals(threads.count(), 1)
+ threads = Message.objects.get_threads(recipient=self.recipient)
+ self.assertEquals(threads.count(), 1)
+
+ memo1, created = MessageMemo.objects.get_or_create(
+ message=root,
+ user=self.recipient,
+ status=MessageMemo.ARCHIVED
+ )
+
+ threads = Message.objects.get_threads(recipient=self.sender)
+ self.assertEquals(threads.count(), 1)
+ threads = Message.objects.get_threads(recipient=self.recipient)
+ self.assertEquals(threads.count(), 0)
+ threads = Message.objects.get_threads(
+ recipient=self.recipient, deleted=True
+ )
+ self.assertEquals(threads.count(), 1)
+
+ def test_user_specific_inboxes(self):
+ self.create_thread_for_user(self.sender, self.recipient)
+
+ threads = Message.objects.get_threads(
+ recipient=self.recipient, sender=self.sender
+ )
+ self.assertEqual(threads.count(), 1)
+ threads = Message.objects.get_threads(
+ recipient=self.sender, sender=self.recipient
+ )
+ self.assertEqual(threads.count(), 0)
+
+ def test_response_updates_thread_headline(self):
+ root = self.create_thread_for_user(self.sender, self.recipient)
+ response = Message.objects.create_response(
+ sender=self.recipient,
+ text='some response',
+ parent=root
+ )
+ self.assertEqual(root.headline, 'some response')
+
+ def test_email_alert_sent(self):
+ root = self.create_thread_for_user(self.sender, self.recipient)
+ from django.core.mail import outbox
+ self.assertEqual(len(outbox), 1)
+ self.assertEqual(len(outbox[0].recipients()), 1)
+ self.assertEqual(outbox[0].recipients()[0], self.recipient.email)
+ html_message = get_html_message(outbox[0])
+ self.assertTrue(root.text in html_message)
+ soup = BeautifulSoup(html_message)
+ links = soup.find_all('a', attrs={'class': 'thread-link'})
+ self.assertEqual(len(links), 1)
+ parse_result = urlparse.urlparse(links[0]['href'])
+ query = urlparse.parse_qs(parse_result.query.replace('&amp;', '&'))
+ self.assertEqual(query['thread_id'][0], str(root.id))
+
+ def test_get_sent_threads(self):
+ root1, re11, re12 = self.setup_three_message_thread()
+ root2, re21, re22 = self.setup_three_message_thread(
+ original_poster=self.recipient, responder=self.sender
+ )
+ root3, re31, re32 = self.setup_three_message_thread()
+
+ #mark root2 as seen
+ root2.mark_as_seen(self.sender)
+ #mark root3 as deleted
+ root3.archive(self.sender)
+
+ threads = Message.objects.get_sent_threads(sender=self.sender)
+ self.assertEqual(threads.count(), 2)
+ self.assertEqual(set(threads), set([root1, root2]))#root3 is deleted
+
+ def test_recipient_lists_are_in_senders_info(self):
+ thread = self.create_thread_for_user(self.sender, self.recipient)
+ self.assertTrue(self.recipient.username in thread.senders_info)
+
+ def test_self_response_not_in_senders_inbox(self):
+ root = self.create_thread_for_user(self.sender, self.recipient)
+ response = Message.objects.create_response(
+ sender=self.sender,
+ text='some response',
+ parent=root
+ )
+ threads = Message.objects.get_threads(recipient=self.sender)
+ self.assertEqual(threads.count(), 0)
+
+ def test_sent_message_is_seen_by_the_sender(self):
+ root = self.create_thread_for_user(self.sender, self.recipient)
+ time.sleep(1.5)
+ last_visits = LastVisitTime.objects.filter(message=root, user=self.sender)
+ self.assertEqual(last_visits.count(), 1)
+
diff --git a/group_messaging/urls.py b/askbot/deps/group_messaging/urls.py
index 30002bf3..19ee35bb 100644
--- a/group_messaging/urls.py
+++ b/askbot/deps/group_messaging/urls.py
@@ -15,6 +15,11 @@ urlpatterns = patterns('',
name='thread_details'
),
url(
+ '^threads/(?P<thread_id>\d+)/delete-or-restore/$',
+ views.DeleteOrRestoreThread().as_view(),
+ name='delete_or_restore_thread'
+ ),
+ url(
'^threads/create/$',
views.NewThread().as_view(),
name='create_thread'
diff --git a/group_messaging/views.py b/askbot/deps/group_messaging/views.py
index 289961ff..244762d1 100644
--- a/group_messaging/views.py
+++ b/askbot/deps/group_messaging/views.py
@@ -10,14 +10,16 @@ and turns them into complete views
"""
import copy
import datetime
-from coffin.template.loader import get_template
+from django.template.loader import get_template
from django.contrib.auth.models import User
+from django.db import models
from django.forms import IntegerField
from django.http import HttpResponse
from django.http import HttpResponseNotAllowed
from django.http import HttpResponseForbidden
from django.utils import simplejson
from group_messaging.models import Message
+from group_messaging.models import MessageMemo
from group_messaging.models import SenderList
from group_messaging.models import LastVisitTime
from group_messaging.models import get_personal_group_by_user_id
@@ -104,7 +106,12 @@ class NewThread(InboxView):
if missing:
result['success'] = False
result['missing_users'] = missing
- else:
+
+ if request.user.username in usernames:
+ result['success'] = False
+ result['self_message'] = True
+
+ if result.get('success', True):
recipients = get_personal_groups_for_users(users)
message = Message.objects.create_thread(
sender=request.user,
@@ -139,6 +146,7 @@ class PostReply(InboxView):
template_name='group_messaging/stored_message.html'
)
+
class ThreadsList(InboxView):
"""shows list of threads for a given user"""
template_name = 'group_messaging/threads_list.html'
@@ -147,11 +155,24 @@ class ThreadsList(InboxView):
def get_context(self, request):
"""returns thread list data"""
#get threads and the last visit time
- threads = Message.objects.get_threads_for_user(request.user)
+ sender_id = IntegerField().clean(request.REQUEST.get('sender_id', '-1'))
+ if sender_id == -2:
+ threads = Message.objects.get_threads(
+ recipient=request.user,
+ deleted=True
+ )
+ elif sender_id == -1:
+ threads = Message.objects.get_threads(recipient=request.user)
+ elif sender_id == request.user.id:
+ threads = Message.objects.get_sent_threads(sender=request.user)
+ else:
+ sender = User.objects.get(id=sender_id)
+ threads = Message.objects.get_threads(
+ recipient=request.user,
+ sender=sender
+ )
- sender_id = IntegerField().clean(request.GET.get('sender_id', '-1'))
- if sender_id != -1:
- threads = threads.filter(sender__id=sender_id)
+ threads = threads.order_by('-last_active_at')
#for each thread we need to know if there is something
#unread for the user - to mark "new" threads as bold
@@ -168,6 +189,17 @@ class ThreadsList(InboxView):
thread_data['thread'] = thread
threads_data[thread.id] = thread_data
+ ids = [thread.id for thread in threads]
+ counts = Message.objects.filter(
+ id__in=ids
+ ).annotate(
+ responses_count=models.Count('descendants')
+ ).values('id', 'responses_count')
+ for count in counts:
+ thread_id = count['id']
+ responses_count = count['responses_count']
+ threads_data[thread_id]['responses_count'] = responses_count
+
last_visit_times = LastVisitTime.objects.filter(
user=request.user,
message__in=threads
@@ -177,9 +209,49 @@ class ThreadsList(InboxView):
if thread_data['thread'].last_active_at <= last_visit.at:
thread_data['status'] = 'seen'
- #after we have all the data - update the last visit time
- last_visit_times.update(at=datetime.datetime.now())
- return {'threads': threads, 'threads_data': threads_data}
+ return {
+ 'threads': threads,
+ 'threads_count': threads.count(),
+ 'threads_data': threads_data,
+ 'sender_id': sender_id
+ }
+
+
+class DeleteOrRestoreThread(ThreadsList):
+ """subclassing :class:`ThreadsList`, because deletion
+ or restoring of thread needs subsequent refreshing
+ of the threads list"""
+
+ http_method_list = ('POST',)
+
+ def post(self, request, thread_id=None):
+ """process the post request:
+ * delete or restore thread
+ * recalculate the threads list and return it for display
+ by reusing the threads list "get" function
+ """
+ #part of the threads list context
+ sender_id = IntegerField().clean(request.POST['sender_id'])
+
+ #a little cryptic, but works - sender_id==-2 means deleted post
+ if sender_id == -2:
+ action = 'restore'
+ else:
+ action = 'delete'
+
+ thread = Message.objects.get(id=thread_id)
+ memo, created = MessageMemo.objects.get_or_create(
+ user=request.user,
+ message=thread
+ )
+ if action == 'delete':
+ memo.status = MessageMemo.ARCHIVED
+ else:
+ memo.status = MessageMemo.SEEN
+ memo.save()
+
+ context = self.get_context(request)
+ return self.render_to_response(context)
class SendersList(InboxView):
@@ -191,7 +263,7 @@ class SendersList(InboxView):
"""get data about senders for the user"""
senders = SenderList.objects.get_senders_for_user(request.user)
senders = senders.values('id', 'username')
- return {'senders': senders}
+ return {'senders': senders, 'request_user_id': request.user.id}
class ThreadDetails(InboxView):
diff --git a/askbot/deps/livesettings/functions.py b/askbot/deps/livesettings/functions.py
index 7517cb9f..6634aa20 100644
--- a/askbot/deps/livesettings/functions.py
+++ b/askbot/deps/livesettings/functions.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext
+from django.utils.translation import ugettext as _
from askbot.deps.livesettings import values
from askbot.deps.livesettings.models import SettingNotSet
from askbot.deps.livesettings.utils import is_string_like
@@ -247,7 +247,7 @@ def config_choice_values(group, key, skip_missing=True, translate=False):
raise SettingNotSet('%s.%s' % (group, key))
if translate:
- choices = [(k, ugettext(v)) for k, v in choices]
+ choices = [(k, _(v)) for k, v in choices]
return choices
diff --git a/askbot/deps/livesettings/models.py b/askbot/deps/livesettings/models.py
index 71db8acf..3f42b59d 100644
--- a/askbot/deps/livesettings/models.py
+++ b/askbot/deps/livesettings/models.py
@@ -2,7 +2,7 @@ from django.conf import settings
from django.contrib.sites.models import Site
from django.db import models
from django.db.models import loading
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import ugettext_lazy
from keyedcache import cache_key, cache_get, cache_set, NotCachedError
from keyedcache.models import CachedObjectMixin
from askbot.deps.livesettings.overrides import get_overrides
@@ -104,7 +104,7 @@ class ImmutableSetting(object):
class Setting(models.Model, CachedObjectMixin):
- site = models.ForeignKey(Site, verbose_name=_('Site'))
+ site = models.ForeignKey(Site, verbose_name=ugettext_lazy('Site'))
group = models.CharField(max_length=100, blank=False, null=False)
key = models.CharField(max_length=100, blank=False, null=False)
value = models.CharField(max_length=255, blank=True)
@@ -150,7 +150,7 @@ class LongSettingManager(models.Manager):
class LongSetting(models.Model, CachedObjectMixin):
"""A Setting which can handle more than 255 characters"""
- site = models.ForeignKey(Site, verbose_name=_('Site'))
+ site = models.ForeignKey(Site, verbose_name=ugettext_lazy('Site'))
group = models.CharField(max_length=100, blank=False, null=False)
key = models.CharField(max_length=100, blank=False, null=False)
value = models.TextField(blank=True)
diff --git a/askbot/deps/livesettings/values.py b/askbot/deps/livesettings/values.py
index 95ca1069..92b5d24e 100644
--- a/askbot/deps/livesettings/values.py
+++ b/askbot/deps/livesettings/values.py
@@ -10,7 +10,8 @@ from django.core.cache import cache
from django.utils import simplejson
from django.utils.datastructures import SortedDict
from django.utils.encoding import smart_str
-from django.utils.translation import gettext, ugettext_lazy as _
+from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy
from django.core.files import storage
from askbot.deps.livesettings.models import find_setting, LongSetting, Setting, SettingNotSet
from askbot.deps.livesettings.overrides import get_overrides
@@ -67,7 +68,7 @@ class SuperGroup(object):
self.groups.append(group)
-BASE_SUPER_GROUP = SuperGroup(_('Main'))
+BASE_SUPER_GROUP = SuperGroup(ugettext_lazy('Main'))
class ConfigurationGroup(SortedDotDict):
"""A simple wrapper for a group of configuration values"""
@@ -126,7 +127,11 @@ class ConfigurationGroup(SortedDotDict):
vals = super(ConfigurationGroup, self).values()
return [v for v in vals if v.enabled()]
-BASE_GROUP = ConfigurationGroup('BASE', _('Base Settings'), ordering=0)
+BASE_GROUP = ConfigurationGroup(
+ 'BASE',
+ ugettext_lazy('Base Settings'),
+ ordering=0
+ )
class Value(object):
@@ -242,7 +247,7 @@ class Value(object):
for x in self.choices:
if x[0] in self.default:
work.append(smart_str(x[1]))
- note = gettext('Default value: ') + ", ".join(work)
+ note = _('Default value: ') + ", ".join(work)
else:
note = _("Default value: %s") % unicode(self.default)
diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst
index f5714421..0c54f173 100644
--- a/askbot/doc/source/changelog.rst
+++ b/askbot/doc/source/changelog.rst
@@ -3,6 +3,41 @@ Changes in Askbot
Development version
-------------------
+* Added full text support for some languages with Postgresql:
+ Danish, Dutch, English, Finnish, French, German, Hungarian,
+ Italian, Japanese (requires package textsearch_ja), Norwegian,
+ Portugese, Romanian, Russian, Spanish, Swedish, Turkish.
+* repost answer as a comment under the previous (older) answer
+* minor edit option for question and answer, to suppress email alerts
+* allowed tags to be created updon marking them as interesting/ignored/subscribed
+
+0.7.48 (Jan 28, 2013)
+---------------------
+* made "how to ask the question" instructions editable
+* added RSS auto-discovery link
+* added support for multilingual site (experimental)
+* tag subscription manager on the tags page (Adolfo)
+
+0.7.47 (Dec 13, 2012)
+---------------------
+* Bugfix release
+
+0.7.46 (Dec 12, 2012)
+---------------------
+* Bugfix release
+
+0.7.45 (Dec 12, 2012)
+---------------------
+* Feedback sender's email is added to the Reply-To header
+ in the feedback form (Evgeny)
+* Reimplemented search as drop-down (Evgeny)
+* Basic design to work on smartphones (Evgeny)
+* Allowed use of alternative form on the user signup page (Evgeny)
+
+0.7.44 (Nov 11, 2012)
+---------------------
+* Support for django 1.4 (Adolfo)
+* Added option to enable/disable rss feeds (Evgeny)
* Added minimum reputation to insert links and hotlinked images (Evgeny)
* Added minimum reputation to suggest links as plain text (Evgeny)
* Added support of Haystack for search (Adolfo)
diff --git a/askbot/doc/source/contributors.rst b/askbot/doc/source/contributors.rst
index a795d84e..71d942bb 100644
--- a/askbot/doc/source/contributors.rst
+++ b/askbot/doc/source/contributors.rst
@@ -6,8 +6,8 @@ This is the list of contributors to the code of Askbot project.
The list is probably incomplete, apologies for any omissions.
Thanks for all your help
-Programming and documentation
------------------------------
+Programming, bug fixes and documentation
+----------------------------------------
* Mike Chen & Sailing Cai - original authors of CNPROG forum
* Evgeny Fadeev - founder of askbot
* `Adolfo Fitoria <http://fitoria.net>`_
@@ -42,6 +42,7 @@ Programming and documentation
* `Alexandros <https://github.com/alexandros-z>`_
* `Paul Backhouse <https://github.com/powlo>`_
* `jtrain <https://github.com/jtrain>`_
+* Niki Rocco
Translations
------------
diff --git a/askbot/doc/source/initial-configuration.rst b/askbot/doc/source/initial-configuration.rst
index 7905aa1d..abef2e48 100644
--- a/askbot/doc/source/initial-configuration.rst
+++ b/askbot/doc/source/initial-configuration.rst
@@ -48,6 +48,8 @@ There may be an error message; ignore it.
| -n <NAME> | Name of the instance, this is the name that the |
| | folder will use. |
+----------------------------------+------------------------------------------------------------+
+ | -e <DATABASE_ENGINE> | Integer values: 1 - postgresql, 2 - sqlite3, 3 - mysql |
+ +----------------------------------+------------------------------------------------------------+
| -d <DATABASE_NAME> | The database name that the instance will use. |
+----------------------------------+------------------------------------------------------------+
| -u <DATABASE_USER> | The database user that the instance will use. |
diff --git a/askbot/doc/source/management-commands.rst b/askbot/doc/source/management-commands.rst
index 2755bcf5..cc5e952f 100644
--- a/askbot/doc/source/management-commands.rst
+++ b/askbot/doc/source/management-commands.rst
@@ -197,5 +197,3 @@ the developers of the Askbot project:
+--------------------------------+-------------------------------------------------------------+
| `askbot_add_test_content` | Creates content with dummy data for testing |
+--------------------------------+-------------------------------------------------------------+
-| `askbot_create_test_fixture` | Creates a test fixture at `askbot/tests/test_data.json` |
-+--------------------------------+-------------------------------------------------------------+
diff --git a/askbot/feed.py b/askbot/feed.py
index 285bb452..0e1102b1 100644
--- a/askbot/feed.py
+++ b/askbot/feed.py
@@ -12,12 +12,14 @@
"""
#!/usr/bin/env python
#encoding:utf-8
+from django.contrib.syndication.views import Feed
+
import itertools
-from django.contrib.syndication.feeds import Feed
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext as _
from django.core.exceptions import ObjectDoesNotExist
+from django.http import Http404
from askbot.models import Post
from askbot.conf import settings as askbot_settings
@@ -36,10 +38,12 @@ class RssIndividualQuestionFeed(Feed):
def description(self):
return askbot_settings.APP_DESCRIPTION
- def get_object(self, bits):
- if len(bits) != 1:
- raise ObjectDoesNotExist
- return Post.objects.get_questions().get(id__exact = bits[0])
+ def get_object(self, request, pk):
+ if askbot_settings.RSS_ENABLED is False:
+ raise Http404
+ #hack to get the request object into the Feed class
+ self.request = request
+ return Post.objects.get_questions().get(id__exact = pk)
def item_link(self, item):
"""get full url to the item
@@ -67,6 +71,7 @@ class RssIndividualQuestionFeed(Feed):
)
answers = Post.objects.get_answers().filter(thread = item.thread)
+
for answer in answers:
chain_elements.append([answer,])
chain_elements.append(
@@ -134,7 +139,7 @@ class RssLastestQuestionsFeed(Feed):
"""returns url without the slug
because the slug can change
"""
- return askbot_settings.APP_URL + item.get_absolute_url(no_slug = True)
+ return self.link() + item.get_absolute_url(no_slug = True)
def item_description(self, item):
"""returns the description for the item
@@ -144,6 +149,8 @@ class RssLastestQuestionsFeed(Feed):
def items(self, item):
"""get questions for the feed
"""
+ if askbot_settings.RSS_ENABLED is False:
+ raise Http404
#initial filtering
qs = Post.objects.get_questions().filter(deleted=False)
@@ -164,7 +171,10 @@ class RssLastestQuestionsFeed(Feed):
return qs.order_by('-thread__last_activity_at')[:30]
-
+ #hack to get the request object into the Feed class
+ 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
diff --git a/askbot/forms.py b/askbot/forms.py
index a4365776..5e9a7850 100644
--- a/askbot/forms.py
+++ b/askbot/forms.py
@@ -4,6 +4,8 @@ import re
from django import forms
from askbot import const
from askbot.const import message_keys
+from django.conf import settings as django_settings
+from django.core.exceptions import PermissionDenied
from django.forms.util import ErrorList
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy, string_concat
@@ -11,7 +13,6 @@ from django.utils.text import get_text_list
from django.contrib.auth.models import User
from django_countries import countries
from askbot.utils.forms import NextUrlField, UserNameField
-from askbot.utils.markup import URL_RE
from askbot.mail import extract_first_email_address
from recaptcha_works.fields import RecaptchaField
from askbot.conf import settings as askbot_settings
@@ -203,6 +204,20 @@ class CountedWordsField(forms.CharField):
return value
+class LanguageField(forms.ChoiceField):
+
+ def __init__(self, *args, **kwargs):
+ kwargs['choices'] = django_settings.LANGUAGES
+ super(LanguageField, self).__init__(*args, **kwargs)
+
+
+class SuppressEmailField(forms.BooleanField):
+ def __init__(self):
+ super(SuppressEmailField, self).__init__()
+ self.required = False
+ self.label = _("minor edit (don't send alerts)")
+
+
class DomainNameField(forms.CharField):
"""Field for Internet Domain Names
todo: maybe there is a standard field for this?
@@ -219,7 +234,7 @@ class DomainNameField(forms.CharField):
class TitleField(forms.CharField):
- """Fild receiving question title"""
+ """Field receiving question title"""
def __init__(self, *args, **kwargs):
super(TitleField, self).__init__(*args, **kwargs)
self.required = kwargs.get('required', True)
@@ -302,20 +317,16 @@ class EditorField(forms.CharField):
) % self.min_length
raise forms.ValidationError(msg)
- if re.search(URL_RE, value):
- min_rep = askbot_settings.MIN_REP_TO_SUGGEST_LINK
- if self.user.is_anonymous():
- raise forms.ValidationError(
- _('Links or images cannot be posted anonymously')
- )
- elif self.user.reputation < min_rep:
- raise forms.ValidationError(
- ungettext_lazy(
- 'At at least %d karma point is required to post links',
- 'At at least %d karma points are required to post links',
- min_rep
- ) % min_rep
- )
+ if self.user.is_anonymous():
+ #we postpone this validation if user is posting
+ #before logging in, up until publishing the post
+ return value
+
+ try:
+ self.user.assert_can_post_text(value)
+ except PermissionDenied, e:
+ raise forms.ValidationError(unicode(e))
+
return value
@@ -392,8 +403,8 @@ class TagNamesField(forms.CharField):
'We ran out of space for recording the tags. '
'Please shorten or delete some of them.'
)
- self.label = _('tags')
- self.help_text = ungettext_lazy(
+ self.label = kwargs.get('label') or _('tags')
+ self.help_text = kwargs.get('help_text') or ungettext_lazy(
'Tags are short keywords, with no spaces within. '
'Up to %(max_tags)d tag can be used.',
'Tags are short keywords, with no spaces within. '
@@ -529,10 +540,6 @@ class ShowQuestionForm(forms.Form):
page = forms.IntegerField(required=False)
sort = forms.CharField(required=False)
- def __init__(self, data, default_sort_method):
- super(ShowQuestionForm, self).__init__(data)
- self.default_sort_method = default_sort_method
-
def get_pruned_data(self):
nones = ('answer', 'comment', 'page')
for key in nones:
@@ -562,10 +569,7 @@ class ShowQuestionForm(forms.Form):
out_data['show_answer'] = in_data.get('answer', None)
else:
out_data['show_page'] = in_data.get('page', 1)
- out_data['answer_sort_method'] = in_data.get(
- 'sort',
- self.default_sort_method
- )
+ out_data['answer_sort_method'] = in_data.get('sort', 'votes')
out_data['show_comment'] = None
out_data['show_answer'] = None
self.cleaned_data = out_data
@@ -633,12 +637,13 @@ class ChangeUserStatusForm(forms.Form):
super(ChangeUserStatusForm, self).__init__(*arg, **kwarg)
#select user_status_choices depending on status of the moderator
- if moderator.is_administrator():
- user_status_choices = ADMINISTRATOR_STATUS_CHOICES
- elif moderator.is_moderator():
- user_status_choices = MODERATOR_STATUS_CHOICES
- if subject.is_moderator() and subject != moderator:
- raise ValueError('moderator cannot moderate another moderator')
+ if moderator.is_authenticated():
+ if moderator.is_administrator():
+ user_status_choices = ADMINISTRATOR_STATUS_CHOICES
+ elif moderator.is_moderator():
+ user_status_choices = MODERATOR_STATUS_CHOICES
+ if subject.is_moderator() and subject != moderator:
+ raise ValueError('moderator cannot moderate another moderator')
else:
raise ValueError('moderator or admin expected from "moderator"')
@@ -929,6 +934,9 @@ class AskForm(PostAsSomeoneForm, PostPrivatelyForm):
#it's important that this field is set up dynamically
self.fields['text'] = QuestionEditorField(user=user)
#hide ask_anonymously field
+ if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False):
+ self.fields['language'] = LanguageField()
+
if askbot_settings.ALLOW_ASK_ANONYMOUSLY is False:
self.hide_field('ask_anonymously')
@@ -1160,11 +1168,7 @@ class RevisionForm(forms.Form):
"""
Lists revisions of a Question or Answer
"""
- revision = forms.ChoiceField(
- widget=forms.Select(
- attrs={'style': 'width:520px'}
- )
- )
+ revision = forms.ChoiceField(widget=forms.Select())
def __init__(self, post, latest_revision, *args, **kwargs):
super(RevisionForm, self).__init__(*args, **kwargs)
@@ -1196,6 +1200,7 @@ class EditQuestionForm(PostAsSomeoneForm, PostPrivatelyForm):
label=_('reveal identity'),
required=False,
)
+ suppress_email = SuppressEmailField()
#todo: this is odd that this form takes question as an argument
def __init__(self, *args, **kwargs):
@@ -1214,12 +1219,21 @@ class EditQuestionForm(PostAsSomeoneForm, PostPrivatelyForm):
if not self.can_stay_anonymous():
self.hide_field('reveal_identity')
+ if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False):
+ self.fields['language'] = LanguageField()
+
def has_changed(self):
if super(EditQuestionForm, self).has_changed():
return True
if askbot_settings.GROUPS_ENABLED:
- return self.question.is_private() \
- != self.cleaned_data['post_privately']
+ was_private = self.question.is_private()
+ if was_private != self.cleaned_data['post_privately']:
+ return True
+
+ if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False):
+ old_language = self.question.thread.language_code
+ if old_language != self.cleaned_data['language']:
+ return True
else:
return False
@@ -1304,6 +1318,7 @@ class EditQuestionForm(PostAsSomeoneForm, PostPrivatelyForm):
class EditAnswerForm(PostAsSomeoneForm, PostPrivatelyForm):
summary = SummaryField()
wiki = WikiField()
+ suppress_email = SuppressEmailField()
def __init__(self, answer, revision, *args, **kwargs):
self.answer = answer
@@ -1324,6 +1339,9 @@ class EditAnswerForm(PostAsSomeoneForm, PostPrivatelyForm):
else:
return False
+class EditCommentForm(forms.Form):
+ comment_id = forms.IntegerField()
+ suppress_email = SuppressEmailField()
class EditTagWikiForm(forms.Form):
text = forms.CharField(required=False)
@@ -1333,7 +1351,7 @@ class EditTagWikiForm(forms.Form):
class EditUserForm(forms.Form):
email = forms.EmailField(
label=u'Email',
- required=True,
+ required=False,
max_length=255,
widget=forms.TextInput(attrs={'size': 35})
)
@@ -1659,3 +1677,17 @@ class ModerateTagForm(forms.Form):
class ShareQuestionForm(forms.Form):
thread_id = forms.IntegerField()
recipient_name = forms.CharField()
+
+class BulkTagSubscriptionForm(forms.Form):
+ date_added = forms.DateField(required=False, widget=forms.HiddenInput())
+ tags = TagNamesField(label=_("Tags"), help_text=' ')
+
+ def __init__(self, *args, **kwargs):
+ from askbot.models import BulkTagSubscription, Tag, Group
+ super(BulkTagSubscriptionForm, self).__init__(*args, **kwargs)
+ self.fields['users'] = forms.ModelMultipleChoiceField(queryset=User.objects.all())
+ if askbot_settings.GROUPS_ENABLED:
+ self.fields['groups'] = forms.ModelMultipleChoiceField(queryset=Group.objects.exclude_personal())
+
+class DeleteCommentForm(forms.Form):
+ comment_id = forms.IntegerField()
diff --git a/askbot/importers/stackexchange/management/commands/load_stackexchange.py b/askbot/importers/stackexchange/management/commands/load_stackexchange.py
index ff17a523..ff6ddb15 100644
--- a/askbot/importers/stackexchange/management/commands/load_stackexchange.py
+++ b/askbot/importers/stackexchange/management/commands/load_stackexchange.py
@@ -1,11 +1,12 @@
#todo: http://stackoverflow.com/questions/837828/how-to-use-a-slug-in-django
-DEBUGME = False
+DEBUGME = False
import os
import re
import sys
from unidecode import unidecode
import zipfile
from datetime import datetime
+from django.conf import settings as django_settings
from django.core.management.base import BaseCommand, CommandError
import askbot.importers.stackexchange.parse_models as se_parser
from xml.etree import ElementTree as et
@@ -17,11 +18,18 @@ import askbot.deps.django_authopenid.models as askbot_openid
import askbot.importers.stackexchange.models as se
from askbot.forms import EditUserEmailFeedsForm
from askbot.conf import settings as askbot_settings
-from django.contrib.auth.models import Message as DjangoMessage
-from django.utils.translation import ugettext as _
+
+try:
+ from django.contrib.auth.models import Message as DjangoMessage
+except ImportError:
+ from askbot.models.message import Message as DjangoMessage
+
+from django.utils.translation import ugettext_lazy as _
+from askbot.utils.console import ProgressBar
from askbot.utils.slug import slugify
from askbot.models.badges import award_badges_signal, award_badges
from askbot.importers.stackexchange.management import is_ready as importer_is_ready
+from optparse import make_option
#from markdown2 import Markdown
#markdowner = Markdown(html4tags=True)
@@ -30,7 +38,8 @@ if DEBUGME == True:
from askbot.utils import dummy_transaction as transaction
HEAP = hpy()
else:
- from django.db import transaction
+ #from django.db import transaction
+ from askbot.utils import dummy_transaction as transaction
xml_read_order = (
'VoteTypes','UserTypes','Users','Users2Votes',
@@ -154,12 +163,12 @@ class X(object):#
#or use database to store these associations
try:
if isinstance(se_post, se.PostComment):
- return askbot.Comment.objects.get(id=COMMENT[se_post.id].id)
+ return askbot.Post.objects.get(id=COMMENT[se_post.id].id)
post_type = se_post.post_type.name
if post_type == 'Question':
- return askbot.Question.objects.get(id=QUESTION[se_post.id].id)
+ return askbot.Post.objects.get(id=QUESTION[se_post.id].id)
elif post_type == 'Answer':
- return askbot.Answer.objects.get(id=ANSWER[se_post.id].id)
+ return askbot.Post.objects.get(id=ANSWER[se_post.id].id)
else:
raise Exception('unknown post type %s' % post_type)
except KeyError:
@@ -280,12 +289,46 @@ class X(object):#
return slugify(cls.badge_exceptions.get(name, name).lower())
class Command(BaseCommand):
- help = 'Loads StackExchange data from unzipped directory of XML files into the ASKBOT database'
+ help = """Loads StackExchange data from SE dump .zip file
+it may be helpful to split this procedure in two:\n
+* read the dump (with option --read-se-dump)
+* transfer data to askbot (with option --process-data)
+"""
args = 'se_dump_dir'
+ option_list = BaseCommand.option_list + (
+ make_option('-r', '--read-dump',
+ action='store_true',
+ dest='read_dump',
+ default=False,
+ help='Only read the the dump'
+ ),
+ make_option('-p', '--process-data',
+ action='store_true',
+ dest='process_data',
+ default=False,
+ help='Only process the data, assuming that the dump is loaded'
+ )
+ )
+
@transaction.commit_manually
def handle(self, *arg, **kwarg):
+ if django_settings.DEBUG:
+ raise CommandError(
+ 'Please set DEBUG to False in the settings.py to reduce '
+ 'RAM usage during the import process'
+ )
+
+ #process the command line arguments, if given
+ if kwarg['read_dump'] is False and kwarg['process_data'] is False:
+ #make them both true as a hack to simulate a condition where
+ #no flags selected means the same as both are indeed selected
+ kwarg['read_dump'] = True
+ kwarg['process_data'] = True
+
+ askbot_settings.update('LIMIT_ONE_ANSWER_PER_USER', False)
+
if not importer_is_ready():
raise CommandError(
"Looks like stackexchange tables are not yet initialized in the database.\n"
@@ -299,16 +342,23 @@ class Command(BaseCommand):
if len(arg) < 1 or not os.path.isfile(arg[0]):
raise CommandError('Error: first argument must be a zip file with the SE forum data')
- self.zipfile = self.open_dump(arg[0])
- #read the data into SE tables
- for item in xml_read_order:
- time_before = datetime.now()
- self.load_xml_file(item)
- transaction.commit()
- time_after = datetime.now()
- if DEBUGME == True:
- print time_after - time_before
- print HEAP.heap()
+ if kwarg['read_dump']:
+ self.zipfile = self.open_dump(arg[0])
+ #read the data into SE tables
+ for item in xml_read_order:
+ time_before = datetime.now()
+ self.load_xml_file(item)
+ transaction.commit()
+ time_after = datetime.now()
+ if DEBUGME == True:
+ print time_after - time_before
+ print HEAP.heap()
+
+ if kwarg['process_data'] is False:
+ #that means we just wanted to load the xml dump to
+ #do the second step in another go in order to have
+ #more ram for the transfer of data from SE to Askbot databases
+ return
#this is important so that when we clean up messages
#automatically generated by the procedures below
@@ -320,36 +370,36 @@ class Command(BaseCommand):
self.save_askbot_message_id_list()
#transfer data into ASKBOT tables
- print 'Transferring users...',
+ print 'Transferring users...'
self.transfer_users()
transaction.commit()
print 'done.'
- print 'Transferring content edits...',
+ print 'Transferring content edits...'
sys.stdout.flush()
self.transfer_question_and_answer_activity()
transaction.commit()
print 'done.'
- print 'Transferring view counts...',
+ print 'Transferring view counts...'
sys.stdout.flush()
self.transfer_question_view_counts()
transaction.commit()
print 'done.'
- print 'Transferring comments...',
+ print 'Transferring comments...'
sys.stdout.flush()
self.transfer_comments()
transaction.commit()
print 'done.'
- print 'Transferring badges and badge awards...',
+ print 'Transferring badges and badge awards...'
sys.stdout.flush()
self.transfer_badges()
transaction.commit()
print 'done.'
- print 'Transferring Q&A votes...',
+ print 'Transferring Q&A votes...'
sys.stdout.flush()
self.transfer_QA_votes()#includes favorites, accepts and flags
transaction.commit()
print 'done.'
- print 'Transferring comment votes...',
+ print 'Transferring comment votes...'
sys.stdout.flush()
self.transfer_comment_votes()
transaction.commit()
@@ -396,7 +446,8 @@ class Command(BaseCommand):
"""transfers some messages from
SE to ASKBOT
"""
- for m in se.Message.objects.all().iterator():
+ messages = se.Message.objects.all()
+ for m in ProgressBar(messages.iterator(), messages.count()):
if m.is_read:
continue
if m.user is None:
@@ -522,10 +573,7 @@ class Command(BaseCommand):
def mark_activity(self,p,u,t):
"""p,u,t - post, user, timestamp
"""
- if isinstance(p, askbot.Question):
- p.thread.set_last_activity(last_activity_by=u, last_activity_at=t)
- elif isinstance(p, askbot.Answer):
- p.question.thread.set_last_activity(last_activity_by=u, last_activity_at=t)
+ p.thread.set_last_activity(last_activity_by=u, last_activity_at=t)
def _process_post_rollback_revision_group(self, rev_group):
#todo: don't know what to do here as there were no
@@ -647,7 +695,9 @@ class Command(BaseCommand):
c_group = []
#this loop groups revisions by revision id, then calls process function
#for the revision grup (elementary revisions posted at once)
- for se_rev in se_revs.iterator():
+ message = 'Processing revisions'
+ count = se_revs.count()
+ for se_rev in ProgressBar(se_revs.iterator(), count, message):
if se_rev.revision_guid == c_guid:
c_group.append(se_rev)
else:
@@ -660,7 +710,8 @@ class Command(BaseCommand):
self._process_post_revision_group(c_group)
def transfer_comments(self):
- for se_c in se.PostComment.objects.all().iterator():
+ comments = se.PostComment.objects.all()
+ for se_c in ProgressBar(comments.iterator(), comments.count()):
if se_c.deletion_date:
print 'Warning deleted comment %d dropped' % se_c.id
sys.stdout.flush()
@@ -683,7 +734,9 @@ class Command(BaseCommand):
def _collect_missing_badges(self):
self._missing_badges = {}
- for se_b in se.Badge.objects.all():
+ badges = se.Badge.objects.all()
+ message = 'Collecting missing badges'
+ for se_b in ProgressBar(badges.iterator(), badges.count(), message):
name = X.get_badge_name(se_b.name)
try:
#todo: query badge from askbot.models.badges
@@ -700,7 +753,9 @@ class Command(BaseCommand):
def _award_badges(self):
#note: SE does not keep information on
#content-related badges like askbot does
- for se_a in se.User2Badge.objects.all().iterator():
+ badges = se.User2Badge.objects.all()
+ message = 'Awarding badges'
+ for se_a in ProgressBar(badges.iterator(), badges.count(), message):
if se_a.user.id == -1:
continue #skip community user
u = USER[se_a.user.id]
@@ -743,7 +798,8 @@ class Command(BaseCommand):
pass
def transfer_question_view_counts(self):
- for se_q in se.Post.objects.filter(post_type__name='Question').iterator():
+ questions = se.Post.objects.filter(post_type__name='Question')
+ for se_q in ProgressBar(questions.iterator(), questions.count()):
q = X.get_post(se_q)
if q is None:
continue
@@ -752,7 +808,8 @@ class Command(BaseCommand):
def transfer_QA_votes(self):
- for v in se.Post2Vote.objects.all().iterator():
+ votes = se.Post2Vote.objects.all()
+ for v in ProgressBar(votes.iterator(), votes.count()):
vote_type = v.vote_type.name
if not vote_type in X.vote_actions:
continue
@@ -779,7 +836,8 @@ class Command(BaseCommand):
transaction.commit()
def transfer_comment_votes(self):
- for v in se.Comment2Vote.objects.all().iterator():
+ votes = se.Comment2Vote.objects.all()
+ for v in ProgressBar(votes.iterator(), votes.count()):
vote_type = v.vote_type.name
if vote_type not in ('UpMod', 'Offensive'):
continue
@@ -822,10 +880,11 @@ class Command(BaseCommand):
xml_data = self.zipfile.read(xml_path)
tree = et.fromstring(xml_data)
- print 'loading from %s to %s' % (xml_path, table_name) ,
+ print 'loading from %s to %s' % (xml_path, table_name)
model = models.get_model('stackexchange', table_name)
i = 0
- for row in tree.findall('.//row'):
+ rows = tree.findall('.//row')
+ for row in ProgressBar(iter(rows), len(rows)):
model_entry = model()
i += 1
for col in row.getchildren():
@@ -849,7 +908,8 @@ class Command(BaseCommand):
return xml_file_basename + '.xml'
def transfer_users(self):
- for se_u in se.User.objects.all().iterator():
+ se_users = se.User.objects.all()
+ for se_u in ProgressBar(se_users.iterator(), se_users.count()):
#if se_u.id == -1:#skip the Community user
# continue
u = askbot.User()
diff --git a/askbot/locale/es/LC_MESSAGES/django.mo b/askbot/locale/es/LC_MESSAGES/django.mo
index 8edbd712..86cdcf86 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 2b3e9eb5..f5218dea 100644
--- a/askbot/locale/es/LC_MESSAGES/django.po
+++ b/askbot/locale/es/LC_MESSAGES/django.po
@@ -6637,7 +6637,7 @@ msgstr "ver preguntas sin respuesta"
#: skins/default/templates/widgets/scope_nav.html:8
msgid "UNANSWERED"
-msgstr "SIN RESPUESTA"
+msgstr "NUEVOS"
#: skins/default/templates/widgets/scope_nav.html:11
msgid "see your followed questions"
diff --git a/askbot/locale/hr/LC_MESSAGES/django.mo b/askbot/locale/hr/LC_MESSAGES/django.mo
new file mode 100644
index 00000000..b8961c59
--- /dev/null
+++ b/askbot/locale/hr/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/hr/LC_MESSAGES/django.po b/askbot/locale/hr/LC_MESSAGES/django.po
new file mode 100644
index 00000000..c68e27bf
--- /dev/null
+++ b/askbot/locale/hr/LC_MESSAGES/django.po
@@ -0,0 +1,6215 @@
+# English translation for CNPROG package.
+# Copyright (C) 2009 Gang Chen, 2010 Askbot
+# This file is distributed under the same license as the CNPROG package.
+# Evgeny Fadeev <evgeny.fadeev@gmail.com>, 2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.7\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-04-18 18:58-0500\n"
+"PO-Revision-Date: 2013-02-25 12:29+0100\n"
+"Last-Translator: Dario Kolak <dkolak@gmail.com>\n"
+"Language-Team: Croatian <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n!= 1;\n"
+"X-Poedit-Language: Croatian\n"
+"X-Poedit-Country: CROATIA\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#: exceptions.py:13
+msgid "Sorry, but anonymous visitors cannot access this function"
+msgstr "Nažalost anonimni posjetitelji ne mogu koristiti ovu funkciju"
+
+#: feed.py:28
+#: feed.py:90
+msgid " - "
+msgstr " - "
+
+#: feed.py:28
+msgid "Individual question feed"
+msgstr "Kanal pojedinog pitanja"
+
+#: feed.py:90
+msgid "latest questions"
+msgstr "najnovije pitanje"
+
+#: forms.py:74
+msgid "select country"
+msgstr "odaberite državu"
+
+#: forms.py:83
+msgid "Country"
+msgstr "Država"
+
+#: forms.py:91
+msgid "Country field is required"
+msgstr "Polje država je nužno"
+
+#: forms.py:104
+#: skins/default/templates/widgets/answer_edit_tips.html:45
+#: skins/default/templates/widgets/answer_edit_tips.html:49
+#: skins/default/templates/widgets/question_edit_tips.html:40
+#: skins/default/templates/widgets/question_edit_tips.html:45
+msgid "title"
+msgstr "naslov"
+
+#: forms.py:105
+msgid "please enter a descriptive title for your question"
+msgstr "unesite naslov vašeg pitanja"
+
+#: forms.py:113
+#, python-format
+msgid "title must be > %d character"
+msgid_plural "title must be > %d characters"
+msgstr[0] "duljina naslova mora biti > %d znaka"
+msgstr[1] "duljina naslova mora biti > %d znakova"
+
+#: forms.py:123
+#, python-format
+msgid "The title is too long, maximum allowed size is %d characters"
+msgstr "Naslov je predugačak, dozvoljena duljina iznosi %d znakova"
+
+#: forms.py:130
+#, python-format
+msgid "The title is too long, maximum allowed size is %d bytes"
+msgstr "Naslov je predugačak, dozvoljena veličina iznosi %d bajta"
+
+#: forms.py:149
+msgid "content"
+msgstr "sadržaj"
+
+#: forms.py:185
+#: skins/common/templates/widgets/edit_post.html:21
+#: skins/default/templates/widgets/meta_nav.html:5
+msgid "tags"
+msgstr "oznake"
+
+#: forms.py:188
+#, python-format
+msgid "Tags are short keywords, with no spaces within. Up to %(max_tags)d tag can be used."
+msgid_plural "Tags are short keywords, with no spaces within. Up to %(max_tags)d tags can be used."
+msgstr[0] "Oznake su ključne riječi bez razmaka. Možete koristiti do %(max_tags)d oznake."
+msgstr[1] "Oznake su ključne riječi bez razmaka. Možete koristiti do %(max_tags)d oznaka."
+
+#: forms.py:222
+#: skins/default/templates/question_retag.html:58
+msgid "tags are required"
+msgstr "oznake su nužne"
+
+#: forms.py:232
+#, python-format
+msgid "please use %(tag_count)d tag or less"
+msgid_plural "please use %(tag_count)d tags or less"
+msgstr[0] "koristite %(tag_count)d oznaku ili manje"
+msgstr[1] "koristite %(tag_count)d oznaka ili manje"
+
+#: forms.py:240
+#, python-format
+msgid "At least one of the following tags is required : %(tags)s"
+msgstr "Najmanje jedna od sljedećih oznaka je nužna: %(tags)s"
+
+#: forms.py:249
+#, 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] "svaka oznaka mora biti kraća od %(max_chars)d znaka"
+msgstr[1] "svaka oznaka mora biti kraća od %(max_chars)d znakova"
+
+#: forms.py:258
+msgid "In tags, please use letters, numbers and characters \"-+.#\""
+msgstr " \"U oznakama možete koristiti slova, brojeve i znakove \"-+.#\""
+
+#: forms.py:294
+msgid "community wiki (karma is not awarded & many others can edit wiki post)"
+msgstr "wiki zajednica (karma se ne nagrađuje, a drugi korisnici mogu uređivati wiki postove)"
+
+#: forms.py:295
+msgid "if you choose community wiki option, the question and answer do not generate points and name of author will not be shown"
+msgstr "ako odaberete mogućnost wiki zajednica, pitanje i odgovor ne donosi bodove, a ime autora neće biti prikazano"
+
+#: forms.py:311
+msgid "update summary:"
+msgstr "ažuriraj sažetak:"
+
+#: forms.py:312
+msgid "enter a brief summary of your revision (e.g. fixed spelling, grammar, improved style, this field is optional)"
+msgstr "unesite kratak sažetak vaše prerade (npr. ispravljen pravopis, gramatika, stil ..., ovo polje je neobvezno)"
+
+#: forms.py:386
+msgid "Enter number of points to add or subtract"
+msgstr "Unesite broj bodova za dodati ili oduzeti"
+
+#: forms.py:400
+#: const/__init__.py:253
+msgid "approved"
+msgstr "odobren"
+
+#: forms.py:401
+#: const/__init__.py:254
+msgid "watched"
+msgstr "pod nadzorom"
+
+#: forms.py:402
+#: const/__init__.py:255
+msgid "suspended"
+msgstr "suspendiran"
+
+#: forms.py:403
+#: const/__init__.py:256
+msgid "blocked"
+msgstr "blokiran"
+
+#: forms.py:405
+msgid "administrator"
+msgstr "administrator"
+
+#: forms.py:406
+#: const/__init__.py:252
+msgid "moderator"
+msgstr "moderator"
+
+#: forms.py:426
+msgid "Change status to"
+msgstr "Promjeni status u"
+
+#: forms.py:453
+msgid "which one?"
+msgstr "koji"
+
+#: forms.py:474
+msgid "Cannot change own status"
+msgstr "Ne može promijeniti svoj status"
+
+#: forms.py:480
+msgid "Cannot turn other user to moderator"
+msgstr "Ne može promijeniti drugog korisnika u moderatora"
+
+#: forms.py:487
+msgid "Cannot change status of another moderator"
+msgstr "Ne može promijeniti status drugog moderatora"
+
+#: forms.py:493
+msgid "Cannot change status to admin"
+msgstr "Ne može promijeniti status u admin"
+
+#: forms.py:499
+#, python-format
+msgid "If you wish to change %(username)s's status, please make a meaningful selection."
+msgstr "Ako želite promijeniti status korisnika %(username)s , suvislo odaberite."
+
+#: forms.py:508
+msgid "Subject line"
+msgstr "Subjekt linija"
+
+#: forms.py:515
+msgid "Message text"
+msgstr "Tekst poruke"
+
+#: forms.py:530
+msgid "Your name (optional):"
+msgstr "Vaše ime (neobvezno):"
+
+#: forms.py:531
+msgid "Email:"
+msgstr "Email:"
+
+#: forms.py:533
+msgid "Your message:"
+msgstr "Vaša poruka:"
+
+#: forms.py:538
+msgid "I don't want to give my email or receive a response:"
+msgstr "Ne želim dati svoj email i primati odgovore:"
+
+#: forms.py:560
+msgid "Please mark \"I dont want to give my mail\" field."
+msgstr "Označite polje \"Ne želim dati svoj email\" ."
+
+#: forms.py:599
+msgid "ask anonymously"
+msgstr "pitaj anonimno"
+
+#: forms.py:601
+msgid "Check if you do not want to reveal your name when asking this question"
+msgstr "Odaberite ako ne želite da vaše ime bude prikazano"
+
+#: forms.py:624
+msgid "Subject line is expected in the format: [tag1, tag2, tag3,...] question title"
+msgstr "Napišite subjekt u obliku: [oznaka1, oznaka2, oznaka3,...] naslov pitanja"
+
+#: forms.py:769
+msgid "You have asked this question anonymously, if you decide to reveal your identity, please check this box."
+msgstr "Postavili ste pitanje anonimno. Ako odlučite otkriti svoj identitet označite okvir za izbor."
+
+#: forms.py:773
+msgid "reveal identity"
+msgstr "objavi identitet"
+
+#: forms.py:831
+msgid "Sorry, only owner of the anonymous question can reveal his or her identity, please uncheck the box"
+msgstr "Samo vlasnik anonimnog pitanja može objaviti svoj identitet, uklonite oznaku s okvira za izbor"
+
+#: forms.py:844
+msgid "Sorry, apparently rules have just changed - it is no longer possible to ask anonymously. Please either check the \"reveal identity\" box or reload this page and try editing the question again."
+msgstr "Nažalost, pravila su se promijenila - više nije moguće anonimno postavljati pitanje. Označite okvir za izbor \"objavi identitet\" ili učitajte ponovo ovu stranicu i pokušajte ponovo urediti pitanje. "
+
+#: forms.py:888
+msgid "Real name"
+msgstr "Pravo ime"
+
+#: forms.py:895
+msgid "Website"
+msgstr "Web stranica"
+
+#: forms.py:902
+msgid "City"
+msgstr "Grad"
+
+#: forms.py:911
+msgid "Show country"
+msgstr "Prikaži državu"
+
+#: forms.py:916
+msgid "Date of birth"
+msgstr "Datum rođenja"
+
+#: forms.py:917
+msgid "will not be shown, used to calculate age, format: YYYY-MM-DD"
+msgstr "neće biti prikazan, koristi se za izračun godina, oblik: GGGG-MM-DD"
+
+#: forms.py:923
+msgid "Profile"
+msgstr "Profil"
+
+#: forms.py:932
+msgid "Screen name"
+msgstr "Ime na zaslonu"
+
+#: forms.py:963
+#: forms.py:964
+msgid "this email has already been registered, please use another one"
+msgstr "ova email adresa već je registrirana, odaberite drugu"
+
+#: forms.py:971
+msgid "Choose email tag filter"
+msgstr "Odaberite email filter oznaku"
+
+#: forms.py:1018
+msgid "Asked by me"
+msgstr "Moje pitanje"
+
+#: forms.py:1021
+msgid "Answered by me"
+msgstr "Moj odgovor"
+
+#: forms.py:1024
+msgid "Individually selected"
+msgstr "Individualno odabrano"
+
+#: forms.py:1027
+msgid "Entire forum (tag filtered)"
+msgstr "Cjeli forum (filtriran oznakom)"
+
+#: forms.py:1031
+msgid "Comments and posts mentioning me"
+msgstr "Komentari i postovi u kojima se spominjem"
+
+#: forms.py:1112
+msgid "please choose one of the options above"
+msgstr "odaberite jednu od gornjih opcija"
+
+#: forms.py:1115
+msgid "okay, let's try!"
+msgstr "uredu, pokušajmo!"
+
+#: forms.py:1118
+#, python-format
+msgid "no %(sitename)s email please, thanks"
+msgstr "bez %(sitename)s emaila molim, hvala"
+
+#: lamson_handlers.py:126
+#: tests/reply_by_email_tests.py:49
+msgid "======= Reply above this line. ====-=-="
+msgstr "======= Odgovorite iznad ove linije. ========"
+
+#: lamson_handlers.py:130
+msgid "Your message was malformed. Please make sure to qoute the original notification you received at the end of your reply."
+msgstr "Vaša poruka nije ispravno formirana. Provjerite da li ste na kraju vašeg odgovora stavili u navodne znake originalnu obavijest koju ste primili."
+
+#: lamson_handlers.py:147
+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 "Odgovorili ste na email adresu nepoznatu sistemu ili ste odgovorili s različite adrese od one na koju ste primili obavijest."
+
+#: urls.py:41
+msgid "about/"
+msgstr "onama/"
+
+#: urls.py:42
+msgid "faq/"
+msgstr "cpp/"
+
+#: urls.py:43
+msgid "privacy/"
+msgstr "privatnost/"
+
+#: urls.py:44
+msgid "help/"
+msgstr "pomoc/"
+
+#: urls.py:46
+#: urls.py:51
+msgid "answers/"
+msgstr "odgovori/"
+
+#: urls.py:46
+#: urls.py:87
+#: urls.py:212
+msgid "edit/"
+msgstr "uredi/"
+
+#: urls.py:51
+#: urls.py:117
+msgid "revisions/"
+msgstr "revizije/"
+
+#: urls.py:61
+msgid "questions"
+msgstr "pitanja"
+
+#: urls.py:82
+#: urls.py:87
+#: urls.py:92
+#: urls.py:97
+#: urls.py:102
+#: urls.py:107
+#: urls.py:112
+#: urls.py:117
+#: urls.py:123
+#: urls.py:299
+msgid "questions/"
+msgstr "pitanja/"
+
+#: urls.py:82
+msgid "ask/"
+msgstr "pitaj/"
+
+#: urls.py:92
+msgid "retag/"
+msgstr "ponovi_oznaku/"
+
+#: urls.py:97
+msgid "close/"
+msgstr "zatvori/"
+
+#: urls.py:102
+msgid "reopen/"
+msgstr "ponovo_otvori/"
+
+#: urls.py:107
+msgid "answer/"
+msgstr "odgovor/"
+
+#: urls.py:112
+msgid "vote/"
+msgstr "glasaj/"
+
+#: urls.py:123
+msgid "widgets/"
+msgstr "dodatci/"
+
+#: urls.py:158
+msgid "tags/"
+msgstr "oznake/"
+
+#: urls.py:201
+msgid "subscribe-for-tags/"
+msgstr "pretplata-na-oznake/"
+
+#: urls.py:206
+#: urls.py:212
+#: urls.py:218
+#: urls.py:226
+msgid "users/"
+msgstr "korisnici/"
+
+#: urls.py:219
+msgid "subscriptions/"
+msgstr "pretplate/"
+
+#: urls.py:231
+msgid "users/update_has_custom_avatar/"
+msgstr "korisnici/azuriranje_ima_prilagodjen_avatar/"
+
+#: urls.py:236
+#: urls.py:241
+msgid "badges/"
+msgstr "znacke/"
+
+#: urls.py:246
+msgid "messages/"
+msgstr "poruke/"
+
+#: urls.py:246
+msgid "markread/"
+msgstr "procitano/"
+
+#: urls.py:262
+msgid "upload/"
+msgstr "posalji/"
+
+#: urls.py:263
+msgid "feedback/"
+msgstr "povrat/"
+
+#: urls.py:305
+msgid "question/"
+msgstr "pitanje/"
+
+#: urls.py:312
+#: setup_templates/settings.py:210
+#: skins/common/templates/authopenid/providers_javascript.html:7
+msgid "account/"
+msgstr "racun/"
+
+#: conf/access_control.py:8
+msgid "Access control settings"
+msgstr "Postavke za kontrolu pristupa"
+
+#: conf/access_control.py:17
+msgid "Allow only registered user to access the forum"
+msgstr "Dozvoli pristup forumu samo registriranim korisnicima"
+
+#: conf/badges.py:13
+msgid "Badge settings"
+msgstr "Postavke znacki"
+
+#: conf/badges.py:23
+msgid "Disciplined: minimum upvotes for deleted post"
+msgstr "Discipliniran: minimum pozitivnih glasova za obrisane postove"
+
+#: conf/badges.py:32
+msgid "Peer Pressure: minimum downvotes for deleted post"
+msgstr "Pritisak Skupine: minimum negativnih glasova za obrisane postove"
+
+#: conf/badges.py:41
+msgid "Teacher: minimum upvotes for the answer"
+msgstr "Učitelj: minimum pozitivnih glasova za odgovor"
+
+#: conf/badges.py:50
+msgid "Nice Answer: minimum upvotes for the answer"
+msgstr "Lijep odgovor: minimum pozitivnih glasova za odgovor"
+
+#: conf/badges.py:59
+msgid "Good Answer: minimum upvotes for the answer"
+msgstr "Dobar Odgovor: minimum pozitivnih glasova za odgovor"
+
+#: conf/badges.py:68
+msgid "Great Answer: minimum upvotes for the answer"
+msgstr "Odličan odgovor: minimum pozitivnih glasova za odgovor"
+
+#: conf/badges.py:77
+msgid "Nice Question: minimum upvotes for the question"
+msgstr "Lijepo Pitanje: minimum pozitivnih glasova za pitanje"
+
+#: conf/badges.py:86
+msgid "Good Question: minimum upvotes for the question"
+msgstr "Dobro Pitanje: minimum pozitivnih glasova za pitanje"
+
+#: conf/badges.py:95
+msgid "Great Question: minimum upvotes for the question"
+msgstr "Odlično pitanje: minimum pozitivnih glasova za pitanje"
+
+#: conf/badges.py:104
+msgid "Popular Question: minimum views"
+msgstr "Popularno Pitanje: minimum pogleda"
+
+#: conf/badges.py:113
+msgid "Notable Question: minimum views"
+msgstr "Značajno Pitanje: minimum pogleda"
+
+#: conf/badges.py:122
+msgid "Famous Question: minimum views"
+msgstr "Slavno Pitanje: minimum pogleda"
+
+#: conf/badges.py:131
+msgid "Self-Learner: minimum answer upvotes"
+msgstr "Samouk: minimum pozitivnih glasova za odgovor"
+
+#: conf/badges.py:140
+msgid "Civic Duty: minimum votes"
+msgstr "Građanska Dužnost: minimum glasova"
+
+#: conf/badges.py:149
+msgid "Enlightened Duty: minimum upvotes"
+msgstr "Nadahnuta Dužnost: minimum pozitivnih glasova"
+
+#: conf/badges.py:158
+msgid "Guru: minimum upvotes"
+msgstr "Guru: minimum pozitivnih glasova"
+
+#: conf/badges.py:167
+msgid "Necromancer: minimum upvotes"
+msgstr "Čarobnjak: minimum pozitivnih glasova"
+
+#: conf/badges.py:176
+msgid "Necromancer: minimum delay in days"
+msgstr "Čarobnjak: minimum odgoda u danima"
+
+#: conf/badges.py:185
+msgid "Associate Editor: minimum number of edits"
+msgstr "Pomoćnik Urednika: minimalan broj uređivanja"
+
+#: conf/badges.py:194
+msgid "Favorite Question: minimum stars"
+msgstr "Omiljeno Pitanje: minimum zvijezda"
+
+#: conf/badges.py:203
+msgid "Stellar Question: minimum stars"
+msgstr "Zvijezdano Pitanje: minimum zvijezda"
+
+#: conf/badges.py:212
+msgid "Commentator: minimum comments"
+msgstr "Komentator: minimum komentara"
+
+#: conf/badges.py:221
+msgid "Taxonomist: minimum tag use count"
+msgstr "Klasifikator: minimalan broj korištenih oznaka"
+
+#: conf/badges.py:230
+msgid "Enthusiast: minimum days"
+msgstr "Entuzijast: minimum dana"
+
+#: conf/email.py:15
+msgid "Email and email alert settings"
+msgstr "Postavke za email i email upozorenja"
+
+#: conf/email.py:24
+msgid "Prefix for the email subject line"
+msgstr "Prefiks za email subjekt"
+
+#: conf/email.py:26
+msgid "This setting takes default from the django settingEMAIL_SUBJECT_PREFIX. A value entered here will overridethe default."
+msgstr "Ova postavke uzima vrijednost zadanu u django postavci EMAIL_SUBJECT_PREFIX. Unešena vrijednost zamijenit će zadanu vrijednost."
+
+#: conf/email.py:38
+msgid "Enable email alerts"
+msgstr "Omogući upozorenja emailom"
+
+#: conf/email.py:47
+msgid "Maximum number of news entries in an email alert"
+msgstr "Maksimalan broj stavki vijesti u email upozorenju"
+
+#: conf/email.py:57
+msgid "Default notification frequency all questions"
+msgstr "Zadana učestalost obavještavanja za: sva pitanja"
+
+#: conf/email.py:59
+msgid "Option to define frequency of emailed updates for: all questions."
+msgstr "Opcija za definiranje učestalosti primanja email statusa za: sva pitanja"
+
+#: conf/email.py:71
+msgid "Default notification frequency questions asked by the user"
+msgstr "Zadana učestalost obavještavanja za korisnikova pitanja"
+
+#: conf/email.py:73
+msgid "Option to define frequency of emailed updates for: Question asked by the user."
+msgstr "Opcija za definiranje učestalosti primanja email statusa za: Korisnikova pitanja."
+
+#: conf/email.py:85
+msgid "Default notification frequency questions answered by the user"
+msgstr "Zadana učestalost obavještavanja za korisnikova pitanja"
+
+#: conf/email.py:87
+msgid "Option to define frequency of emailed updates for: Question answered by the user."
+msgstr "Opcija za definiranje učestalosti primanja email statusa za: Pitanja odgovorena od strane korisnik."
+
+#: conf/email.py:99
+msgid "Default notification frequency questions individually selected by the user"
+msgstr "Zadana učestalost obavještavanja za pitanja odabrana od strane korisnika"
+
+#: conf/email.py:102
+msgid "Option to define frequency of emailed updates for: Question individually selected by the user."
+msgstr "Opcija za definiranje učestalosti primanja email statusa za: Pitanja izabrana od strane korisnika."
+
+#: conf/email.py:114
+msgid "Default notification frequency for mentions and comments"
+msgstr "Zadana učestalost obavještavanja za spominjanje i komentiranje"
+
+#: conf/email.py:117
+msgid "Option to define frequency of emailed updates for: Mentions and comments."
+msgstr "Opcija za definiranje učestalosti primanja email statusa za: Spominjanje i komentiranje."
+
+#: conf/email.py:128
+msgid "Send periodic reminders about unanswered questions"
+msgstr "Periodno pošalji obavijesti o neodgovorenim pitanjima"
+
+#: conf/email.py:130
+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 "NAPOMENA: da bi koristili ovo svojstvo potrebno je pokrenuti komandu \"send_unanswered_question_reminders\" (npr. putem cron posla - sa prikladnom učestalošću)"
+
+#: conf/email.py:143
+msgid "Days before starting to send reminders about unanswered questions"
+msgstr "Broj dana prije početka slanja obavijesti o neodgovorenim pitanjima"
+
+#: conf/email.py:154
+msgid "How often to send unanswered question reminders (in days between the reminders sent)."
+msgstr "Koliko često slati obavijesti o neodgovorenim pitanjima (u danima između poslanih obavijesti)"
+
+#: conf/email.py:166
+msgid "Max. number of reminders to send about unanswered questions"
+msgstr "Maksimalan broj poslanih obavijesti o neodgovorenim pitanjima"
+
+#: conf/email.py:177
+msgid "Send periodic reminders to accept the best answer"
+msgstr "Periodno pošalji obavijesti za prihvaćanje najboljeg odgovora"
+
+#: conf/email.py:179
+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 "NAPOMENA: da bi koristili ovo svojstvo potrebno je pokrenuti komandu \"send_accept_answer_reminders\" (npr. putem cron posla - sa prikladnom učestalošću)"
+
+#: conf/email.py:192
+msgid "Days before starting to send reminders to accept an answer"
+msgstr "Broj dana prije početka slanja obavijesti za prihvaćanje odgovora"
+
+#: conf/email.py:203
+msgid "How often to send accept answer reminders (in days between the reminders sent)."
+msgstr "Koliko često slati obavijesti za prihvaćanje odgovora (u danima između poslanih obavijesti)"
+
+#: conf/email.py:215
+msgid "Max. number of reminders to send to accept the best answer"
+msgstr "Maksimalan broj poslanih obavijesti za prihvaćanje najboljeg odgovora"
+
+#: conf/email.py:227
+msgid "Require email verification before allowing to post"
+msgstr "Zahtjevaj potvrdu emaila prije dopuštenja objave postova"
+
+#: conf/email.py:228
+msgid "Active email verification is done by sending a verification key in email"
+msgstr "Aktivacija se izvodi slanje potvrdnog ključa u emailu"
+
+#: conf/email.py:237
+msgid "Allow only one account per email address"
+msgstr "Dozvoli smo jedan račun po email adresi"
+
+#: conf/email.py:246
+msgid "Fake email for anonymous user"
+msgstr "Napravi nepostojeći email za anonimne korisnike"
+
+#: conf/email.py:247
+msgid "Use this setting to control gravatar for email-less user"
+msgstr "Koristi ovu postavku za kontrolu gavatara za korisnike bez emaila"
+
+#: conf/email.py:256
+msgid "Allow posting questions by email"
+msgstr "Dozvoli objavu pitanja bez emaila"
+
+#: conf/email.py:258
+msgid "Before enabling this setting - please fill out IMAP settings in the settings.py file"
+msgstr "Prije omogućavanja ove postavke popunite IMAP postavku u settings.py datoteci"
+
+#: conf/email.py:269
+msgid "Replace space in emailed tags with dash"
+msgstr "Zamjeni razmake između oznaka sa crticama u oznakama poslanim emailom"
+
+#: conf/email.py:271
+msgid "This setting applies to tags written in the subject line of questions asked by email"
+msgstr "Ova postavka se odnosi na oznake napisane u subjekt liniji pitanja postavljenog putem emaila."
+
+#: conf/email.py:284
+msgid "Enable posting answers and comments by email"
+msgstr "Omogući objavljivanje odgovora i komentara putem emaila"
+
+#: conf/email.py:287
+msgid "To enable this feature make sure lamson is running"
+msgstr "Prije omogućavanja ovog svojstva provjerite da li lamson radi"
+
+#: conf/email.py:298
+msgid "Reply by email hostname"
+msgstr "Odgovori putem poslužiteljevog emaila"
+
+#: conf/email.py:311
+msgid "Email replies having fewer words than this number will be posted as comments instead of answers"
+msgstr "Email odgovori koji imaju manje riječi od ovog broja biti će objavljeni kao komentari ,a ne kao odgovori"
+
+#: conf/external_keys.py:11
+msgid "Keys for external services"
+msgstr "Ključevi za vanjske servise"
+
+#: conf/external_keys.py:19
+msgid "Google site verification key"
+msgstr "Google potvrdni ključ"
+
+#: conf/external_keys.py:21
+#, python-format
+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 "Ovaj ključ pomaže Google-u indeksirati vašu internet stranicu. Nabavite ga na ovoj <a href=\"%(url)s?hl=%(lang)s\">stranici</a>"
+
+#: conf/external_keys.py:36
+msgid "Google Analytics key"
+msgstr "Google Analytics ključ"
+
+#: 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 "Nabavite ga na <a href=\"%(url)s\">Google Analytics</a> stranici ako želite koristiti Google Analytics za nadgledanje vaše internet stranice. "
+
+#: conf/external_keys.py:51
+msgid "Enable recaptcha (keys below are required)"
+msgstr "Omogući recaptchu (ključevi ispod su obvezni)"
+
+#: conf/external_keys.py:62
+msgid "Recaptcha public key"
+msgstr "Recaptcha javni ključ"
+
+#: conf/external_keys.py:70
+msgid "Recaptcha private key"
+msgstr "Recaptcha privatni ključ"
+
+#: conf/external_keys.py:72
+#, python-format
+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 "Recaptcha je alat koji pomaže odvojiti prave ljude od robota za neželjenu poštu. Javni ključ nabavite ovdje: <a href=\"%(url)s\">%(url)s</a>"
+
+#: conf/external_keys.py:84
+msgid "Facebook public API key"
+msgstr "Facebook javni API ključ"
+
+#: conf/external_keys.py:86
+#, python-format
+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 "Facebook API ključ i Facebook secret omogućuju korištenje Facebook Connect prijave na vašoj stranici. Nabavite ključeve na stranici<a href=\"%(url)s\">kreiraj facebook aplikaciju</a> "
+
+#: conf/external_keys.py:99
+msgid "Facebook secret key"
+msgstr "Facebook tajni ključ"
+
+#: conf/external_keys.py:107
+msgid "Twitter consumer key"
+msgstr "Twitter korisnički ključ"
+
+#: conf/external_keys.py:109
+#, python-format
+msgid "Please register your forum at <a href=\"%(url)s\">twitter applications site</a>"
+msgstr "Registrirajte svoj forum na stranici <a href=\"%(url)s\">twitter aplikacije</a>"
+
+#: conf/external_keys.py:120
+msgid "Twitter consumer secret"
+msgstr "Twitter korisnička tajna"
+
+#: conf/external_keys.py:128
+msgid "LinkedIn consumer key"
+msgstr "LinkedIn korisnički ključ"
+
+#: conf/external_keys.py:130
+#, python-format
+msgid "Please register your forum at <a href=\"%(url)s\">LinkedIn developer site</a>"
+msgstr "Registrirajte svoj forum na stranici <a href=\"%(url)s\">LinkedIn stranica za programere</a>"
+
+#: conf/external_keys.py:141
+msgid "LinkedIn consumer secret"
+msgstr "LinkedIn korisnička tajna"
+
+#: conf/external_keys.py:149
+msgid "ident.ca consumer key"
+msgstr "ident.ca korisnički ključ"
+
+#: conf/external_keys.py:151
+#, python-format
+msgid "Please register your forum at <a href=\"%(url)s\">Identi.ca applications site</a>"
+msgstr "Registrirajte svoj forum na <a href=\"%(url)s\">Identi.ca aplikacije</a>"
+
+#: conf/external_keys.py:162
+msgid "ident.ca consumer secret"
+msgstr "ident.ca korisnički ključ"
+
+#: conf/flatpages.py:11
+msgid "Flatpages - about, privacy policy, etc."
+msgstr "Statične stranice - o nama, pravila o privatnosti, itd."
+
+#: conf/flatpages.py:19
+msgid "Text of the Q&A forum About page (html format)"
+msgstr "Tekst O nama stranice (html format) na P&O forumu"
+
+#: 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 "Spremi, zatim <a href=\"http://validator.w3.org/\">upotrijebi HTML validator</a>\" na \"onama\" stranici radi provjere unosa."
+
+#: conf/flatpages.py:32
+msgid "Text of the Q&A forum FAQ page (html format)"
+msgstr "Tekst ČPP stranice (html format) na P&O forumu"
+
+#: 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 "Spremi, zatim <a href=\"http://validator.w3.org/\">upotrijebi HTML validator</a>\" na \"cpp\" stranici radi provjere unosa."
+
+#: conf/flatpages.py:46
+msgid "Text of the Q&A forum Privacy Policy (html format)"
+msgstr "Tekst stranice Police Privatnosti (html format) na P&O forumu"
+
+#: conf/flatpages.py:49
+msgid "Save, then <a href=\"http://validator.w3.org/\">use HTML validator</a> on the \"privacy\" page to check your input."
+msgstr "Spremi, zatim <a href=\"http://validator.w3.org/\">upotrijebi HTML validator</a>\" na \"privatnost\" stranici radi provjere unosa."
+
+#: conf/forum_data_rules.py:12
+msgid "Data entry and display rules"
+msgstr "Pravila unosa i prikaza podataka"
+
+#: conf/forum_data_rules.py:21
+msgid "Enable embedding videos. "
+msgstr "Omogući umetanje videa"
+
+#: conf/forum_data_rules.py:23
+#, python-format
+msgid "<em>Note: please read <a href=\"%(url)s\">read this</a> first.</em>"
+msgstr "<em>Napomena: prvo pročitajte <a href=\"%(url)s\">ovo</a>.</em>"
+
+#: conf/forum_data_rules.py:33
+msgid "Check to enable community wiki feature"
+msgstr "Označite za omogućavanje svojstva wiki zajednice"
+
+#: conf/forum_data_rules.py:42
+msgid "Allow asking questions anonymously"
+msgstr "Dopusti anonimno postavljanje pitanja"
+
+#: conf/forum_data_rules.py:44
+msgid "Users do not accrue reputation for anonymous questions and their identity is not revealed until they change their mind"
+msgstr "Za objavu anonimnih pitanja korisnicima ne raste ugled, a njihov identitet se ne otkriva dok ne promjene mišljenje"
+
+#: conf/forum_data_rules.py:56
+msgid "Allow posting before logging in"
+msgstr "Dozvoli objavljivanje postova prije prijave"
+
+#: conf/forum_data_rules.py:58
+msgid "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."
+msgstr "Označite ako želite omogućiti objavu pitanja ili odgovora prije prijave. Ova opcija zahtjeva prilagodbu sistema za prijavu korisnika radi provjere postova na čekanju svaki put kad se korisnik prijavi. Askbot sistem za provjeru ima ovo svojstvo."
+
+#: conf/forum_data_rules.py:73
+msgid "Allow swapping answer with question"
+msgstr "Dozvoli zamjenu odgovora sa pitanjem"
+
+#: conf/forum_data_rules.py:75
+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 "Ova postavka pomaže prenijeti podatke s drugih foruma kao što su zendesk, kada automatsko unošenje podataka ne uspije pravilno otkriti originalno pitanje."
+
+#: conf/forum_data_rules.py:87
+msgid "Maximum length of tag (number of characters)"
+msgstr "Maksimalna duljina oznake (broj znakova)"
+
+#: conf/forum_data_rules.py:96
+msgid "Minimum length of title (number of characters)"
+msgstr "Maksimalna duljina naslova (broj znakova)"
+
+#: conf/forum_data_rules.py:106
+msgid "Minimum length of question body (number of characters)"
+msgstr "Maksimalna duljina pitanja (broj znakova)"
+
+#: conf/forum_data_rules.py:117
+msgid "Minimum length of answer body (number of characters)"
+msgstr "Maksimalna duljina odgovora (broj znakova)"
+
+#: conf/forum_data_rules.py:126
+msgid "Are tags required?"
+msgstr "Da li su oznake nužne?"
+
+#: conf/forum_data_rules.py:135
+msgid "Mandatory tags"
+msgstr "Nužne oznake"
+
+#: conf/forum_data_rules.py:138
+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 "Najmanje jedna od ovih oznaka biti će nužna za bilo koje novo ili novo uređeno pitanje. Nužna oznaka može biti višeznačnik, ako su su oznake za višeznačnike aktivne."
+
+#: conf/forum_data_rules.py:150
+msgid "Force lowercase the tags"
+msgstr "Nametni oznake u malim slovima"
+
+#: conf/forum_data_rules.py:152
+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 "Pozor: nakon što ovo označite, napravite kopiju baze podataka i pokrenite komandu: <code>python manage.py fix_question_tags</code> za globalnu promjenu naziva oznaka"
+
+#: conf/forum_data_rules.py:166
+msgid "Format of tag list"
+msgstr "Format liste oznaka"
+
+#: conf/forum_data_rules.py:168
+msgid "Select the format to show tags in, either as a simple list, or as a tag cloud"
+msgstr "Odaberite format prikaza oznaka u obliku jednostavne liste ili oblaka oznaka"
+
+#: conf/forum_data_rules.py:180
+msgid "Use wildcard tags"
+msgstr "Koristi višeznačne oznake"
+
+#: conf/forum_data_rules.py:182
+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 "Višeznačne oznake se mogu koristiti za praćenje ili ignoriranje više oznaka odjednom, ispravna višeznačna oznaka ima jedan višeznačnik na samom kraju"
+
+#: conf/forum_data_rules.py:195
+msgid "Default max number of comments to display under posts"
+msgstr "Zadan maksimalan broj komentara prikazanih ispod postova"
+
+#: conf/forum_data_rules.py:206
+#, python-format
+msgid "Maximum comment length, must be < %(max_len)s"
+msgstr "Maksimalna duljina komentara mora biti < %(max_len)s"
+
+#: conf/forum_data_rules.py:216
+msgid "Limit time to edit comments"
+msgstr "Ograniči vrijeme za uređivanje komentara"
+
+#: conf/forum_data_rules.py:218
+msgid "If unchecked, there will be no time limit to edit the comments"
+msgstr "Ako nije označeno, vrijeme za uređivanje komentara neće biti ograničeno"
+
+#: conf/forum_data_rules.py:229
+msgid "Minutes allowed to edit a comment"
+msgstr "Dozvoljen broj minuta za uređivanje komentara"
+
+#: conf/forum_data_rules.py:230
+msgid "To enable this setting, check the previous one"
+msgstr "Za omogućavanje ove postavke označite prethodni"
+
+#: conf/forum_data_rules.py:239
+msgid "Save comment by pressing <Enter> key"
+msgstr "Sačuvajte komentar pritiskom tipke <Enter>"
+
+#: conf/forum_data_rules.py:248
+msgid "Minimum length of search term for Ajax search"
+msgstr "Minimalna duljina traženog pojma za Ajax pretragu"
+
+#: conf/forum_data_rules.py:249
+msgid "Must match the corresponding database backend setting"
+msgstr "Mora odgovarati pozadinskoj postavci baze podataka"
+
+#: conf/forum_data_rules.py:258
+msgid "Do not make text query sticky in search"
+msgstr "U pretrazi ne pravi tekstualni upit ljepljivim"
+
+#: conf/forum_data_rules.py:260
+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 "Označite za deaktiviviranje \"ljepljivog\" ponašanja za traženi upit. Ovo može biti korisno ako želite promijeniti prostor za pretraživanje izvan zadanog položaja ili vam se ne sviđa zadano ljepljivo ponašanje tekstualnog upita"
+
+#: conf/forum_data_rules.py:273
+msgid "Maximum number of tags per question"
+msgstr "Maksimalan broj oznaka po pitanju"
+
+#: conf/forum_data_rules.py:285
+msgid "Number of questions to list by default"
+msgstr "Zadan broj pitanja na listi"
+
+#: conf/forum_data_rules.py:295
+msgid "What should \"unanswered question\" mean?"
+msgstr "Što bi \"neodgovoreno ptanje\" trebalo značiti?"
+
+#: conf/ldap.py:9
+msgid "LDAP login configuration"
+msgstr "Konfiguracija LDAP prijave"
+
+#: conf/ldap.py:17
+msgid "Use LDAP authentication for the password login"
+msgstr "Koristi LDAP provjeru valjanosti za prijavu lozinkom"
+
+#: conf/ldap.py:26
+msgid "LDAP URL"
+msgstr "LDAP URL"
+
+#: conf/ldap.py:35
+msgid "LDAP BASE DN"
+msgstr "LDAP BASE DN"
+
+#: conf/ldap.py:43
+msgid "LDAP Search Scope"
+msgstr "LDAP Raspon Pretrage"
+
+#: conf/ldap.py:52
+msgid "LDAP Server USERID field name"
+msgstr "LDAP Server USERID naziv polja"
+
+#: conf/ldap.py:61
+msgid "LDAP Server \"Common Name\" field name"
+msgstr "LDAP Server \"Uobičajeno Ime\" naziv polja "
+
+#: conf/ldap.py:70
+msgid "LDAP Server EMAIL field name"
+msgstr "LDAP Server EMAIL naziv polja"
+
+#: conf/leading_sidebar.py:12
+msgid "Common left sidebar"
+msgstr "Uobičajeni lijevi rubni stupac"
+
+#: conf/leading_sidebar.py:20
+msgid "Enable left sidebar"
+msgstr "Omogući lijevi rubni stupac"
+
+#: conf/leading_sidebar.py:29
+msgid "HTML for the left sidebar"
+msgstr "HTML za lijevi rubni stupac"
+
+#: 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 "Koristi ovo područje za unos sadržaja u LIJEVOM rubnom stupcu u HTML formatu. Prilikom korištenja ove mogućnosti koristite HTML validator kako bi ste provjerili da je vaš unos ispravan te da je prikaz ispravan u u svim preglednicima."
+
+#: conf/license.py:13
+msgid "Content License"
+msgstr "Licenca sadržaja"
+
+#: conf/license.py:21
+msgid "Show license clause in the site footer"
+msgstr "Prikaži klauzulu licence u podnožju stranice"
+
+#: conf/license.py:30
+msgid "Short name for the license"
+msgstr "Kratko ime licence"
+
+#: conf/license.py:39
+msgid "Full name of the license"
+msgstr "Puno ime licence"
+
+#: conf/license.py:40
+msgid "Creative Commons Attribution Share Alike 3.0"
+msgstr "Creative Commons Attribution Share Alike 3.0"
+
+#: conf/license.py:48
+msgid "Add link to the license page"
+msgstr "Napravi vezu na stranicu licence"
+
+#: conf/license.py:57
+msgid "License homepage"
+msgstr "Početna stranica licence"
+
+#: conf/license.py:59
+msgid "URL of the official page with all the license legal clauses"
+msgstr "URL službene stranice sa svim klauzulama licence"
+
+#: conf/license.py:69
+msgid "Use license logo"
+msgstr "Koristi logo licence"
+
+#: conf/license.py:78
+msgid "License logo image"
+msgstr "Slika loga licence"
+
+#: conf/login_providers.py:13
+msgid "Login provider setings"
+msgstr "Postavke za pružatelja prijave"
+
+#: conf/login_providers.py:22
+msgid "Show alternative login provider buttons on the password \"Sign Up\" page"
+msgstr "Na stranici \"Prijava\" prikaži gumb za alternativne pružatelje prijave"
+
+#: conf/login_providers.py:31
+msgid "Always display local login form and hide \"Askbot\" button."
+msgstr "Uvijek prikaži lokalni prijavni obrazac i sakri \"Askbot\" gumb."
+
+#: conf/login_providers.py:40
+msgid "Activate to allow login with self-hosted wordpress site"
+msgstr "Aktiviraj za dopuštenje prijave sa svoje wordpress internet stranice"
+
+#: conf/login_providers.py:41
+msgid "to activate this feature you must fill out the wordpress xml-rpc setting bellow"
+msgstr "za aktiviranje ovog svojstva morate popuniti wordpress xml-rpc postavke ispod"
+
+#: conf/login_providers.py:50
+msgid "Fill it with the wordpress url to the xml-rpc, normally http://mysite.com/xmlrpc.php"
+msgstr "Popunite sa wordpress url-om na xml-rpc, uobičajeno http://mojastranica.hr/xmlrpc.php"
+
+#: conf/login_providers.py:51
+msgid "To enable, go to Settings->Writing->Remote Publishing and check the box for XML-RPC"
+msgstr "Za omogućavanje idite na Settings->Writing->Remote Publishing i označite okvir za izbor za XML-RPC"
+
+#: conf/login_providers.py:60
+msgid "Upload your icon"
+msgstr "Pošaljite vašu ikonu"
+
+#: conf/login_providers.py:90
+#, python-format
+msgid "Activate %(provider)s login"
+msgstr "Aktivirajte %(provider)s prijavu"
+
+#: conf/login_providers.py:95
+#, python-format
+msgid "Note: to really enable %(provider)s login some additional parameters will need to be set in the \"External keys\" section"
+msgstr "Napomena: za omogućavanje %(provider)s prijave potrebno je podesiti dodatne parametre u dijelu \"Vanjski ključevi\""
+
+#: conf/markup.py:15
+msgid "Markup in posts"
+msgstr "Obilježja u postovima"
+
+#: conf/markup.py:41
+msgid "Enable code-friendly Markdown"
+msgstr "Omogućite prijateljski kod Markdown"
+
+#: conf/markup.py:43
+msgid "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."
+msgstr "Ako je označeno, znakovi podvlačenja neće aktivirati kurziv ili podebljano formatiranje - podebljan i kurziv tekst se mogu označiti sa zvjezdicama. Napomena da \"MathJax podrška\" implicitno uključuje ovo svojstvo zato što se znakovi podvlačenja puno koriste u LaTeX unosu."
+
+#: conf/markup.py:58
+msgid "Mathjax support (rendering of LaTeX)"
+msgstr "Podrška za Mathjax (izvođenje LaTeXa)"
+
+#: 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 "Ako omogućite ovo svojstvo, <a href=\"%(url)s\">mathjax</a> mora biti instaliran na vašem poslužitelju u svojem direktoriju."
+
+#: conf/markup.py:74
+msgid "Base url of MathJax deployment"
+msgstr "Osnovni url MathJax implementacije"
+
+#: 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 "Napomena - <strong>MathJax nije uključen u askbot</strong> - trebate ga sami instalirati. po mogućnosti na drugoj domeni i unijeti url koji pokazuje na \"mathjax\" direktorij (npr. http://mojastranica.hr/mathjax)"
+
+#: conf/markup.py:91
+msgid "Enable autolinking with specific patterns"
+msgstr "Omogući automatsko spajanje s pojedinim obrazcima"
+
+#: conf/markup.py:93
+msgid "If you enable this feature, the application will be able to detect patterns and auto link to URLs"
+msgstr "Ako omogućite ovo svojstvo aplikacija će moći pronaći obrazce i automatski spojiti s URL-ovima"
+
+#: conf/markup.py:106
+msgid "Regexes to detect the link patterns"
+msgstr "Regularni izrazi za pronalazak veze na obrazce"
+
+#: conf/markup.py:108
+msgid "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."
+msgstr "Unesite ispravan regularni izraz za obrazac, jedan po liniji. Na primjer za pronalazak greške obrasca kao #bug123 koristite sljedeći regularni izraz: #bug(\\d+). Brojevi unutar zagrada obrasca biti će pretvoreni u url vezu na predložak. Za više informacija o regularnim izrazima pogledajte drugdje."
+
+#: conf/markup.py:127
+msgid "URLs for autolinking"
+msgstr "URL-ovi za automatsko spajanje"
+
+#: conf/markup.py:129
+msgid "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."
+msgstr "Unesite url predložaka za obrasce unijete u prethodnoj postavci, također jednu po liniji. <strong>Provjerite da li je broj linija u ovoj postavci jednak broju u prethodnoj</strong>. Naprimjer predložak https://bugzilla.redhat.com/show_bug.cgi?id=\\1 zajedno s obrascem prikazanim iznad i unosom u postu #123, kreirati će vezu na grešku 123 u redhat sistemu za praćenje greški."
+
+#: conf/minimum_reputation.py:12
+msgid "Karma thresholds"
+msgstr "Granice karme"
+
+#: conf/minimum_reputation.py:22
+msgid "Upvote"
+msgstr "Pozitivan glas"
+
+#: conf/minimum_reputation.py:31
+msgid "Downvote"
+msgstr "Negativan glas"
+
+#: conf/minimum_reputation.py:40
+msgid "Answer own question immediately"
+msgstr "Odmah odgovorite na svoje pitanje"
+
+#: conf/minimum_reputation.py:49
+msgid "Accept own answer"
+msgstr "Prihvatite svoj odgovor"
+
+#: conf/minimum_reputation.py:58
+msgid "Flag offensive"
+msgstr "Označi kao uvredljivo"
+
+#: conf/minimum_reputation.py:67
+msgid "Leave comments"
+msgstr "Ostavi komentara"
+
+#: conf/minimum_reputation.py:76
+msgid "Delete comments posted by others"
+msgstr "Obriši komentare drugih korisnika"
+
+#: conf/minimum_reputation.py:85
+msgid "Delete questions and answers posted by others"
+msgstr "Obriši pitanja i odgovore drugih korisnika"
+
+#: conf/minimum_reputation.py:94
+msgid "Upload files"
+msgstr "Pošaljite datoteke"
+
+#: conf/minimum_reputation.py:103
+msgid "Close own questions"
+msgstr "Zatvorite svoja pitanja"
+
+#: conf/minimum_reputation.py:112
+msgid "Retag questions posted by other people"
+msgstr "Ponovo označi pitanja drugih korisnika"
+
+#: conf/minimum_reputation.py:121
+msgid "Reopen own questions"
+msgstr "Ponovo otvori svoja pitanja"
+
+#: conf/minimum_reputation.py:130
+msgid "Edit community wiki posts"
+msgstr "Uređivanje postova wiki zajednice"
+
+#: conf/minimum_reputation.py:139
+msgid "Edit posts authored by other people"
+msgstr "Uređivanje postova drugih korisnika "
+
+#: conf/minimum_reputation.py:148
+msgid "View offensive flags"
+msgstr "Pregled uvredljivih oznaka"
+
+#: conf/minimum_reputation.py:157
+msgid "Close questions asked by others"
+msgstr "Zatvori pitanja drugih korisnika"
+
+#: conf/minimum_reputation.py:166
+msgid "Lock posts"
+msgstr "Zaključaj postove"
+
+#: conf/minimum_reputation.py:175
+msgid "Remove rel=nofollow from own homepage"
+msgstr "Ukloni rel=nofollow sa svoje početne stranice"
+
+#: conf/minimum_reputation.py:177
+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 "Kada pauk tražilice vidi rel=nofollow atribut na a vezi - veza neće važiti za rangiranje osobne internet stranice korisnika."
+
+#: conf/minimum_reputation.py:190
+msgid "Post answers and comments by email"
+msgstr "Objavi odgovore i komentare putem emaila"
+
+#: conf/reputation_changes.py:13
+msgid "Karma loss and gain rules"
+msgstr "Pravila za dobivanje i gubljenje karme"
+
+#: conf/reputation_changes.py:23
+msgid "Maximum daily reputation gain per user"
+msgstr "Maksimalna dnevna količina dobivenog ugleda po korisniku"
+
+#: conf/reputation_changes.py:32
+msgid "Gain for receiving an upvote"
+msgstr "Dobit za primanje pozitivnog glasa"
+
+#: conf/reputation_changes.py:41
+msgid "Gain for the author of accepted answer"
+msgstr "Dobit za autora prihvaćenog odgovora"
+
+#: conf/reputation_changes.py:50
+msgid "Gain for accepting best answer"
+msgstr "Dobit za prihvaćanje najboljeg odgovora"
+
+#: conf/reputation_changes.py:59
+msgid "Gain for post owner on canceled downvote"
+msgstr "Dobit za vlasnika posta na obustavljenom negativnom glasu"
+
+#: conf/reputation_changes.py:68
+msgid "Gain for voter on canceling downvote"
+msgstr "Dobit za glasača na obustavljenom negativnom glasu"
+
+#: conf/reputation_changes.py:78
+msgid "Loss for voter for canceling of answer acceptance"
+msgstr "Gubitak za glasača za obustavljanje prihvaćanja odgovora"
+
+#: conf/reputation_changes.py:88
+msgid "Loss for author whose answer was \"un-accepted\""
+msgstr "Gubitak za glasača čiji odgovor je bio \"neprihvacen\""
+
+#: conf/reputation_changes.py:98
+msgid "Loss for giving a downvote"
+msgstr "Gubitak za davanje negativnog glasa"
+
+#: conf/reputation_changes.py:108
+msgid "Loss for owner of post that was flagged offensive"
+msgstr "Gubitak za vlasnika posta označenog kao uvredljiv"
+
+#: conf/reputation_changes.py:118
+msgid "Loss for owner of post that was downvoted"
+msgstr "Gubitak za vlasnika posta koji je dobio negativan glas"
+
+#: conf/reputation_changes.py:128
+msgid "Loss for owner of post that was flagged 3 times per same revision"
+msgstr "Gubitak za vlasnika posta koji je označen 3 puta po istoj reviziji"
+
+#: conf/reputation_changes.py:138
+msgid "Loss for owner of post that was flagged 5 times per same revision"
+msgstr "Gubitak za vlasnika posta koji je označen 5 puta po istoj reviziji"
+
+#: conf/reputation_changes.py:148
+msgid "Loss for post owner when upvote is canceled"
+msgstr "Gubitak za vlasnika posta kada je pozitivan glas obustavljen"
+
+#: conf/sidebar_main.py:12
+msgid "Main page sidebar"
+msgstr "Rubni stupac glavne stranice"
+
+#: conf/sidebar_main.py:20
+#: conf/sidebar_profile.py:20
+#: conf/sidebar_question.py:19
+msgid "Custom sidebar header"
+msgstr "Prilagođeno zaglavlje rubnog stupca"
+
+#: conf/sidebar_main.py:23
+#: conf/sidebar_profile.py:23
+#: conf/sidebar_question.py:22
+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 validation service to make sure that your input is valid and works well in all browsers."
+msgstr "Koristi ovo područje za unos sadržaja u GORNJEM DIJELU rubnog stupca u HTML formatu. Prilikom korištenja ove mogućnosti koristite HTML validator kako bi ste provjerili da je vaš unos ispravan te da je prikaz ispravan u u svim preglednicima."
+
+#: conf/sidebar_main.py:36
+msgid "Show avatar block in sidebar"
+msgstr "Prikaži blok avatara u rubnom stupcu"
+
+#: conf/sidebar_main.py:38
+msgid "Uncheck this if you want to hide the avatar block from the sidebar "
+msgstr "Uklonite oznaku ako želite sakriti blok avatara u rubnom stupcu"
+
+#: conf/sidebar_main.py:49
+msgid "Limit how many avatars will be displayed on the sidebar"
+msgstr "Limitiraj koliko će avatara biti prikazano u rubnom stupcu"
+
+#: conf/sidebar_main.py:59
+msgid "Show tag selector in sidebar"
+msgstr "Prikaži izbornik oznaka u rubnom stupcu"
+
+#: conf/sidebar_main.py:61
+msgid "Uncheck this if you want to hide the options for choosing interesting and ignored tags "
+msgstr "Uklonite oznaku ako želite sakriti mogućnost za odabiranje zanimljivih i ignoriranih oznaka"
+
+#: conf/sidebar_main.py:72
+msgid "Show tag list/cloud in sidebar"
+msgstr "Prikaži listu/oblak oznaka u rubnom stupcu"
+
+#: conf/sidebar_main.py:74
+msgid "Uncheck this if you want to hide the tag cloud or tag list from the sidebar "
+msgstr "Ukloni oznaku ako želite sakriti listu ili oblak oznaka iz rubnog stupca"
+
+#: conf/sidebar_main.py:85
+#: conf/sidebar_profile.py:36
+#: conf/sidebar_question.py:75
+msgid "Custom sidebar footer"
+msgstr "Prilagođeno podnožje rubnog stupca"
+
+#: conf/sidebar_main.py:88
+#: conf/sidebar_profile.py:39
+#: conf/sidebar_question.py:78
+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 validation service to make sure that your input is valid and works well in all browsers."
+msgstr "Koristi ovo područje za unos sadržaja u DONJEM DIJELU rubnog stupca u HTML formatu. Prilikom korištenja ove mogućnosti koristite HTML validator kako bi ste provjerili da je vaš unos ispravan te da je prikaz ispravan u svim preglednicima."
+
+#: conf/sidebar_profile.py:12
+msgid "User profile sidebar"
+msgstr "Rubni stupac korisničkog profila"
+
+#: conf/sidebar_question.py:11
+msgid "Question page sidebar"
+msgstr "Rubni stupac stranice Pitanja"
+
+#: conf/sidebar_question.py:35
+msgid "Show tag list in sidebar"
+msgstr "Prikaži listu oznaka u rubnom stupcu"
+
+#: conf/sidebar_question.py:37
+msgid "Uncheck this if you want to hide the tag list from the sidebar "
+msgstr "Uklonite oznaku ako želite sakriti listu oznaka iz rubnog stupca"
+
+#: conf/sidebar_question.py:48
+msgid "Show meta information in sidebar"
+msgstr "Prikaži meta informacije u rubnom stupcu"
+
+#: conf/sidebar_question.py:50
+msgid "Uncheck this if you want to hide the meta information about the question (post date, views, last updated). "
+msgstr "Uklonite oznaku ako želite sakriti meta informacije o pitanju (datum objave, preglede, zadnje ažuriranje)."
+
+#: conf/sidebar_question.py:62
+msgid "Show related questions in sidebar"
+msgstr "Prikaži slična pitanja u rubnom stupcu"
+
+#: conf/sidebar_question.py:64
+msgid "Uncheck this if you want to hide the list of related questions. "
+msgstr "Uklonite oznaku ako želite sakriti listu sličnih pitanja."
+
+#: conf/site_modes.py:64
+msgid "Bootstrap mode"
+msgstr "Bootstrap način"
+
+#: conf/site_modes.py:74
+msgid "Activate a \"Bootstrap\" mode"
+msgstr "Aktivirajte \"Bootstarp\" način"
+
+#: conf/site_modes.py:76
+msgid "Bootstrap mode lowers reputation and certain badge thresholds, to values, more suitable for the smaller communities, <strong>WARNING:</strong> your current value for Minimum reputation, Bagde Settings and Vote Rules will be changed after you modify this setting."
+msgstr "Bootstrap način smanjuje ugled i određene postavke za značke na vrijednosti prilagođene manjim zajednicama <strong>OPREZ:</strong> vaše trenutne vrijednosti za Minimum ugleda, Postavke Znački i Pravila Glasanja promjenit će se nakon što promjenite ovu postavku."
+
+#: conf/site_settings.py:12
+msgid "URLS, keywords & greetings"
+msgstr "URL-ovi, ključne riječi i pozdravi"
+
+#: conf/site_settings.py:21
+msgid "Site title for the Q&A forum"
+msgstr "Naslov stranice za P&O forum"
+
+#: conf/site_settings.py:30
+msgid "Comma separated list of Q&A site keywords"
+msgstr "Lista ključnih riječi odvojenih zarezom za P&O stranicu"
+
+#: conf/site_settings.py:39
+msgid "Copyright message to show in the footer"
+msgstr "Poruka o autorskim pravima prikazana u podnožju stranice"
+
+#: conf/site_settings.py:49
+msgid "Site description for the search engines"
+msgstr "Opis internet stranice za tražilice"
+
+#: conf/site_settings.py:58
+msgid "Short name for your Q&A forum"
+msgstr "Kratko ime za vaš P&O forum"
+
+#: conf/site_settings.py:67
+msgid "Base URL for your Q&A forum, must start with http or https"
+msgstr "Osnovni URL za vaš P&O forum, mora početi s http ili https"
+
+#: conf/site_settings.py:78
+msgid "Check to enable greeting for anonymous user"
+msgstr "Označite za omogućavanje pozdrava anonimnog korisnika"
+
+#: conf/site_settings.py:89
+msgid "Text shown in the greeting message shown to the anonymous user"
+msgstr "Tekst prikazan u pozdravnoj poruci za anonimnog korisnika"
+
+#: conf/site_settings.py:93
+msgid "Use HTML to format the message "
+msgstr "Koristi HTML format poruke"
+
+#: conf/site_settings.py:102
+msgid "Feedback site URL"
+msgstr "URL stranice sa povratnom informacijom"
+
+#: conf/site_settings.py:104
+msgid "If left empty, a simple internal feedback form will be used instead"
+msgstr "Ako se ostavi prazno biti će korišten jednostavan obrazac za povratnu informaciju"
+
+#: conf/skin_counter_settings.py:11
+msgid "Skin: view, vote and answer counters"
+msgstr "Tema: brojači pregleda, glasova i odgovora"
+
+#: conf/skin_counter_settings.py:19
+msgid "Vote counter value to give \"full color\""
+msgstr "Vrijednost brojača glasova za dodjeljivanje \"pune boje\""
+
+#: conf/skin_counter_settings.py:29
+msgid "Background color for votes = 0"
+msgstr "Pozadinska boja za glasove = 0"
+
+#: conf/skin_counter_settings.py:30
+#: conf/skin_counter_settings.py:41
+#: conf/skin_counter_settings.py:52
+#: conf/skin_counter_settings.py:62
+#: conf/skin_counter_settings.py:72
+#: conf/skin_counter_settings.py:85
+#: conf/skin_counter_settings.py:106
+#: conf/skin_counter_settings.py:117
+#: conf/skin_counter_settings.py:128
+#: conf/skin_counter_settings.py:138
+#: conf/skin_counter_settings.py:148
+#: conf/skin_counter_settings.py:163
+#: conf/skin_counter_settings.py:186
+#: conf/skin_counter_settings.py:196
+#: conf/skin_counter_settings.py:206
+#: conf/skin_counter_settings.py:216
+#: conf/skin_counter_settings.py:228
+#: conf/skin_counter_settings.py:239
+#: conf/skin_counter_settings.py:252
+#: conf/skin_counter_settings.py:262
+msgid "HTML color name or hex value"
+msgstr "HTML naziv boje ili hex vrijednost"
+
+#: conf/skin_counter_settings.py:40
+msgid "Foreground color for votes = 0"
+msgstr "Primarna boja za glasove = 0"
+
+#: conf/skin_counter_settings.py:51
+msgid "Background color for votes"
+msgstr "Boja pozadine za glasove"
+
+#: conf/skin_counter_settings.py:61
+msgid "Foreground color for votes"
+msgstr "Primarna boja za glasove"
+
+#: conf/skin_counter_settings.py:71
+msgid "Background color for votes = MAX"
+msgstr "Boja pozadine za glasove = MAX"
+
+#: conf/skin_counter_settings.py:84
+msgid "Foreground color for votes = MAX"
+msgstr "Primarna boja za glasove = MAX"
+
+#: conf/skin_counter_settings.py:95
+msgid "View counter value to give \"full color\""
+msgstr "Vrijednost brojača pregleda za dodjeljivanje \"pune boje\""
+
+#: conf/skin_counter_settings.py:105
+msgid "Background color for views = 0"
+msgstr "Boja pozadine za preglede = 0"
+
+#: conf/skin_counter_settings.py:116
+msgid "Foreground color for views = 0"
+msgstr "Primarna boja za preglede = 0"
+
+#: conf/skin_counter_settings.py:127
+msgid "Background color for views"
+msgstr "Boja pozadine za za preglede"
+
+#: conf/skin_counter_settings.py:137
+msgid "Foreground color for views"
+msgstr "Primarna boja za preglede"
+
+#: conf/skin_counter_settings.py:147
+msgid "Background color for views = MAX"
+msgstr "Boja pozadine za preglede = MAX"
+
+#: conf/skin_counter_settings.py:162
+msgid "Foreground color for views = MAX"
+msgstr "Primarna boja za preglede = MAX"
+
+#: conf/skin_counter_settings.py:173
+msgid "Answer counter value to give \"full color\""
+msgstr "Vrijednost brojača odgovora za dodjeljivanje \"pune boje\""
+
+#: conf/skin_counter_settings.py:185
+msgid "Background color for answers = 0"
+msgstr "Boja pozadine za odgovore = 0"
+
+#: conf/skin_counter_settings.py:195
+msgid "Foreground color for answers = 0"
+msgstr "Primarna boja za odgovore = 0"
+
+#: conf/skin_counter_settings.py:205
+msgid "Background color for answers"
+msgstr "Boja pozadine za odgovore "
+
+#: conf/skin_counter_settings.py:215
+msgid "Foreground color for answers"
+msgstr "Primarna boja za odgovore"
+
+#: conf/skin_counter_settings.py:227
+msgid "Background color for answers = MAX"
+msgstr "Boja pozadine za odgovore = MAX"
+
+#: conf/skin_counter_settings.py:238
+msgid "Foreground color for answers = MAX"
+msgstr "Primarna boja za odgovore = MAX"
+
+#: conf/skin_counter_settings.py:251
+msgid "Background color for accepted"
+msgstr "Boja pozadine za prihaćene"
+
+#: conf/skin_counter_settings.py:261
+msgid "Foreground color for accepted answer"
+msgstr "Primarna boja za prihvaćene odgovora"
+
+#: conf/skin_general_settings.py:15
+msgid "Logos and HTML <head> parts"
+msgstr "Logo i HTML <head> dijelovi"
+
+#: conf/skin_general_settings.py:23
+msgid "Q&A site logo"
+msgstr "Logo P&O stranice"
+
+#: conf/skin_general_settings.py:25
+msgid "To change the logo, select new file, then submit this whole form."
+msgstr "Za promjenu loga odaberite novu datoteku zatim podnesite cjeli obrazac."
+
+#: conf/skin_general_settings.py:37
+msgid "Show logo"
+msgstr "Prikaži logo"
+
+#: conf/skin_general_settings.py:39
+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 "Označite ako želite da logo bude u zaglavlju foruma ili uklonite oznaku ako ne želite da logo bude prikazan na zadanom mjestu"
+
+#: conf/skin_general_settings.py:51
+msgid "Site favicon"
+msgstr "Favicon stranice"
+
+#: conf/skin_general_settings.py:53
+#, python-format
+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 "Mala ikona veličine 16x16 ili 32x32 piksela koja se koristi za razlikovanje vaše stranice u pregledniku. Pronađite više informacija o faviconu na <a href=\"%(favicon_info_url)s\">ovoj stranici</a>."
+
+#: conf/skin_general_settings.py:69
+msgid "Password login button"
+msgstr "Gumb za prijavu lozinkom"
+
+#: conf/skin_general_settings.py:71
+msgid "An 88x38 pixel image that is used on the login screen for the password login button."
+msgstr "Slika veličine 88x38 piksela koja se koristi na prijavnom zaslonu za gumb za prijavu lozinkom"
+
+#: conf/skin_general_settings.py:84
+msgid "Show all UI functions to all users"
+msgstr "Prikaži sve UI funkcije svim korisnicima"
+
+#: conf/skin_general_settings.py:86
+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 "U slučaju odabira sve funkcije foruma biti će prikazane korisnicima bez obzira na njihov ugled, ali za korištenje tih funkcija, moderatorskih pravila, ugleda i ostalog, ograničenja će se i dalje primjenjivati"
+
+#: conf/skin_general_settings.py:101
+msgid "Select skin"
+msgstr "Odaberite temu"
+
+#: conf/skin_general_settings.py:112
+msgid "Customize HTML <HEAD>"
+msgstr "Prilagodi HTML <HEAD>"
+
+#: conf/skin_general_settings.py:121
+msgid "Custom portion of the HTML <HEAD>"
+msgstr "Prilagođen dio HTML <HEAD>"
+
+#: conf/skin_general_settings.py:123
+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 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."
+msgstr "<strong>Za korištenje ove mogućnosti</strong>, označite \"Prilagodi HTML &lt;HEAD&gt;\" gore. Sadržaj u kvadratu biti će ugrađen u &lt;HEAD&gt; dio HTML koda, gdje elementi kao što su &lt;script&gt;, &lt;link&gt;, &lt;meta&gt; mogu biti dodani. Imajte na umu da se dodavanje vanjske javascript datoteke u &lt;HEAD&gt; se ne preporučuje jer usporava učitavanje stranice. Efikasnije je staviti veze na javascript datoteke u podnožje stranice. <strong>Napomena:</strong> ako ćete koristiti ovu postavku, testirajte stranicu sa W3C HTML validatorom."
+
+#: conf/skin_general_settings.py:145
+msgid "Custom header additions"
+msgstr "Dodatci prilagođenog zaglavlja"
+
+#: conf/skin_general_settings.py:147
+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 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 "Zaglavlje je dio na vrhu sadržaja koji sadrži podatke o korisniku i poveznice na druge stranice te je uobičajen na svim stranicama. Koristite ovo područje za unos sadržaja zaglavlja u HTML formatu. Prilikom prilagodbe zaglavlja stranice (kao i podnožja i HTML &lt;HEAD&gt;) koristite HTML validator da bi ste provjerili da unos ispravno radi u svim preglednicima."
+
+#: conf/skin_general_settings.py:162
+msgid "Site footer mode"
+msgstr "Mod podnožja stranice"
+
+#: conf/skin_general_settings.py:164
+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 "Podnožje je donji dio sadržaja uobičajen svim stanicama. Možete onemogućiti, prilagoditi ili koristiti zadano podnožje."
+
+#: conf/skin_general_settings.py:181
+msgid "Custom footer (HTML format)"
+msgstr "Prilagđeno podnožje (HTML format)"
+
+#: conf/skin_general_settings.py:183
+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 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 "<strong>Za korištenje ove mogućnosti</strong>, označite \"Mod podnožja stranice\" gore. Koristite ovo područje za unos sadržaja podnožja u HTML formatu. Prilikom prilagođavanja podnožja stranice (kao i zaglavlja i HTML &lt;HEAD&gt;), koristite HTML validator da bi ste provjerili da unos ispravno radi u svim preglednicima."
+
+#: conf/skin_general_settings.py:198
+msgid "Apply custom style sheet (CSS)"
+msgstr "Primjeni prilagođenu listu stilova (CSS)"
+
+#: conf/skin_general_settings.py:200
+msgid "Check if you want to change appearance of your form by adding custom style sheet rules (please see the next item)"
+msgstr "Označite ako želite promjeniti izgled vašeg foruma dodavanjem prilagođene liste stilova (pogledajte sljedeću stavku)"
+
+#: conf/skin_general_settings.py:212
+msgid "Custom style sheet (CSS)"
+msgstr "Prilagođena lista stilova (CSS)"
+
+#: conf/skin_general_settings.py:214
+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 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 "<strong>Za korištenje ove funkcije</strong> označite \"Primjeni prilagođenu listu stilova (CSS)\" gore. CSS pravila dodana u ovom prozoru će se primijeniti nakon zadane liste stilova. Prilagođena lista stilova izvršavati će se dinamički na url-u \"&lt;forum url&gt;/custom.css\" gdje \"&lt;forum url&gt; dio ovisi (zadan je prazan niz) o url konfiguraciji urls.py datotke. "
+
+#: conf/skin_general_settings.py:230
+msgid "Add custom javascript"
+msgstr "Dodaj prilagođen javascript"
+
+#: conf/skin_general_settings.py:233
+msgid "Check to enable javascript that you can enter in the next field"
+msgstr "Označite za omogućavanje javascripta koji možete unijeti u sljedećem polju"
+
+#: conf/skin_general_settings.py:243
+msgid "Custom javascript"
+msgstr "Prilagođen javascript"
+
+#: conf/skin_general_settings.py:245
+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 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)."
+msgstr "Utipkajte ili zalijepite javascript koji želite da se izvrši na vašoj internet stranici. Link na skriptu biti će unešen na dnu HTML izlaza i služit će se na urlu \"&lt;forum url&gt;/custom.js\". Imajte na umu da javascript može pokvariti druge funkcije na stranici te da izvršavanje možda neće biti jednako u svim preglednicima(<strong>za omogućavanje prilagođenog koda</strong>, označite \"Dodaj prilagođen javascript\" opciju iznad.)."
+
+#: conf/skin_general_settings.py:263
+msgid "Skin media revision number"
+msgstr "Broj revizije teme"
+
+#: conf/skin_general_settings.py:265
+msgid "Will be set automatically but you can modify it if necessary."
+msgstr "Biti će postavljeno automatski, ali u slučaju potrebe možete ga prilagoditi."
+
+#: conf/skin_general_settings.py:276
+msgid "Hash to update the media revision number automatically."
+msgstr "Jedinstvena vrijednost za automatsko ažuriranje broja medijske revizije"
+
+#: conf/skin_general_settings.py:280
+msgid "Will be set automatically, it is not necesary to modify manually."
+msgstr "Biti će određena automatski, nije potrebno ručno podesiti."
+
+#: conf/social_sharing.py:11
+msgid "Sharing content on social networks"
+msgstr "Dijeljenje sadržaja na društvenim mrežama"
+
+#: conf/social_sharing.py:20
+msgid "Check to enable sharing of questions on Twitter"
+msgstr "Označite za omogućavanje dijeljenja pitanja na Twitteru"
+
+#: conf/social_sharing.py:29
+msgid "Check to enable sharing of questions on Facebook"
+msgstr "Označite za omogućavanje dijeljenja pitanja na Facebooku"
+
+#: conf/social_sharing.py:38
+msgid "Check to enable sharing of questions on LinkedIn"
+msgstr "Označite za omogućavanje dijeljenja pitanja na LinkedInu"
+
+#: conf/social_sharing.py:47
+msgid "Check to enable sharing of questions on Identi.ca"
+msgstr "Označite za omogućavanje dijeljenja pitanja na Identi.ca-i"
+
+#: conf/social_sharing.py:56
+msgid "Check to enable sharing of questions on Google+"
+msgstr "Označite za omogućavanje dijeljenja pitanja na Google+u"
+
+#: conf/spam_and_moderation.py:10
+msgid "Akismet spam protection"
+msgstr "Akismet zaštita od neželjene pošte"
+
+#: conf/spam_and_moderation.py:18
+msgid "Enable Akismet spam detection(keys below are required)"
+msgstr "Omogući Akismet otkrivanje neželjene pošte (nužni su ključevi ispod)"
+
+#: conf/spam_and_moderation.py:21
+#, python-format
+msgid "To get an Akismet key please visit <a href=\"%(url)s\">Akismet site</a>"
+msgstr "Za dobivanje Akismet ključa posjetite <a href=\"%(url)s\">Akismet stranicu</a>"
+
+#: conf/spam_and_moderation.py:31
+msgid "Akismet key for spam detection"
+msgstr "Akismet ključ za otkrivanje neželjene pošte"
+
+#: conf/super_groups.py:5
+msgid "Reputation, Badges, Votes & Flags"
+msgstr "Ugled, Značke, Glasovi i Zastave"
+
+#: conf/super_groups.py:6
+msgid "Static Content, URLS & UI"
+msgstr "Statični Sadržaj, URLOVI i Korisničko sučelje"
+
+#: conf/super_groups.py:7
+msgid "Data rules & Formatting"
+msgstr "Pravila o podacima i Formatiranju"
+
+#: conf/super_groups.py:8
+msgid "External Services"
+msgstr "Vanjski Servisi"
+
+#: conf/super_groups.py:9
+msgid "Login, Users & Communication"
+msgstr "Prijava, Korisnici i Komunikacija"
+
+#: conf/user_settings.py:14
+msgid "User settings"
+msgstr "Korisničke postavke"
+
+#: conf/user_settings.py:23
+msgid "Allow editing user screen name"
+msgstr "Dopusti uređivanje prikaznog imena korisnika"
+
+#: conf/user_settings.py:32
+msgid "Allow users change own email addresses"
+msgstr "Dopusti korisnicima promijenu svoje email adrese"
+
+#: conf/user_settings.py:41
+msgid "Allow account recovery by email"
+msgstr "Dopusti obnavljanje računa putem emaila "
+
+#: conf/user_settings.py:50
+msgid "Allow adding and removing login methods"
+msgstr "Dopusti dodavanje i oduzimanje metoda prijave"
+
+#: conf/user_settings.py:60
+msgid "Minimum allowed length for screen name"
+msgstr "Minimalna dozvoljena duljina prikaznog imena"
+
+#: conf/user_settings.py:68
+msgid "Default avatar for users"
+msgstr "Zadani avatar za korisnike"
+
+#: conf/user_settings.py:70
+msgid "To change the avatar image, select new file, then submit this whole form."
+msgstr "Za promjenu slike avatara, odaberite novu datoteku, zatim podnesite cijeli obrazac."
+
+#: conf/user_settings.py:83
+msgid "Use automatic avatars from gravatar.com"
+msgstr "Automatski koristi avatare iz gavatar.com-a"
+
+#: conf/user_settings.py:85
+msgid "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>."
+msgstr "Odaberite ovu mogućnost ako želite koristiti avatare iz gavatar.com-a. Imajte na umu da ovo svojstvo treba 10 minuta za potpunu aktivaciju. Morati ćete također omogućiti slanje avatara. Za više informacija posjetite <a href=\"http://askbot.org/doc/optional-modules.html#uploaded-avatars\">ovu stranicu</a>."
+
+#: conf/user_settings.py:97
+msgid "Default Gravatar icon type"
+msgstr "Zadan tip Gavatar ikone"
+
+#: conf/user_settings.py:99
+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 "Ova opcija vam omogućava zadavanje tipa avatara za email adrese bez povezanih gavatar slika. Za više informacija posjetite <a href=\"http://en.gravatar.com/site/implement/images/\">ovu stranicu</a>."
+
+#: conf/user_settings.py:109
+msgid "Name for the Anonymous user"
+msgstr "Ime za Anonimnog korisnika"
+
+#: conf/vote_rules.py:14
+msgid "Vote and flag limits"
+msgstr "Limit za glasanje i označavanje zastavom"
+
+#: conf/vote_rules.py:24
+msgid "Number of votes a user can cast per day"
+msgstr "Broj glasova koje korisnik dnevno može odbaciti"
+
+#: conf/vote_rules.py:33
+msgid "Maximum number of flags per user per day"
+msgstr "Maksimalan broj zastava po korisniku po danu"
+
+#: conf/vote_rules.py:42
+msgid "Threshold for warning about remaining daily votes"
+msgstr "Granica za upozorenje o preostalim dnevnim glasovima"
+
+#: conf/vote_rules.py:51
+msgid "Number of days to allow canceling votes"
+msgstr "Broj dana za dopuštanje otkazivanja glasova"
+
+#: conf/vote_rules.py:60
+msgid "Number of days required before answering own question"
+msgstr "Broj dana potrebnih prije mogućnosti odgovaranja na svoje pitanje"
+
+#: conf/vote_rules.py:69
+msgid "Number of flags required to automatically hide posts"
+msgstr "Broj zastava potrebnih za automatsko skrivanje posta"
+
+#: conf/vote_rules.py:78
+msgid "Number of flags required to automatically delete posts"
+msgstr "Broj zastava potrebnih za automatsko brisanje posta"
+
+#: conf/vote_rules.py:87
+msgid "Minimum days to accept an answer, if it has not been accepted by the question poster"
+msgstr "Minimalan broj dana za prihvaćanje odgovora, ako ga nije prihvatila osoba koja je postavila pitanje"
+
+#: conf/widgets.py:13
+msgid "Embeddable widgets"
+msgstr "Dodatci za ugrađivanje"
+
+#: conf/widgets.py:25
+msgid "Number of questions to show"
+msgstr "Broj prikazanih pitanja"
+
+#: conf/widgets.py:28
+msgid "To embed the widget, add the following code to your site (and fill in correct base url, preferred tags, width and height):<iframe src=\"{{base_url}}/widgets/questions?tags={{comma-separated-tags}}\" width=\"100%\" height=\"300\"scrolling=\"no\"><p>Your browser does not support iframes.</p></iframe>"
+msgstr "Za ugrađivanje dodatka dodajte sljedeći kod u vašu internet stranicu (i popunite ispravan osnovni url, željene oznake, širinu i visinu):<iframe src=\"{{base_url}}/widgets/questions?tags={{comma-separated-tags}}\" width=\"100%\" height=\"300\"scrolling=\"no\"><p>Vaš preglednik ne podržava iframeove.</p></iframe>"
+
+#: conf/widgets.py:73
+msgid "CSS for the questions widget"
+msgstr "CSS za dodatke s pitanjima"
+
+#: conf/widgets.py:81
+msgid "Header for the questions widget"
+msgstr "Zaglavlje za dodatak s pitanjima"
+
+#: conf/widgets.py:90
+msgid "Footer for the questions widget"
+msgstr "Podnožje za dodatak s pitanjima"
+
+#: const/__init__.py:10
+msgid "duplicate question"
+msgstr "duplikat pitanje"
+
+#: const/__init__.py:11
+msgid "question is off-topic or not relevant"
+msgstr "pitanje je izvan teme ili nije važno"
+
+#: const/__init__.py:12
+msgid "too subjective and argumentative"
+msgstr "previše subjektivno i polemično"
+
+#: const/__init__.py:13
+msgid "not a real question"
+msgstr "nije pravo pitanje"
+
+#: const/__init__.py:14
+msgid "the question is answered, right answer was accepted"
+msgstr "pitanje je odgovoreno, ispravan odgovor je prihvaćen"
+
+#: const/__init__.py:15
+msgid "question is not relevant or outdated"
+msgstr "pitanje nije relevantno ili je zastarilo"
+
+#: const/__init__.py:16
+msgid "question contains offensive or malicious remarks"
+msgstr "pitanje sadrži uvredljive ili zle primjedbe"
+
+#: const/__init__.py:17
+msgid "spam or advertising"
+msgstr "spam ili oglašavanje"
+
+#: const/__init__.py:18
+msgid "too localized"
+msgstr "previše lokaliziran"
+
+#: const/__init__.py:43
+#: skins/default/templates/question/answer_tab_bar.html:18
+msgid "newest"
+msgstr "najnovije"
+
+#: const/__init__.py:44
+#: skins/default/templates/users.html:27
+#: skins/default/templates/question/answer_tab_bar.html:15
+msgid "oldest"
+msgstr "najstarije"
+
+#: const/__init__.py:45
+msgid "active"
+msgstr "aktivno"
+
+#: const/__init__.py:46
+msgid "inactive"
+msgstr "ne aktivno"
+
+#: const/__init__.py:47
+msgid "hottest"
+msgstr "popularna"
+
+#: const/__init__.py:48
+msgid "coldest"
+msgstr "ne popularna"
+
+#: const/__init__.py:49
+#: skins/default/templates/question/answer_tab_bar.html:21
+msgid "most voted"
+msgstr "s najviše glasova"
+
+#: const/__init__.py:50
+msgid "least voted"
+msgstr "s najmanje glasova"
+
+#: const/__init__.py:51
+msgid "relevance"
+msgstr "relevantnost"
+
+#: const/__init__.py:63
+#: skins/default/templates/user_profile/user_inbox.html:50
+#: skins/default/templates/user_profile/user_inbox.html:62
+msgid "all"
+msgstr "sva"
+
+#: const/__init__.py:64
+msgid "unanswered"
+msgstr "0 odgovora"
+
+#: const/__init__.py:65
+msgid "favorite"
+msgstr "omiljena"
+
+#: const/__init__.py:70
+msgid "list"
+msgstr "lista"
+
+#: const/__init__.py:71
+msgid "cloud"
+msgstr "oblak"
+
+#: const/__init__.py:79
+msgid "Question has no answers"
+msgstr "Pitanje nema odgovore"
+
+#: const/__init__.py:80
+msgid "Question has no accepted answers"
+msgstr "Pitanje nema prihvaćene odgovore"
+
+#: const/__init__.py:125
+msgid "asked a question"
+msgstr "postavio/la pitanje"
+
+#: const/__init__.py:126
+msgid "answered a question"
+msgstr "odgovorio/la na pitanje"
+
+#: const/__init__.py:127
+#: const/__init__.py:203
+msgid "commented question"
+msgstr "komentirao/la pitanje"
+
+#: const/__init__.py:128
+#: const/__init__.py:204
+msgid "commented answer"
+msgstr "komentirao/la odgovor"
+
+#: const/__init__.py:129
+msgid "edited question"
+msgstr "uredio/la pitanje"
+
+#: const/__init__.py:130
+msgid "edited answer"
+msgstr "uredio/la odgovor"
+
+#: const/__init__.py:131
+msgid "received badge"
+msgstr "primio/la značku"
+
+#: const/__init__.py:132
+msgid "marked best answer"
+msgstr "označio/la najbolji odgovor"
+
+#: const/__init__.py:133
+msgid "upvoted"
+msgstr "dao/la pozitivan glas"
+
+#: const/__init__.py:134
+msgid "downvoted"
+msgstr "dao/la negativan glas"
+
+#: const/__init__.py:135
+msgid "canceled vote"
+msgstr "poništio/la glas"
+
+#: const/__init__.py:136
+msgid "deleted question"
+msgstr "obrisano pitanje"
+
+#: const/__init__.py:137
+msgid "deleted answer"
+msgstr "obrisan odgovor"
+
+#: const/__init__.py:138
+msgid "marked offensive"
+msgstr "označeno kao uvredljivo"
+
+#: const/__init__.py:139
+msgid "updated tags"
+msgstr "ažurirane oznake"
+
+#: const/__init__.py:140
+msgid "selected favorite"
+msgstr "odabran omiljeni"
+
+#: const/__init__.py:141
+msgid "completed user profile"
+msgstr "završen korisnički profil"
+
+#: const/__init__.py:142
+msgid "email update sent to user"
+msgstr "email dopuna poslana korisniku"
+
+#: const/__init__.py:145
+msgid "reminder about unanswered questions sent"
+msgstr "poslana napomena o ne odgovorenim pitanjima"
+
+#: const/__init__.py:149
+msgid "reminder about accepting the best answer sent"
+msgstr "poslana napomena o prihvaćanju najboljeg odgovora"
+
+#: const/__init__.py:151
+msgid "mentioned in the post"
+msgstr "spomenut u postu"
+
+#: const/__init__.py:202
+msgid "answered question"
+msgstr "odgovoreno pitanje"
+
+#: const/__init__.py:205
+msgid "accepted answer"
+msgstr "prihvaćen odgovor"
+
+#: const/__init__.py:209
+msgid "[closed]"
+msgstr "[zatvoreno]"
+
+#: const/__init__.py:210
+msgid "[deleted]"
+msgstr "[obrisano]"
+
+#: const/__init__.py:211
+#: views/readers.py:566
+msgid "initial version"
+msgstr "prva verzija"
+
+#: const/__init__.py:212
+msgid "retagged"
+msgstr "ponovo označeno"
+
+#: const/__init__.py:220
+msgid "off"
+msgstr "isključeno"
+
+#: const/__init__.py:221
+msgid "exclude ignored"
+msgstr "isključi ignorirano"
+
+#: const/__init__.py:222
+msgid "only selected"
+msgstr "samo odabrano"
+
+#: const/__init__.py:226
+msgid "instantly"
+msgstr "odmah"
+
+#: const/__init__.py:227
+msgid "daily"
+msgstr "dnevno"
+
+#: const/__init__.py:228
+msgid "weekly"
+msgstr "tjedno"
+
+#: const/__init__.py:229
+msgid "no email"
+msgstr "bez emaila"
+
+#: const/__init__.py:236
+msgid "identicon"
+msgstr "identicon"
+
+#: const/__init__.py:237
+msgid "mystery-man"
+msgstr "tajanstven čovjek"
+
+#: const/__init__.py:238
+msgid "monsterid"
+msgstr "monsterid"
+
+#: const/__init__.py:239
+msgid "wavatar"
+msgstr "wavatar"
+
+#: const/__init__.py:240
+msgid "retro"
+msgstr "retro"
+
+#: const/__init__.py:287
+#: skins/default/templates/badges.html:38
+msgid "gold"
+msgstr "zlatni"
+
+#: const/__init__.py:288
+#: skins/default/templates/badges.html:48
+msgid "silver"
+msgstr "srebrni"
+
+#: const/__init__.py:289
+#: skins/default/templates/badges.html:55
+msgid "bronze"
+msgstr "brončani"
+
+#: const/__init__.py:301
+msgid "None"
+msgstr "Nijedan"
+
+#: const/__init__.py:302
+msgid "Gravatar"
+msgstr "Gavatar"
+
+#: const/__init__.py:303
+msgid "Uploaded Avatar"
+msgstr "Poslan Avatar"
+
+#: const/message_keys.py:21
+msgid "most relevant questions"
+msgstr "najralevantnija pitanja"
+
+#: const/message_keys.py:22
+msgid "click to see most relevant questions"
+msgstr "najrelevantnija pitanja"
+
+#: const/message_keys.py:23
+msgid "by relevance"
+msgstr "po relevantnosti"
+
+#: const/message_keys.py:24
+msgid "click to see the oldest questions"
+msgstr "najstarijia pitanja"
+
+#: const/message_keys.py:25
+msgid "by date"
+msgstr "datumu"
+
+#: const/message_keys.py:26
+msgid "click to see the newest questions"
+msgstr "najnovija pitanja"
+
+#: const/message_keys.py:27
+msgid "click to see the least recently updated questions"
+msgstr "zadnje ažurirana pitanja"
+
+#: const/message_keys.py:28
+msgid "by activity"
+msgstr "aktivnosti"
+
+#: const/message_keys.py:29
+msgid "click to see the most recently updated questions"
+msgstr "zadnje ažurirana pitanja"
+
+#: const/message_keys.py:30
+msgid "click to see the least answered questions"
+msgstr "zadnje odgovorena pitanja"
+
+#: const/message_keys.py:31
+msgid "by answers"
+msgstr "odgovoru"
+
+#: const/message_keys.py:32
+msgid "click to see the most answered questions"
+msgstr "pitanja s najviše odgovora"
+
+#: const/message_keys.py:33
+msgid "click to see least voted questions"
+msgstr "zadnje glasana pitanja"
+
+#: const/message_keys.py:34
+msgid "by votes"
+msgstr "glasovima"
+
+#: const/message_keys.py:35
+msgid "click to see most voted questions"
+msgstr "pitanja s najviše glasova"
+
+#: const/message_keys.py:40
+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 "Čini se da je vaš račun blokiran stoga ne možete objavljivati nove postove dok se spor ne riješi. Kontaktirajte administratora foruma za rješenje."
+
+#: const/message_keys.py:45
+#: models/__init__.py:788
+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 "Čini se da je vaš račun blokiran stoga ne možete objavljivati nove postove dok se spor ne riješi. Možete samo uređivati postojeće postove. Kontaktirajte administratora foruma za rješenje."
+
+#: deps/django_authopenid/backends.py:166
+msgid "Welcome! Please set email address (important!) in your profile and adjust screen name, if necessary."
+msgstr "Dobrodošli! Unesite email adresu (važno!) u vaš profil te ako je potrebno, podesite prikazno ime."
+
+#: deps/django_authopenid/forms.py:110
+#: deps/django_authopenid/views.py:142
+msgid "i-names are not supported"
+msgstr "i-imena nisu podržana"
+
+#: deps/django_authopenid/forms.py:233
+#, python-format
+msgid "Please enter your %(username_token)s"
+msgstr "Unesite vaše %(username_token)s"
+
+#: deps/django_authopenid/forms.py:259
+msgid "Please, enter your user name"
+msgstr "Unesite vaše korisničko ime"
+
+#: deps/django_authopenid/forms.py:263
+msgid "Please, enter your password"
+msgstr "Unesite vašu lozinku"
+
+#: deps/django_authopenid/forms.py:270
+#: deps/django_authopenid/forms.py:274
+msgid "Please, enter your new password"
+msgstr "Unesite vašu novu lozinku"
+
+#: deps/django_authopenid/forms.py:285
+msgid "Passwords did not match"
+msgstr "Lozinke nisu iste"
+
+#: deps/django_authopenid/forms.py:297
+#, python-format
+msgid "Please choose password > %(len)s characters"
+msgstr "Unesite lozinku > %(len)s znakova"
+
+#: deps/django_authopenid/forms.py:335
+msgid "Current password"
+msgstr "Trenutna lozinka"
+
+#: deps/django_authopenid/forms.py:346
+msgid "Old password is incorrect. Please enter the correct password."
+msgstr "Stara lozinka nije točna. Unesite ispravnu lozinku."
+
+#: deps/django_authopenid/forms.py:399
+msgid "Sorry, we don't have this email address in the database"
+msgstr "Unešena email adresa se ne nalazi u našoj bazi podataka"
+
+#: deps/django_authopenid/forms.py:435
+msgid "Your user name (<i>required</i>)"
+msgstr "Vaše korisničko ime (<i>nužno</i>)"
+
+#: deps/django_authopenid/forms.py:450
+msgid "sorry, there is no such user name"
+msgstr "ne postoji takvo korisničko ime"
+
+#: deps/django_authopenid/urls.py:9
+#: deps/django_authopenid/urls.py:12
+#: deps/django_authopenid/urls.py:15
+#: setup_templates/settings.py:210
+msgid "signin/"
+msgstr "prijava/"
+
+#: deps/django_authopenid/urls.py:10
+msgid "signout/"
+msgstr "odjava/"
+
+#: deps/django_authopenid/urls.py:12
+msgid "complete/"
+msgstr "zavrsi/"
+
+#: deps/django_authopenid/urls.py:15
+msgid "complete-oauth/"
+msgstr "zavrsi-oauth/"
+
+#: deps/django_authopenid/urls.py:19
+msgid "register/"
+msgstr "registracija/"
+
+#: deps/django_authopenid/urls.py:21
+msgid "signup/"
+msgstr "upis/"
+
+#: deps/django_authopenid/urls.py:25
+msgid "logout/"
+msgstr "odjava/"
+
+#: deps/django_authopenid/urls.py:30
+msgid "recover/"
+msgstr "obnova/"
+
+#: deps/django_authopenid/util.py:378
+#, python-format
+msgid "%(site)s user name and password"
+msgstr "%(site)s korisničko ime i lozinka"
+
+#: deps/django_authopenid/util.py:384
+#: skins/common/templates/authopenid/signin.html:115
+msgid "Create a password-protected account"
+msgstr "Kreiraj račun zaštićen lozinkom"
+
+#: deps/django_authopenid/util.py:385
+msgid "Change your password"
+msgstr "Promjenite lozinku"
+
+#: deps/django_authopenid/util.py:473
+msgid "Sign in with Yahoo"
+msgstr "Yahoo prijava"
+
+#: deps/django_authopenid/util.py:480
+msgid "AOL screen name"
+msgstr "AOL prikazno ime"
+
+#: deps/django_authopenid/util.py:488
+msgid "OpenID url"
+msgstr "OpenID url"
+
+#: deps/django_authopenid/util.py:517
+msgid "Flickr user name"
+msgstr "Flickr korisničko ime"
+
+#: deps/django_authopenid/util.py:525
+msgid "Technorati user name"
+msgstr "Technorati korisničko ime"
+
+#: deps/django_authopenid/util.py:533
+msgid "WordPress blog name"
+msgstr "WordPress blog ime"
+
+#: deps/django_authopenid/util.py:541
+msgid "Blogger blog name"
+msgstr "Blogger blog ime"
+
+#: deps/django_authopenid/util.py:549
+msgid "LiveJournal blog name"
+msgstr "LiveJournal blog ime"
+
+#: deps/django_authopenid/util.py:557
+msgid "ClaimID user name"
+msgstr "ClaimID korisničko ime"
+
+#: deps/django_authopenid/util.py:565
+msgid "Vidoop user name"
+msgstr "Vidoop korisničko ime"
+
+#: deps/django_authopenid/util.py:573
+msgid "Verisign user name"
+msgstr "Verisign korisničko ime"
+
+#: deps/django_authopenid/util.py:608
+#, python-format
+msgid "Change your %(provider)s password"
+msgstr "Promjenite %(provider)s lozinku"
+
+#: deps/django_authopenid/util.py:612
+#, python-format
+msgid "Click to see if your %(provider)s signin still works for %(site_name)s"
+msgstr "Kliknite da vidite da li %(provider)s prijava još radi za %(site_name)s"
+
+#: deps/django_authopenid/util.py:621
+#, python-format
+msgid "Create password for %(provider)s"
+msgstr "Kreirajte lozinku za %(provider)s"
+
+#: deps/django_authopenid/util.py:625
+#, python-format
+msgid "Connect your %(provider)s account to %(site_name)s"
+msgstr "Spojite vaš %(provider)s račun s %(site_name)s"
+
+#: deps/django_authopenid/util.py:634
+#, python-format
+msgid "Signin with %(provider)s user name and password"
+msgstr "Prijavite se sa %(provider)s korisničkim imenom i lozinkom"
+
+#: deps/django_authopenid/util.py:641
+#, python-format
+msgid "Sign in with your %(provider)s account"
+msgstr "Prijavite se sa %(provider)s korisničkim računom"
+
+#: deps/django_authopenid/views.py:149
+#, python-format
+msgid "OpenID %(openid_url)s is invalid"
+msgstr "OpenID %(openid_url)s je neispravan"
+
+#: deps/django_authopenid/views.py:261
+#: deps/django_authopenid/views.py:408
+#: deps/django_authopenid/views.py:436
+#, python-format
+msgid "Unfortunately, there was some problem when connecting to %(provider)s, please try again or use another provider"
+msgstr "Nažalost, nastali su problemi prilikom spajanja na %(provider)s, pokušajte ponovo ili koristite drugog pružatelja"
+
+#: deps/django_authopenid/views.py:358
+msgid "Your new password saved"
+msgstr "Vaša nova lozinka je sačuvana"
+
+#: deps/django_authopenid/views.py:462
+msgid "The login password combination was not correct"
+msgstr "Kombinacija prijavne lozinke nije ispravna"
+
+#: deps/django_authopenid/views.py:564
+msgid "Please click any of the icons below to sign in"
+msgstr "Za prijavu kliknite na bilo koju od donjih ikona"
+
+#: deps/django_authopenid/views.py:566
+msgid "Account recovery email sent"
+msgstr "Email za obnovu računa je poslan"
+
+#: deps/django_authopenid/views.py:569
+msgid "Please add one or more login methods."
+msgstr "Dodajte jedan ili više načina prijave."
+
+#: deps/django_authopenid/views.py:571
+msgid "If you wish, please add, remove or re-validate your login methods"
+msgstr "Ako želite., dodajte, uklonite ili ponovo potvrdite načine prijave"
+
+#: deps/django_authopenid/views.py:573
+msgid "Please wait a second! Your account is recovered, but ..."
+msgstr "Pričekajte trenutak! Vaš račun je obnovljen, ali ..."
+
+#: deps/django_authopenid/views.py:575
+msgid "Sorry, this account recovery key has expired or is invalid"
+msgstr "Ovaj ključ za obnovu računa nije ispravan ili je istekao"
+
+#: deps/django_authopenid/views.py:648
+#, python-format
+msgid "Login method %(provider_name)s does not exist"
+msgstr "%(provider_name)s način prijave ne postoji"
+
+#: deps/django_authopenid/views.py:654
+msgid "Oops, sorry - there was some error - please try again"
+msgstr "Uups, oprostite - dogodila se greška - pokušajte ponovo"
+
+#: deps/django_authopenid/views.py:745
+#, python-format
+msgid "Your %(provider)s login works fine"
+msgstr "Vaša %(provider)s prijava radi"
+
+#: deps/django_authopenid/views.py:1056
+#: deps/django_authopenid/views.py:1062
+#, python-format
+msgid "your email needs to be validated see %(details_url)s"
+msgstr "Your email needs to be validated. Please see details <a id='validate_email_alert' href='%(details_url)s'>here</a>."
+
+#: deps/django_authopenid/views.py:1083
+#, python-format
+msgid "Recover your %(site)s account"
+msgstr "Obnovite vaš %(site)s račun"
+
+#: deps/django_authopenid/views.py:1155
+msgid "Please check your email and visit the enclosed link."
+msgstr "Provjerite vaš email i posjetite priloženu vezu."
+
+#: deps/livesettings/models.py:101
+#: deps/livesettings/models.py:140
+msgid "Site"
+msgstr "Internet stranica"
+
+#: deps/livesettings/values.py:69
+msgid "Main"
+msgstr "Glavna"
+
+#: deps/livesettings/values.py:128
+msgid "Base Settings"
+msgstr "Osnovne Postavke"
+
+#: deps/livesettings/values.py:235
+msgid "Default value: \"\""
+msgstr "Zadana vrijednost: \"\""
+
+#: deps/livesettings/values.py:242
+msgid "Default value: "
+msgstr "Zadana vrijednost:"
+
+#: deps/livesettings/values.py:245
+#, python-format
+msgid "Default value: %s"
+msgstr "Zadana vrijednost: %s"
+
+#: deps/livesettings/values.py:629
+#, python-format
+msgid "Allowed image file types are %(types)s"
+msgstr "Za slike su dozvoljeni %(types)s tipovi datoteka"
+
+#: deps/livesettings/templates/livesettings/_admin_site_views.html:4
+msgid "Sites"
+msgstr "Internet stranice"
+
+#: deps/livesettings/templates/livesettings/group_settings.html:11
+#: deps/livesettings/templates/livesettings/site_settings.html:23
+msgid "Documentation"
+msgstr "Dokumentacija"
+
+#: deps/livesettings/templates/livesettings/group_settings.html:11
+#: deps/livesettings/templates/livesettings/site_settings.html:23
+#: skins/common/templates/authopenid/signin.html:143
+msgid "Change password"
+msgstr "Promjeni lozinku"
+
+#: deps/livesettings/templates/livesettings/group_settings.html:11
+#: deps/livesettings/templates/livesettings/site_settings.html:23
+msgid "Log out"
+msgstr "Odjava"
+
+#: deps/livesettings/templates/livesettings/group_settings.html:14
+#: deps/livesettings/templates/livesettings/site_settings.html:26
+msgid "Home"
+msgstr "Početna"
+
+#: deps/livesettings/templates/livesettings/group_settings.html:15
+msgid "Edit Group Settings"
+msgstr "Uredi Postavke Grupa"
+
+#: deps/livesettings/templates/livesettings/group_settings.html:22
+#: deps/livesettings/templates/livesettings/site_settings.html:50
+msgid "Please correct the error below."
+msgid_plural "Please correct the errors below."
+msgstr[0] "Ispravite grešku ispod."
+msgstr[1] "Ispravite greške ispod."
+
+#: deps/livesettings/templates/livesettings/group_settings.html:28
+#, python-format
+msgid "Settings included in %(name)s."
+msgstr "Postavke uključene u %(name)s."
+
+#: deps/livesettings/templates/livesettings/group_settings.html:62
+#: deps/livesettings/templates/livesettings/site_settings.html:97
+msgid "You don't have permission to edit values."
+msgstr "Nemate dozvolu za uređivanje vrijednosti."
+
+#: deps/livesettings/templates/livesettings/site_settings.html:27
+msgid "Edit Site Settings"
+msgstr "Uredi Postavke Stranice"
+
+#: deps/livesettings/templates/livesettings/site_settings.html:43
+msgid "Livesettings are disabled for this site."
+msgstr "Instant postavke su nisu moguće za ovu stranicu."
+
+#: deps/livesettings/templates/livesettings/site_settings.html:44
+msgid "All configuration options must be edited in the site settings.py file"
+msgstr "Sve konfiguracijske mogućnosti moraju se urediti u settings.py datoteci"
+
+#: deps/livesettings/templates/livesettings/site_settings.html:66
+#, python-format
+msgid "Group settings: %(name)s"
+msgstr "Postavke za grupu: %(name)s"
+
+#: deps/livesettings/templates/livesettings/site_settings.html:93
+msgid "Uncollapse all"
+msgstr "Složi sve"
+
+#: importers/stackexchange/management/commands/load_stackexchange.py:141
+msgid "Congratulations, you are now an Administrator"
+msgstr "Čestitamo, postali ste Administrator"
+
+#: management/commands/send_accept_answer_reminders.py:58
+#, python-format
+msgid "Accept the best answer for %(question_count)d of your questions"
+msgstr "Prihvati najbolji odgovor za %(question_count)d vaših pitanja"
+
+#: management/commands/send_accept_answer_reminders.py:63
+msgid "Please accept the best answer for this question:"
+msgstr "Prihvatite najbolji odgovor za ovo pitanje:"
+
+#: management/commands/send_accept_answer_reminders.py:65
+msgid "Please accept the best answer for these questions:"
+msgstr "Prihvatite najbolji odgovor za ova pitanja:"
+
+#: management/commands/send_email_alerts.py:414
+#, python-format
+msgid "%(question_count)d updated question about %(topics)s"
+msgid_plural "%(question_count)d updated questions about %(topics)s"
+msgstr[0] "%(question_count)d ažurirano pitanje o %(topics)s"
+msgstr[1] "%(question_count)d ažurirana pitanja o %(topics)s"
+
+#: management/commands/send_email_alerts.py:425
+#, python-format
+msgid "<p>Dear %(name)s,</p><p>The following question has been updated %(sitename)s</p>"
+msgid_plural "<p>Dear %(name)s,</p><p>The following %(num)d questions have been updated on %(sitename)s:</p>"
+msgstr[0] "<p>Dragi %(name)s,</p><p>Sljedeće pitanje je ažurirano %(sitename)s</p>"
+msgstr[1] "<p>Dragi %(name)s,</p><p>Sljedećih %(num)d pitanja je ažurirano na %(sitename)s:</p>"
+
+#: management/commands/send_email_alerts.py:449
+msgid "new question"
+msgstr "novo pitanje"
+
+#: management/commands/send_email_alerts.py:474
+#, python-format
+msgid "<p>Please remember that you can always <a hrefl\"%(email_settings_link)s\">adjust</a> frequency of the email updates or turn them off entirely.<br/>If you believe that this message was sent in an error, please email about it the forum administrator at %(admin_email)s.</p><p>Sincerely,</p><p>Your friendly %(sitename)s server.</p>"
+msgstr "<p>Upamtite da uvijek možete <a hrefl\"%(email_settings_link)s\">namjestiti</a> učestalost slanja ažuriranja putem email ili ih potpuno isključiti.<br/>Ako smatrate da je ova poruka poslana greškom, kontaktirajte administratora fouma na %(admin_email)s.</p><p>S štovanjem,</p><p>Vaš %(sitename)s poslužitelj.</p>"
+
+#: management/commands/send_unanswered_question_reminders.py:60
+#, python-format
+msgid "%(question_count)d unanswered question about %(topics)s"
+msgid_plural "%(question_count)d unanswered questions about %(topics)s"
+msgstr[0] "%(question_count)d ne odgovoreno pitanje o %(topics)s"
+msgstr[1] "%(question_count)d ne odgovorenih pitanja o %(topics)s"
+
+#: middleware/forum_mode.py:53
+#, python-format
+msgid "Please log in to use %s"
+msgstr "Za korištenje %s potrebna je prijava"
+
+#: models/__init__.py:320
+msgid "Sorry, you cannot accept or unaccept best answers because your account is blocked"
+msgstr "Ne možete prihvatiti ili odbiti najbolji odgovor jer je vaš račun blokiran"
+
+#: models/__init__.py:324
+msgid "Sorry, you cannot accept or unaccept best answers because your account is suspended"
+msgstr "Ne možete prihvatiti ili odbiti najbolji odgovor jer je vaš račun suspendiran"
+
+#: models/__init__.py:337
+#, python-format
+msgid ">%(points)s points required to accept or unaccept your own answer to your own question"
+msgstr "Potrebno je >%(points)s bodova za prihvaćanje ili odbijanje svojeg odgovora na svoje pitanje "
+
+#: models/__init__.py:359
+#, python-format
+msgid "Sorry, you will be able to accept this answer only after %(will_be_able_at)s"
+msgstr "Biti ćete u mogućnosti prihvatiti ovaj odgovor nakon %(will_be_able_at)s"
+
+#: models/__init__.py:367
+#, python-format
+msgid "Sorry, only moderators or original author of the question - %(username)s - can accept or unaccept the best answer"
+msgstr "Samo moderatori ili autor pitanja - %(username)s - može prihvatiti ili odbiti najbolji odgovor "
+
+#: models/__init__.py:390
+msgid "Sorry, you cannot vote for your own posts"
+msgstr "Ne možete glasati za svoje postove"
+
+#: models/__init__.py:394
+msgid "Sorry your account appears to be blocked "
+msgstr "Izgleda da je vaš račun blokiran"
+
+#: models/__init__.py:399
+msgid "Sorry your account appears to be suspended "
+msgstr "Izgleda da je vaš račun suspendiran"
+
+#: models/__init__.py:409
+#, python-format
+msgid ">%(points)s points required to upvote"
+msgstr "Potrebno je >%(points)s za davanje pozitivnog glasa"
+
+#: models/__init__.py:415
+#, python-format
+msgid ">%(points)s points required to downvote"
+msgstr "Potrebno je >%(points)s za davanje negativnog glasa"
+
+#: models/__init__.py:430
+msgid "Sorry, blocked users cannot upload files"
+msgstr "Blokirani korisnici ne mogu slati datoteke"
+
+#: models/__init__.py:431
+msgid "Sorry, suspended users cannot upload files"
+msgstr "Suspendirani korisnici ne mogu slati datoteke"
+
+#: models/__init__.py:433
+#, python-format
+msgid "sorry, file uploading requires karma >%(min_rep)s"
+msgstr "Slanje datoteka zahtjeva veličinu karme >%(min_rep)s"
+
+#: models/__init__.py:482
+#, python-format
+msgid "Sorry, comments (except the last one) are editable only within %(minutes)s minute from posting"
+msgid_plural "Sorry, comments (except the last one) are editable only within %(minutes)s minutes from posting"
+msgstr[0] "Komentari (osim zadnjeg) se mogu uređivati unutar %(minutes)s minute od objave posta"
+msgstr[1] "Komentari (osim zadnjeg) se mogu uređivati unutar %(minutes)s minuta od objave posta"
+
+#: models/__init__.py:494
+msgid "Sorry, but only post owners or moderators can edit comments"
+msgstr "Samo vlasnici posta ili moderatori mogu uređivati komentare"
+
+#: models/__init__.py:519
+msgid "Sorry, since your account is suspended you can comment only your own posts"
+msgstr "Zato što vam je račun suspendiran možete komentirati samo svoje postove"
+
+#: models/__init__.py:523
+#, 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 "Za komentiranje postova potrebno je imati ugled od najmanje %(min_rep)s bodova. Trenutno možete komentirati samo svoje postove i odgovore na pitanja."
+
+#: models/__init__.py:553
+msgid "This post has been deleted and can be seen only by post owners, site administrators and moderators"
+msgstr "Ovaj post je obrisan, a mogu ga vidjeti samo vlasnik posta, administrator i moderatori."
+
+#: models/__init__.py:570
+msgid "Sorry, only moderators, site administrators and post owners can edit deleted posts"
+msgstr "Samo moderatori, administratori i vlasnici posta mogu uređivati obrisane postove"
+
+#: models/__init__.py:585
+msgid "Sorry, since your account is blocked you cannot edit posts"
+msgstr "Ne možete uređivati postove zato što vam je račun blokiran"
+
+#: models/__init__.py:589
+msgid "Sorry, since your account is suspended you can edit only your own posts"
+msgstr "Ne možete uređivati postove zato što vam je račun suspendiran"
+
+#: models/__init__.py:594
+#, python-format
+msgid "Sorry, to edit wiki posts, a minimum reputation of %(min_rep)s is required"
+msgstr "Za uređivanje wiki postova, potreban je minimalan ugled od %(min_rep)s "
+
+#: models/__init__.py:601
+#, python-format
+msgid "Sorry, to edit other people's posts, a minimum reputation of %(min_rep)s is required"
+msgstr "Za uređivanje postova drugih korisnika, potreban je minimalan ugled od %(min_rep)s"
+
+#: models/__init__.py:664
+msgid "Sorry, cannot delete your question since it has an upvoted answer posted by someone else"
+msgid_plural "Sorry, cannot delete your question since it has some upvoted answers posted by other users"
+msgstr[0] "Ne možete obrisati vaše pitanje zato što ima odgovor s pozitivnim glasom kojeg je objavio drugi korisnik"
+msgstr[1] "Ne možete obrisati vaše pitanje zato što ima odgovore s pozitivnim glasom kojeg su objavili drugi korisnici"
+
+#: models/__init__.py:679
+msgid "Sorry, since your account is blocked you cannot delete posts"
+msgstr "Ne možete obrisati postove jer vam je račun blokiran"
+
+#: models/__init__.py:683
+msgid "Sorry, since your account is suspended you can delete only your own posts"
+msgstr "Možete brisati samo svoje postove jer vam je račun suspendiran"
+
+#: models/__init__.py:687
+#, python-format
+msgid "Sorry, to deleted other people' posts, a minimum reputation of %(min_rep)s is required"
+msgstr "Za brisanje postova drugih korisnika potreban je minimalan ugled od %(min_rep)s"
+
+#: models/__init__.py:707
+msgid "Sorry, since your account is blocked you cannot close questions"
+msgstr "Ne možete zatvoriti pitanja jer vam je račun blokiran"
+
+#: models/__init__.py:711
+msgid "Sorry, since your account is suspended you cannot close questions"
+msgstr "Ne možete zatvoriti pitanja jer vam je račun suspendiran"
+
+#: models/__init__.py:715
+#, python-format
+msgid "Sorry, to close other people' posts, a minimum reputation of %(min_rep)s is required"
+msgstr "Za zatvaranje postova drugih korisnika potreban je minimalan ugled od %(min_rep)s"
+
+#: models/__init__.py:724
+#, python-format
+msgid "Sorry, to close own question a minimum reputation of %(min_rep)s is required"
+msgstr "Za zatvaranje svojih pitanja potreban je minimalan ugled od %(min_rep)s"
+
+#: models/__init__.py:748
+#, python-format
+msgid "Sorry, only administrators, moderators or post owners with reputation > %(min_rep)s can reopen questions."
+msgstr "Samo administratori, moderatori i vlasnici posta sa ugledom > %(min_rep)s mogu ponovo otvoriti pitanja."
+
+#: models/__init__.py:754
+#, python-format
+msgid "Sorry, to reopen own question a minimum reputation of %(min_rep)s is required"
+msgstr "Za ponovo otvaranje svojih pitanja potreban je minimalan ugled od %(min_rep)s"
+
+#: models/__init__.py:775
+msgid "You have flagged this question before and cannot do it more than once"
+msgstr "Već ste označili zastavom ovo pitanje i ne možete ga označiti ponovo"
+
+#: models/__init__.py:783
+msgid "Sorry, since your account is blocked you cannot flag posts as offensive"
+msgstr "Ne možete označiti postove kao uvedljive jer vam je račun blokiran"
+
+#: models/__init__.py:794
+#, python-format
+msgid "Sorry, to flag posts as offensive a minimum reputation of %(min_rep)s is required"
+msgstr "Za označavanje postova uvredljivim potreban je minimalan ugled od %(min_rep)s"
+
+#: models/__init__.py:815
+#, python-format
+msgid "Sorry, you have exhausted the maximum number of %(max_flags_per_day)s offensive flags per day."
+msgstr "Iscrpili ste maksimalan broj od %(max_flags_per_day)s uvredljivih zastava po danu."
+
+#: models/__init__.py:827
+msgid "cannot remove non-existing flag"
+msgstr "ne mogu ukloniti nepostojeću zastavu"
+
+#: models/__init__.py:833
+msgid "Sorry, since your account is blocked you cannot remove flags"
+msgstr "Ne možete ukloniti zastave jer vam je račun blokiran"
+
+#: models/__init__.py:837
+msgid "Sorry, your account appears to be suspended and you cannot remove flags. Please contact the forum administrator to reach a resolution."
+msgstr "Ne možete ukloniti zastave jer vam je račun suspendiran. Kontaktirajte administratora foruma radi rješavanja problema."
+
+#: models/__init__.py:843
+#, 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] "Za označavanje posta zastavom potreban je minimalan ugled od %(min_rep)d"
+msgstr[1] "Za označavanje postova zastavom potreban je minimalan ugled od %(min_rep)d"
+
+#: models/__init__.py:862
+msgid "you don't have the permission to remove all flags"
+msgstr "nemate dozvolu za uklanjanje svih zastava"
+
+#: models/__init__.py:863
+msgid "no flags for this entry"
+msgstr "nema zastava na ovom unosu"
+
+#: models/__init__.py:887
+msgid "Sorry, only question owners, site administrators and moderators can retag deleted questions"
+msgstr "Samo vlasnici pitanja, administratori i moderatori mogu ponovo označiti obrisana pitanja"
+
+#: models/__init__.py:894
+msgid "Sorry, since your account is blocked you cannot retag questions"
+msgstr "Ne možete ponovo označiti pitanja jer vam je račun blokiran"
+
+#: models/__init__.py:898
+msgid "Sorry, since your account is suspended you can retag only your own questions"
+msgstr "Ne možete ponovo označiti pitanja jer vam je račun suspendiran"
+
+#: models/__init__.py:902
+#, python-format
+msgid "Sorry, to retag questions a minimum reputation of %(min_rep)s is required"
+msgstr "Za ponovo označavanje pitanja potreban je minimalan ugled od %(min_rep)s"
+
+#: models/__init__.py:921
+msgid "Sorry, since your account is blocked you cannot delete comment"
+msgstr "Ne možete obrisati komentar jer vam je račun blokiran"
+
+#: models/__init__.py:925
+msgid "Sorry, since your account is suspended you can delete only your own comments"
+msgstr "Ne možete obrisati svoje komentare jer vam je račun suspendiran"
+
+#: models/__init__.py:929
+#, python-format
+msgid "Sorry, to delete comments reputation of %(min_rep)s is required"
+msgstr "Za brisanje komentara potreban je minimalan ugled od %(min_rep)s"
+
+#: models/__init__.py:953
+msgid "sorry, but older votes cannot be revoked"
+msgstr "stari glasovi se ne mogu opozvati"
+
+#: models/__init__.py:1469
+#: utils/functions.py:78
+#, python-format
+msgid "on %(date)s"
+msgstr "na %(date)s"
+
+#: models/__init__.py:1471
+msgid "in two days"
+msgstr "za dva dana"
+
+#: models/__init__.py:1473
+msgid "tomorrow"
+msgstr "sutra"
+
+#: models/__init__.py:1475
+#, python-format
+msgid "in %(hr)d hour"
+msgid_plural "in %(hr)d hours"
+msgstr[0] "za %(hr)d sat"
+msgstr[1] "za %(hr)d sati"
+
+#: models/__init__.py:1477
+#, python-format
+msgid "in %(min)d min"
+msgid_plural "in %(min)d mins"
+msgstr[0] "za %(min)d minut"
+msgstr[1] "za %(min)d minuta"
+
+#: models/__init__.py:1478
+#, python-format
+msgid "%(days)d day"
+msgid_plural "%(days)d days"
+msgstr[0] "%(days)d dan"
+msgstr[1] "%(days)d dana"
+
+#: models/__init__.py:1480
+#, python-format
+msgid "New users must wait %(days)s before answering their own question. You can post an answer %(left)s"
+msgstr "Novi korisnici mogu odgovaranje na svoje pitanje nakon %(days)s dana. Možete objaviti odgovor %(left)s"
+
+#: models/__init__.py:1653
+#: skins/default/templates/feedback_email.txt:9
+msgid "Anonymous"
+msgstr "Anoniman"
+
+#: models/__init__.py:1749
+msgid "Site Adminstrator"
+msgstr "Administartor"
+
+#: models/__init__.py:1751
+msgid "Forum Moderator"
+msgstr "Forum Moderator"
+
+#: models/__init__.py:1753
+msgid "Suspended User"
+msgstr "Suspendiran Korisnik"
+
+#: models/__init__.py:1755
+msgid "Blocked User"
+msgstr "Blokiran Korisnik"
+
+#: models/__init__.py:1757
+msgid "Registered User"
+msgstr "Registrian Korisnik"
+
+#: models/__init__.py:1759
+msgid "Watched User"
+msgstr "Korisnik pod Smotrom"
+
+#: models/__init__.py:1761
+msgid "Approved User"
+msgstr "Odobren Korisnik"
+
+#: models/__init__.py:1870
+#, python-format
+msgid "%(username)s karma is %(reputation)s"
+msgstr "%(username)s karma je %(reputation)s"
+
+#: models/__init__.py:1880
+#, python-format
+msgid "one gold badge"
+msgid_plural "%(count)d gold badges"
+msgstr[0] "jedna zlatna značka"
+msgstr[1] "%(count)d zlatnih znački"
+
+#: models/__init__.py:1887
+#, python-format
+msgid "one silver badge"
+msgid_plural "%(count)d silver badges"
+msgstr[0] "jedna srebrna značka"
+msgstr[1] "%(count)d srebrnih znački"
+
+#: models/__init__.py:1894
+#, python-format
+msgid "one bronze badge"
+msgid_plural "%(count)d bronze badges"
+msgstr[0] "jedna brončana značka"
+msgstr[1] "%(count)d brončanih znački"
+
+#: models/__init__.py:1905
+#, python-format
+msgid "%(item1)s and %(item2)s"
+msgstr "%(item1)s i %(item2)s"
+
+#: models/__init__.py:1909
+#, python-format
+msgid "%(user)s has %(badges)s"
+msgstr "%(user)s ima %(badges)s"
+
+#: models/__init__.py:2389
+#, python-format
+msgid "\"%(title)s\""
+msgstr "\"%(title)s\""
+
+#: models/__init__.py:2542
+#, python-format
+msgid "Congratulations, you have received a badge '%(badge_name)s'. Check out <a href=\"%(user_profile)s\">your profile</a>."
+msgstr "Čestitamo, dobili ste značku '%(badge_name)s'. Provjerite <a href=\"%(user_profile)s\">vaš profil</a>."
+
+#: models/__init__.py:2745
+#: views/commands.py:460
+msgid "Your tag subscription was saved, thanks!"
+msgstr "Vaša pretplata na oznaku je sačuvana, hvala!"
+
+#: models/badges.py:129
+#, python-format
+msgid "Deleted own post with %(votes)s or more upvotes"
+msgstr "Obrisani postovi sa %(votes)s ili više pozitivnih glasova"
+
+#: models/badges.py:133
+msgid "Disciplined"
+msgstr "Discipliniran"
+
+#: models/badges.py:151
+#, python-format
+msgid "Deleted own post with %(votes)s or more downvotes"
+msgstr "Obrisani postovi sa %(votes)s ili više negativnih glasova"
+
+#: models/badges.py:155
+msgid "Peer Pressure"
+msgstr "Pritisak Skupine"
+
+#: models/badges.py:174
+#, python-format
+msgid "Received at least %(votes)s upvote for an answer for the first time"
+msgstr "Prvi put primljeno najmanje %(votes)s pozitivnih glasova za odgovor"
+
+#: models/badges.py:178
+msgid "Teacher"
+msgstr "Učitelj"
+
+#: models/badges.py:218
+msgid "Supporter"
+msgstr "Pristalica"
+
+#: models/badges.py:219
+msgid "First upvote"
+msgstr "Prvi pozitivan glas"
+
+#: models/badges.py:227
+msgid "Critic"
+msgstr "Kritičar"
+
+#: models/badges.py:228
+msgid "First downvote"
+msgstr "Prvi negativan glas"
+
+#: models/badges.py:237
+msgid "Civic Duty"
+msgstr "Građanska Dužnost"
+
+#: models/badges.py:238
+#, python-format
+msgid "Voted %(num)s times"
+msgstr "Glasano %(num)s puta"
+
+#: models/badges.py:252
+#, python-format
+msgid "Answered own question with at least %(num)s up votes"
+msgstr "Odgovor na svoje pitanje sa najmanje %(num)s pozitivnih odgovora"
+
+#: models/badges.py:256
+msgid "Self-Learner"
+msgstr "Samouk"
+
+#: models/badges.py:304
+msgid "Nice Answer"
+msgstr "Lijep odgovor"
+
+#: models/badges.py:309
+#: models/badges.py:321
+#: models/badges.py:333
+#, python-format
+msgid "Answer voted up %(num)s times"
+msgstr "Odgovor pozitivno glasan %(num)s puta"
+
+#: models/badges.py:316
+msgid "Good Answer"
+msgstr "Dobar Odgovor"
+
+#: models/badges.py:328
+msgid "Great Answer"
+msgstr "Odličan Odgovor"
+
+#: models/badges.py:340
+msgid "Nice Question"
+msgstr "Lijepo Pitanje"
+
+#: models/badges.py:345
+#: models/badges.py:357
+#: models/badges.py:369
+#, python-format
+msgid "Question voted up %(num)s times"
+msgstr "Pitanje pozitivno glasano %(num)s puta"
+
+#: models/badges.py:352
+msgid "Good Question"
+msgstr "Dobro Pitanje"
+
+#: models/badges.py:364
+msgid "Great Question"
+msgstr "Odlično pitanje"
+
+#: models/badges.py:376
+msgid "Student"
+msgstr "Student"
+
+#: models/badges.py:381
+msgid "Asked first question with at least one up vote"
+msgstr "Postavljeno prvo pitanje s najmanje jednim pozitivnim glasom"
+
+#: models/badges.py:414
+msgid "Popular Question"
+msgstr "Popularno Pitanje"
+
+#: models/badges.py:418
+#: models/badges.py:429
+#: models/badges.py:441
+#, python-format
+msgid "Asked a question with %(views)s views"
+msgstr "Postavljeno pitanje sa %(views)s pregleda"
+
+#: models/badges.py:425
+msgid "Notable Question"
+msgstr "Značajno Pitanje"
+
+#: models/badges.py:436
+msgid "Famous Question"
+msgstr "Slavno Pitanje"
+
+#: models/badges.py:450
+msgid "Asked a question and accepted an answer"
+msgstr "Postavljeno pitanje i prihvaćen odgovor"
+
+#: models/badges.py:453
+msgid "Scholar"
+msgstr "Naučnik"
+
+#: models/badges.py:495
+msgid "Enlightened"
+msgstr "Nadahnut"
+
+#: models/badges.py:499
+#, python-format
+msgid "First answer was accepted with %(num)s or more votes"
+msgstr "Prvi odgovor je prihvaćen sa %(num)s ili više glasova"
+
+#: models/badges.py:507
+msgid "Guru"
+msgstr "Guru"
+
+#: models/badges.py:510
+#, python-format
+msgid "Answer accepted with %(num)s or more votes"
+msgstr "Odgovor prihvaćen sa %(num)s ili više glasova"
+
+#: models/badges.py:518
+#, python-format
+msgid "Answered a question more than %(days)s days later with at least %(votes)s votes"
+msgstr "Odgovoreno na pitanje više od %(days)s dana kasnije sa najmanje %(votes)s glasova"
+
+#: models/badges.py:525
+msgid "Necromancer"
+msgstr "Čarobnjak"
+
+#: models/badges.py:548
+msgid "Citizen Patrol"
+msgstr "Građanska Patrola"
+
+#: models/badges.py:551
+msgid "First flagged post"
+msgstr "Prvi post označen zastavom"
+
+#: models/badges.py:563
+msgid "Cleanup"
+msgstr "Čišćenje"
+
+#: models/badges.py:566
+msgid "First rollback"
+msgstr "Prvo vraćanje unazad"
+
+#: models/badges.py:577
+msgid "Pundit"
+msgstr "Pundit"
+
+#: models/badges.py:580
+msgid "Left 10 comments with score of 10 or more"
+msgstr "Ostavi 10 komentara da rezultatom 10 ili više"
+
+#: models/badges.py:612
+msgid "Editor"
+msgstr "Urednik"
+
+#: models/badges.py:615
+msgid "First edit"
+msgstr "Prvo uređivanje"
+
+#: models/badges.py:623
+msgid "Associate Editor"
+msgstr "Pomoćnik Urednika"
+
+#: models/badges.py:627
+#, python-format
+msgid "Edited %(num)s entries"
+msgstr "Uređeno %(num)s unosa"
+
+#: models/badges.py:634
+msgid "Organizer"
+msgstr "Organizator"
+
+#: models/badges.py:637
+msgid "First retag"
+msgstr "Prvo ponovno označavanje"
+
+#: models/badges.py:644
+msgid "Autobiographer"
+msgstr "Životopisac"
+
+#: models/badges.py:647
+msgid "Completed all user profile fields"
+msgstr "Ispunjena sva polja korisničkog profila"
+
+#: models/badges.py:663
+#, python-format
+msgid "Question favorited by %(num)s users"
+msgstr "Omiljeno pitanje kod %(num)s korisnika"
+
+#: models/badges.py:689
+msgid "Stellar Question"
+msgstr "Zvjezdano Pitanje"
+
+#: models/badges.py:698
+msgid "Favorite Question"
+msgstr "Omiljeno Pitanje"
+
+#: models/badges.py:710
+msgid "Enthusiast"
+msgstr "Entuzijast"
+
+#: models/badges.py:714
+#, python-format
+msgid "Visited site every day for %(num)s days in a row"
+msgstr "Posjetio stranicu svaki dan %(num)s dana u nizu"
+
+#: models/badges.py:732
+msgid "Commentator"
+msgstr "Komentator"
+
+#: models/badges.py:736
+#, python-format
+msgid "Posted %(num_comments)s comments"
+msgstr "Objavio %(num_comments)s komentara"
+
+#: models/badges.py:752
+msgid "Taxonomist"
+msgstr "Klasifikator"
+
+#: models/badges.py:756
+#, python-format
+msgid "Created a tag used by %(num)s questions"
+msgstr "Kreirao oznaku korištenu u %(num)s pitanja"
+
+#: models/badges.py:774
+msgid "Expert"
+msgstr "Stručnjak"
+
+#: models/badges.py:777
+msgid "Very active in one tag"
+msgstr "Vrlo aktivan u jednoj oznaci"
+
+#: models/post.py:1071
+msgid "Sorry, this question has been deleted and is no longer accessible"
+msgstr "Ovo pitanje je obrisano i više nije dostupno."
+
+#: models/post.py:1087
+msgid "Sorry, the answer you are looking for is no longer available, because the parent question has been removed"
+msgstr "Odgovor koji tražite više nije dostupan zato što je roditeljsko pitanje obrisano"
+
+#: models/post.py:1094
+msgid "Sorry, this answer has been removed and is no longer accessible"
+msgstr "Ovaj odgovor je obrisan i više nije dostupan"
+
+#: models/post.py:1110
+msgid "Sorry, the comment you are looking for is no longer accessible, because the parent question has been removed"
+msgstr "Komentar koji tražite više nije dostupan zato što je roditeljsko pitanje obrisano"
+
+#: models/post.py:1117
+msgid "Sorry, the comment you are looking for is no longer accessible, because the parent answer has been removed"
+msgstr "Komentar koji tražite više nije dostupan zato što je roditeljski odgovor obrisan"
+
+#: models/question.py:54
+#, python-format
+msgid "\" and \"%s\""
+msgstr "\" i \"%s\""
+
+#: models/question.py:57
+msgid "\" and more"
+msgstr "\" i više"
+
+#: models/reply_by_email.py:71
+msgid "edited by email"
+msgstr "uređeno putem emaila"
+
+#: models/repute.py:143
+#, python-format
+msgid "<em>Changed by moderator. Reason:</em> %(reason)s"
+msgstr "<em>Promijenio moderator. Razlog:</em> %(reason)s"
+
+#: models/repute.py:154
+#, python-format
+msgid "%(points)s points were added for %(username)s's contribution to question %(question_title)s"
+msgstr "%(points)s bodova je dodano zbog doprinosa korisnika %(username)s pitanju %(question_title)s"
+
+#: models/repute.py:159
+#, python-format
+msgid "%(points)s points were subtracted for %(username)s's contribution to question %(question_title)s"
+msgstr "%(points)s bodova je oduzeto zbog doprinosa korisnika %(username)s pitanju %(question_title)s"
+
+#: models/tag.py:106
+msgid "interesting"
+msgstr "zanimljivo"
+
+#: models/tag.py:106
+msgid "ignored"
+msgstr "ignorirano"
+
+#: models/user.py:266
+msgid "Entire forum"
+msgstr "Cjeli forum"
+
+#: models/user.py:267
+msgid "Questions that I asked"
+msgstr "Moja pitanja"
+
+#: models/user.py:268
+msgid "Questions that I answered"
+msgstr "Moji odgovori na pitanja"
+
+#: models/user.py:269
+msgid "Individually selected questions"
+msgstr "Individualno odabrana pitanja"
+
+#: models/user.py:270
+msgid "Mentions and comment responses"
+msgstr "Odgovori na spomen i komentar"
+
+#: models/user.py:273
+msgid "Instantly"
+msgstr "Odmah"
+
+#: models/user.py:274
+msgid "Daily"
+msgstr "Dnevno"
+
+#: models/user.py:275
+msgid "Weekly"
+msgstr "Tjedno"
+
+#: models/user.py:276
+msgid "No email"
+msgstr "Bez emaila"
+
+#: skins/common/templates/authopenid/authopenid_macros.html:63
+msgid "Please enter your <span>user name</span>, then sign in"
+msgstr "Unesite vaše <span>korisničko ime</span>, zatim se prijavite"
+
+#: skins/common/templates/authopenid/authopenid_macros.html:64
+#: skins/common/templates/authopenid/signin.html:97
+msgid "(or select another login method above)"
+msgstr "(ili odaberite drugi način prijave gore)"
+
+#: skins/common/templates/authopenid/authopenid_macros.html:66
+#: skins/common/templates/authopenid/signin.html:113
+msgid "Sign in"
+msgstr "Prijavi me"
+
+#: skins/common/templates/authopenid/changeemail.html:2
+#: skins/common/templates/authopenid/changeemail.html:8
+#: skins/common/templates/authopenid/changeemail.html:49
+msgid "Change Email"
+msgstr "Promjeni Email"
+
+#: skins/common/templates/authopenid/changeemail.html:10
+msgid "Save your email address"
+msgstr "Spremi email adresu"
+
+#: skins/common/templates/authopenid/changeemail.html:15
+#, python-format
+msgid ""
+"<span class=\\\"strong big\\\">Enter your new email into the box below</span> if \n"
+"you'd like to use another email for <strong>update subscriptions</strong>.\n"
+"<br>Currently you are using <strong>%%(email)s</strong>"
+msgstr ""
+"<span class=\\\"strong big\\\">Unesite vašu novu email adrestu ispod</span> ako \n"
+"ako želite koristiti drugu email adresu za <strong>ažuriranje pretplata</strong>.\n"
+"<br>Trenutno koristite <strong>%%(email)s</strong>"
+
+#: skins/common/templates/authopenid/changeemail.html:19
+#, python-format
+msgid ""
+"<span class='strong big'>Please enter your email address in the box below.</span>\n"
+"Valid email address is required on this Q&amp;A forum. If you like, \n"
+"you can <strong>receive updates</strong> on interesting questions or entire\n"
+"forum via email. Also, your email is used to create a unique \n"
+"<a href='%%(gravatar_faq_url)s'><strong>gravatar</strong></a> image for your\n"
+"account. Email addresses are never shown or otherwise shared with anybody\n"
+"else."
+msgstr ""
+"<span class='strong big'>Unesite vašu email adresu ispod.</span>\n"
+"Ispravna email adresa potrebna je za P&amp;O forum. Ako želite, \n"
+"možete <strong>primati dopune</strong> interesantnih pitanja ili cijelog\n"
+"foruma putem emaila. Također vaš email se koristi za kreiranje jedinstvene \n"
+"<a href='%%(gravatar_faq_url)s'><strong>gravatar</strong></a> slike za vaš\n"
+"račun. Email adrese se ne prikazuju niti dijele s drugima"
+
+#: skins/common/templates/authopenid/changeemail.html:38
+msgid ""
+"<strong>Your new Email:</strong> \n"
+"(will <strong>not</strong> be shown to anyone, must be valid)"
+msgstr ""
+"<strong>Vaš novi Email:</strong> \n"
+"(<strong>neće</strong> biti prikazan nikome, mora biti ispravan)"
+
+#: skins/common/templates/authopenid/changeemail.html:49
+msgid "Save Email"
+msgstr "Spremi Email"
+
+#: skins/common/templates/authopenid/changeemail.html:51
+#: skins/default/templates/answer_edit.html:25
+#: skins/default/templates/close.html:16
+#: skins/default/templates/feedback.html:64
+#: skins/default/templates/question_edit.html:36
+#: skins/default/templates/question_retag.html:22
+#: skins/default/templates/reopen.html:27
+#: skins/default/templates/subscribe_for_tags.html:16
+#: skins/default/templates/user_profile/user_edit.html:102
+msgid "Cancel"
+msgstr "Odustani"
+
+#: skins/common/templates/authopenid/changeemail.html:58
+msgid "Validate email"
+msgstr "Potvrdi email"
+
+#: skins/common/templates/authopenid/changeemail.html:61
+#, python-format
+msgid ""
+"<span class=\\\"strong big\\\">An email with a validation link has been sent to \n"
+"%%(email)s.</span> Please <strong>follow the emailed link</strong> with your \n"
+"web browser. Email validation is necessary to help insure the proper use of \n"
+"email on <span class=\\\"orange\\\">Q&amp;A</span>. If you would like to use \n"
+"<strong>another email</strong>, please <a \n"
+"href='%%(change_email_url)s'><strong>change it again</strong></a>."
+msgstr ""
+"<span class=\\\"strong big\\\">Poslan vam je email s potvrdnom vezom \n"
+"%%(email)s.</span> <strong>Otvorite vezu u emailu</strong> sa \n"
+"sa preglednikom. Potvrda je potrebna radi uvjeravanja u ispravno korištenje\n"
+"emaila u <span class=\\\"orange\\\">P&amp;O</span>. Ako želite koristiti \n"
+"<strong>drugi email</strong>, <a \n"
+"href='%%(change_email_url)s'><strong>promjenite ga ponovo</strong></a>."
+
+#: skins/common/templates/authopenid/changeemail.html:70
+msgid "Email not changed"
+msgstr "Email nije promjenjen"
+
+#: skins/common/templates/authopenid/changeemail.html:73
+#, python-format
+msgid ""
+"<span class=\\\"strong big\\\">Your email address %%(email)s has not been changed.\n"
+"</span> If you decide to change it later - you can always do it by editing \n"
+"it in your user profile or by using the <a \n"
+"href='%%(change_email_url)s'><strong>previous form</strong></a> again."
+msgstr ""
+"<span class=\\\"strong big\\\">Vaša email adresa %%(email)s nije promijenjena.\n"
+"</span> Ako je kasnije odlučite promijeniti - to možete učinit \n"
+"u promjenom vašeg korisničkog profila ili korištenjem <a \n"
+"href='%%(change_email_url)s'><strong>prethodnog obrasca</strong></a> ponovo."
+
+#: skins/common/templates/authopenid/changeemail.html:80
+msgid "Email changed"
+msgstr "Email je promjenjen"
+
+#: skins/common/templates/authopenid/changeemail.html:83
+#, python-format
+msgid ""
+"\n"
+"<span class='big strong'>Your email address is now set to %%(email)s.</span> \n"
+"Updates on the questions that you like most will be sent to this address. \n"
+"Email notifications are sent once a day or less frequently - only when there \n"
+"are any news."
+msgstr ""
+"\n"
+"<span class='big strong'>Vaša email adresa je promijenjena u %%(email)s.</span> \n"
+"Dopune pitanja biti će poslane na ovu email adresu. \n"
+"Email napomene se šalju jednom dnevno - samo kad ima novosti. "
+
+#: skins/common/templates/authopenid/changeemail.html:91
+msgid "Email verified"
+msgstr "Email potvrđen"
+
+#: skins/common/templates/authopenid/changeemail.html:94
+msgid ""
+"<span class=\\\"big strong\\\">Thank you for verifying your email!</span> Now \n"
+"you can <strong>ask</strong> and <strong>answer</strong> questions. Also if \n"
+"you find a very interesting question you can <strong>subscribe for the \n"
+"updates</strong> - then will be notified about changes <strong>once a day</strong>\n"
+"or less frequently."
+msgstr ""
+"<span class=\\\"big strong\\\">Hvala na potvrdi emaila!</span> Sada \n"
+"možete <strong>postaviti</strong> i <strong>odgovarati</strong> na pitanja. \n"
+"Ako nađete interesantno pitanje možete se <strong>pretplatiti na dopune \n"
+"pitanja</strong> - o promjenama ćete biti obaviješteni <strong>jednom dnevno</strong>\n"
+"ili manje učestalo."
+
+#: skins/common/templates/authopenid/changeemail.html:102
+msgid "Validation email not sent"
+msgstr "Potvrdni email nije poslan"
+
+#: skins/common/templates/authopenid/changeemail.html:105
+#, python-format
+msgid ""
+"<span class='big strong'>Your current email address %%(email)s has been \n"
+"validated before</span> so the new key was not sent. You can <a \n"
+"href='%%(change_link)s'>change</a> email used for update subscriptions if \n"
+"necessary."
+msgstr ""
+"<span class='big strong'>Vaša trenutna email adresa %%(email)s je \n"
+"već potvrđena</span> stoga nije poslan novi ključ. Ako je potrebno <a \n"
+"href='%%(change_link)s'>možete promijeniti</a> email za ažuriranje \n"
+"pretplata."
+
+#: skins/common/templates/authopenid/complete.html:21
+msgid "Registration"
+msgstr "Registracija"
+
+#: skins/common/templates/authopenid/complete.html:23
+msgid "User registration"
+msgstr "Registracija korisnika"
+
+#: skins/common/templates/authopenid/complete.html:60
+msgid "<strong>Receive forum updates by email</strong>"
+msgstr "<strong>Primajte dopune s foruma putem emaila</strong>"
+
+#: skins/common/templates/authopenid/complete.html:64
+#: skins/common/templates/authopenid/signup_with_password.html:46
+msgid "please select one of the options above"
+msgstr "odaberite jednu od gornjih mogućenosti"
+
+#: skins/common/templates/authopenid/complete.html:67
+#: skins/common/templates/authopenid/signup_with_password.html:4
+#: skins/common/templates/authopenid/signup_with_password.html:53
+msgid "Signup"
+msgstr "Upiši me"
+
+#: skins/common/templates/authopenid/confirm_email.txt:1
+msgid "Thank you for registering at our Q&A forum!"
+msgstr "Hvala što ste se registrirali na naš P&O forum!"
+
+#: skins/common/templates/authopenid/confirm_email.txt:3
+msgid "Your account details are:"
+msgstr "Detalji vašeg računa su:"
+
+#: skins/common/templates/authopenid/confirm_email.txt:5
+msgid "Username:"
+msgstr "Korisničko ime:"
+
+#: skins/common/templates/authopenid/confirm_email.txt:6
+msgid "Password:"
+msgstr "Lozinka:"
+
+#: skins/common/templates/authopenid/confirm_email.txt:8
+msgid "Please sign in here:"
+msgstr "Upišite se ovdje:"
+
+#: skins/common/templates/authopenid/confirm_email.txt:11
+#: skins/common/templates/authopenid/email_validation.txt:13
+msgid ""
+"Sincerely,\n"
+"Q&A Forum Administrator"
+msgstr ""
+"S štovanjem,\n"
+"P&O Forum Administrator"
+
+#: skins/common/templates/authopenid/email_validation.txt:1
+msgid "Greetings from the Q&A forum"
+msgstr "Pozdrav od P&O foruma"
+
+#: skins/common/templates/authopenid/email_validation.txt:3
+msgid "To make use of the Forum, please follow the link below:"
+msgstr "Za korištenje Foruma, pratite vezu ispod:"
+
+#: skins/common/templates/authopenid/email_validation.txt:7
+msgid "Following the link above will help us verify your email address."
+msgstr "Pratite vezu iznad kako bi mogli potvrdite vašu email adresu."
+
+#: skins/common/templates/authopenid/email_validation.txt:9
+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 ""
+"Ako smatrate da je ova poruka poslana greškom - \n"
+"daljnji potezi nisu potrebni. Ignorirajte ovu poruku. \n"
+"Ispričavamo se zbog greške"
+
+#: skins/common/templates/authopenid/logout.html:3
+msgid "Logout"
+msgstr "Sign out"
+
+#: skins/common/templates/authopenid/logout.html:5
+msgid "You have successfully logged out"
+msgstr "Uspješno ste se odjavili"
+
+#: skins/common/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 "Moguće je da ste i dalje prijavljeni kod vašeg OpenID pružatelja usluge pristupa. Ako želite odjavite se sa vašeg pružatelja usluge pristupa."
+
+#: skins/common/templates/authopenid/signin.html:4
+msgid "User login"
+msgstr "User login"
+
+#: skins/common/templates/authopenid/signin.html:14
+#, python-format
+msgid ""
+"\n"
+" Your answer to %(title)s %(summary)s will be posted once you log in\n"
+" "
+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>"
+
+#: skins/common/templates/authopenid/signin.html:21
+#, python-format
+msgid ""
+"Your question \n"
+" %(title)s %(summary)s will be posted once you log in\n"
+" "
+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>"
+
+#: skins/common/templates/authopenid/signin.html:28
+msgid "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."
+msgstr "Izaberite vaš omiljeni servis za prijavu korištenjem sigurnog OpenID-a ili slične tehnologije. Lozinka vašeg vanjskog servisa uvijek ostaje tajna i ne morate pamtiti ili kreirati drugu. "
+
+#: skins/common/templates/authopenid/signin.html:31
+msgid "It's a good idea to make sure that your existing login methods still work, or add a new one. Please click any of the icons below to check/change or add new login methods."
+msgstr "Dobra je ideja provjeriti da li vaši postojeći načini prijave rade ili dodati novi način. Kliknite na bilo koju ikonu dolje i provjerite/promijenite ili dodajte novu metodu za prijavu."
+
+#: skins/common/templates/authopenid/signin.html:33
+msgid "Please add a more permanent login method by clicking one of the icons below, to avoid logging in via email each time."
+msgstr "Dodajte trajniji način prijave klikom na jednu od ikona dolje, kako bi ste izbjegli prijavljivanje putem email svaki put."
+
+#: skins/common/templates/authopenid/signin.html:37
+msgid "Click on one of the icons below to add a new login method or re-validate an existing one."
+msgstr "Kliknite na jednu od ikona dolje za dodavanje novih načina prijave ili ponovnu potvrdu postojećih."
+
+#: skins/common/templates/authopenid/signin.html:39
+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 "Nemate način prijave, dodajte jedan ili više klikom na jednu od ikona dolje."
+
+#: skins/common/templates/authopenid/signin.html:42
+msgid "Please check your email and visit the enclosed link to re-connect to your account"
+msgstr "Provjerite vaš email i posjetite vezu u prilogu radi ponovnog spajanja vašeg računa"
+
+#: skins/common/templates/authopenid/signin.html:89
+msgid "or enter your <span>user name and password</span>, then sign in"
+msgstr "ili unesite vaše <span>korisničko ime i lozinku</span>, zatim se prijavite"
+
+#: skins/common/templates/authopenid/signin.html:93
+msgid "Please, sign in"
+msgstr "Prijavite se"
+
+#: skins/common/templates/authopenid/signin.html:100
+msgid "Login failed, please try again"
+msgstr "Prijava nije uspjela, pokušajte ponovo"
+
+#: skins/common/templates/authopenid/signin.html:104
+msgid "Login or email"
+msgstr "Korisničko ime ili email"
+
+#: skins/common/templates/authopenid/signin.html:108
+#: utils/forms.py:169
+msgid "Password"
+msgstr "Lozinka"
+
+#: skins/common/templates/authopenid/signin.html:120
+msgid "To change your password - please enter the new one twice, then submit"
+msgstr "Za promjenu vaše lozinke unesite novu dva puta zatim podnesite"
+
+#: skins/common/templates/authopenid/signin.html:124
+msgid "New password"
+msgstr "Nova lozinka"
+
+#: skins/common/templates/authopenid/signin.html:133
+msgid "Please, retype"
+msgstr "Ponovo unesite"
+
+#: skins/common/templates/authopenid/signin.html:157
+msgid "Here are your current login methods"
+msgstr "Ovo su vaše trenutni načini prijave"
+
+#: skins/common/templates/authopenid/signin.html:161
+msgid "provider"
+msgstr "pružatelj usluge pristupa"
+
+#: skins/common/templates/authopenid/signin.html:162
+msgid "last used"
+msgstr "zadnji korišten"
+
+#: skins/common/templates/authopenid/signin.html:163
+msgid "delete, if you like"
+msgstr "obrišite ako želite"
+
+#: skins/common/templates/authopenid/signin.html:177
+#: skins/common/templates/question/answer_controls.html:13
+#: skins/common/templates/question/question_controls.html:4
+msgid "delete"
+msgstr "obriši"
+
+#: skins/common/templates/authopenid/signin.html:179
+msgid "cannot be deleted"
+msgstr "ne može se obrisati"
+
+#: skins/common/templates/authopenid/signin.html:192
+msgid "Still have trouble signing in?"
+msgstr "Imate i dalje problema s prijavom?"
+
+#: skins/common/templates/authopenid/signin.html:197
+msgid "Please, enter your email address below and obtain a new key"
+msgstr "Unesite vašu email adresu ispod i preuzmite novi ključ"
+
+#: skins/common/templates/authopenid/signin.html:199
+msgid "Please, enter your email address below to recover your account"
+msgstr "Unesite vašu email adresu ispod za obnovu vašeg računa"
+
+#: skins/common/templates/authopenid/signin.html:202
+msgid "recover your account via email"
+msgstr "obnovite račun putem emaila"
+
+#: skins/common/templates/authopenid/signin.html:213
+msgid "Send a new recovery key"
+msgstr "Pošalji novi ključ za obnovu"
+
+#: skins/common/templates/authopenid/signin.html:215
+msgid "Recover your account via email"
+msgstr "Obnovite račun putem emaila"
+
+#: skins/common/templates/authopenid/signup_with_password.html:10
+msgid "Please register by clicking on any of the icons below"
+msgstr "Registrirajte se klikom na jednu od ikona ispod"
+
+#: skins/common/templates/authopenid/signup_with_password.html:23
+msgid "or create a new user name and password here"
+msgstr "ili kreirajte novo korisničko ime i lozinku ovdje"
+
+#: skins/common/templates/authopenid/signup_with_password.html:25
+msgid "Create login name and password"
+msgstr "Kreiraj korisničko ime i lozinku"
+
+#: skins/common/templates/authopenid/signup_with_password.html:26
+msgid ""
+"<span class='strong big'>If you prefer, create your forum login name and \n"
+"password here. However</span>, please keep in mind that we also support \n"
+"<strong>OpenID</strong> login method. With <strong>OpenID</strong> you can \n"
+"simply reuse your external login (e.g. Gmail or AOL) without ever sharing \n"
+"your login details with anyone and having to remember yet another password."
+msgstr ""
+"<span class='strong big'>Ako želite, kreirajte vaše forum ime i lozinku ovdje. \n"
+"</span> Imajte na umu da da podržavamo \n"
+"<strong>OpenID</strong> način prijave. Sa <strong>OpenID-om</strong> možete \n"
+"jednostavno upotrijebiti postojeći račun (npr. Gmail ili Yahoo) bez dijeljenja \n"
+"vaših podataka za prijavu ili potrebe za pamćenjem nove lozinke."
+
+#: skins/common/templates/authopenid/signup_with_password.html:41
+msgid "<strong>Receive periodic updates by email</strong>"
+msgstr "<strong>Periodno primaj dopune putem emaila</strong>"
+
+#: skins/common/templates/authopenid/signup_with_password.html:50
+msgid "Please read and type in the two words below to help us prevent automated account creation."
+msgstr "Pročitajte i unesite dvije riječi ispod i pomozite nam spriječiti automatsko kreiranje računa."
+
+#: skins/common/templates/authopenid/signup_with_password.html:55
+msgid "or"
+msgstr "ili"
+
+#: skins/common/templates/authopenid/signup_with_password.html:56
+msgid "return to OpenID login"
+msgstr "vrati na OpenID prijavu"
+
+#: skins/common/templates/avatar/add.html:3
+msgid "add avatar"
+msgstr "dodaj avatar"
+
+#: skins/common/templates/avatar/add.html:5
+msgid "Change avatar"
+msgstr "Promijeni avatar"
+
+#: skins/common/templates/avatar/add.html:6
+#: skins/common/templates/avatar/change.html:7
+msgid "Your current avatar: "
+msgstr "Vaš trenutni avatar:"
+
+#: skins/common/templates/avatar/add.html:9
+#: skins/common/templates/avatar/change.html:11
+msgid "You haven't uploaded an avatar yet. Please upload one now."
+msgstr "Niste još poslali avatar. Pošaljite ga."
+
+#: skins/common/templates/avatar/add.html:13
+msgid "Upload New Image"
+msgstr "Pošalji Novu Sliku"
+
+#: skins/common/templates/avatar/change.html:4
+msgid "change avatar"
+msgstr "promjeni avatar"
+
+#: skins/common/templates/avatar/change.html:17
+msgid "Choose new Default"
+msgstr "Odaberit novi Zadani"
+
+#: skins/common/templates/avatar/change.html:22
+msgid "Upload"
+msgstr "Pošalji"
+
+#: skins/common/templates/avatar/confirm_delete.html:2
+msgid "delete avatar"
+msgstr "obriši avatar"
+
+#: skins/common/templates/avatar/confirm_delete.html:4
+msgid "Please select the avatars that you would like to delete."
+msgstr "Odaberite avatare koje želite obrisati."
+
+#: skins/common/templates/avatar/confirm_delete.html:6
+#, python-format
+msgid "You have no avatars to delete. Please <a href=\"%(avatar_change_url)s\">upload one</a> now."
+msgstr "Nema avatara za brisanje. <a href=\"%(avatar_change_url)s\">Pošaljite jedan</a> sad."
+
+#: skins/common/templates/avatar/confirm_delete.html:12
+msgid "Delete These"
+msgstr "Obriši Ove"
+
+#: skins/common/templates/question/answer_controls.html:2
+msgid "swap with question"
+msgstr "zamjeni sa pitanjem"
+
+#: skins/common/templates/question/answer_controls.html:7
+msgid "permanent link"
+msgstr "stalna veza"
+
+#: skins/common/templates/question/answer_controls.html:8
+#: skins/default/templates/widgets/answer_edit_tips.html:45
+#: skins/default/templates/widgets/question_edit_tips.html:40
+msgid "link"
+msgstr "veza"
+
+#: skins/common/templates/question/answer_controls.html:13
+#: skins/common/templates/question/question_controls.html:4
+msgid "undelete"
+msgstr "vrati obrisano"
+
+#: skins/common/templates/question/answer_controls.html:19
+msgid "remove offensive flag"
+msgstr "ukloni zastavu uvredljivo"
+
+#: skins/common/templates/question/answer_controls.html:21
+#: skins/common/templates/question/question_controls.html:16
+msgid "remove flag"
+msgstr "ukloni zastavu"
+
+#: skins/common/templates/question/answer_controls.html:26
+#: skins/common/templates/question/answer_controls.html:35
+#: skins/common/templates/question/question_controls.html:14
+#: skins/common/templates/question/question_controls.html:20
+#: skins/common/templates/question/question_controls.html:27
+msgid "report as offensive (i.e containing spam, advertising, malicious text, etc.)"
+msgstr "prijavi kao uvredljivo (npr. sadrži neželjen sadržaj, oglase, zlonamjeran tekst itd.)"
+
+#: skins/common/templates/question/answer_controls.html:28
+#: skins/common/templates/question/answer_controls.html:37
+#: skins/common/templates/question/question_controls.html:22
+#: skins/common/templates/question/question_controls.html:29
+msgid "flag offensive"
+msgstr "označi zastavom uvredljivo"
+
+#: skins/common/templates/question/answer_controls.html:41
+#: skins/common/templates/question/question_controls.html:36
+#: skins/default/templates/macros.html:311
+#: skins/default/templates/revisions.html:38
+#: skins/default/templates/revisions.html:41
+msgid "edit"
+msgstr "uredi"
+
+#: skins/common/templates/question/answer_vote_buttons.html:6
+#: skins/default/templates/user_profile/user_stats.html:24
+msgid "this answer has been selected as correct"
+msgstr "ovaj odgovor je odabran kao točan"
+
+#: skins/common/templates/question/answer_vote_buttons.html:8
+msgid "mark this answer as correct (click again to undo)"
+msgstr "označi ovaj odgovor kao točan (kliknite ponovo za poništavanje)"
+
+#: skins/common/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 "Pitanje je zatvoreno zbog sljedećih razloga <b>\"%(close_reason)s\"</b> <i>od strane"
+
+#: skins/common/templates/question/closed_question_info.html:4
+#, python-format
+msgid "close date %(closed_at)s"
+msgstr "datum zatvaranja %(closed_at)s"
+
+#: skins/common/templates/question/question_controls.html:6
+msgid "reopen"
+msgstr "ponovo otvori"
+
+#: skins/common/templates/question/question_controls.html:8
+#: skins/default/templates/user_profile/user_inbox.html:67
+msgid "close"
+msgstr "zatvori"
+
+#: skins/common/templates/question/question_controls.html:35
+msgid "retag"
+msgstr "ponovo označi"
+
+#: skins/common/templates/widgets/edit_post.html:22
+msgid ", one of these is required"
+msgstr ", jedno od ovoga je nužno"
+
+#: skins/common/templates/widgets/edit_post.html:31
+#: skins/common/templates/widgets/edit_post.html:36
+msgid "tags:"
+msgstr "oznake:"
+
+#: skins/common/templates/widgets/edit_post.html:32
+msgid "(required)"
+msgstr "(nužno)"
+
+#: skins/common/templates/widgets/edit_post.html:58
+msgid "Toggle the real time Markdown editor preview"
+msgstr "Aktiviraj/deaktiviraj prikaz Markdown uređivača u stvarnom vremenu"
+
+#: skins/common/templates/widgets/edit_post.html:60
+#: skins/default/templates/answer_edit.html:61
+#: skins/default/templates/answer_edit.html:64
+#: skins/default/templates/ask.html:49
+#: skins/default/templates/ask.html:52
+#: skins/default/templates/question_edit.html:73
+#: skins/default/templates/question_edit.html:76
+#: skins/default/templates/question/javascript.html:85
+#: skins/default/templates/question/javascript.html:88
+msgid "hide preview"
+msgstr "sakri prikaz"
+
+#: skins/common/templates/widgets/related_tags.html:3
+#: skins/default/templates/tags.html:4
+msgid "Tags"
+msgstr "Oznake"
+
+#: skins/common/templates/widgets/tag_selector.html:4
+msgid "Interesting tags"
+msgstr "Zanimljive oznake"
+
+#: skins/common/templates/widgets/tag_selector.html:19
+#: skins/common/templates/widgets/tag_selector.html:36
+msgid "add"
+msgstr "+"
+
+#: skins/common/templates/widgets/tag_selector.html:21
+msgid "Ignored tags"
+msgstr "Ignorirane oznake"
+
+#: skins/common/templates/widgets/tag_selector.html:38
+msgid "Display tag filter"
+msgstr "Prikaži filter oznaka"
+
+#: skins/default/templates/404.jinja.html:3
+#: skins/default/templates/404.jinja.html:10
+msgid "Page not found"
+msgstr "Stranica nije pronađena"
+
+#: skins/default/templates/404.jinja.html:13
+msgid "Sorry, could not find the page you requested."
+msgstr "Tražena stranica nije pronađena."
+
+#: skins/default/templates/404.jinja.html:15
+msgid "This might have happened for the following reasons:"
+msgstr "Ovo se moglo dogoditi zbog sljedećih razloga:"
+
+#: skins/default/templates/404.jinja.html:17
+msgid "this question or answer has been deleted;"
+msgstr "ovo pitanje ili odgovor je obrisano;"
+
+#: skins/default/templates/404.jinja.html:18
+msgid "url has error - please check it;"
+msgstr "url ima grešku - provjerite"
+
+#: skins/default/templates/404.jinja.html:19
+msgid "the page you tried to visit is protected or you don't have sufficient points, see"
+msgstr "stranice koju ste htjeli posjetiti je zaštićena ili nemate dovoljno bodova za pregled"
+
+#: skins/default/templates/404.jinja.html:19
+#: skins/default/templates/widgets/footer.html:39
+msgid "faq"
+msgstr "čpp"
+
+#: skins/default/templates/404.jinja.html:20
+msgid "if you believe this error 404 should not have occured, please"
+msgstr "ako smatrate da se 404 greška nije smjela dogoditi, "
+
+#: skins/default/templates/404.jinja.html:21
+msgid "report this problem"
+msgstr "prijavite ovaj problem"
+
+#: skins/default/templates/404.jinja.html:30
+#: skins/default/templates/500.jinja.html:11
+msgid "back to previous page"
+msgstr "natrag na prethodnu stranicu"
+
+#: skins/default/templates/404.jinja.html:31
+#: skins/default/templates/widgets/scope_nav.html:6
+msgid "see all questions"
+msgstr "sva pitanja"
+
+#: skins/default/templates/404.jinja.html:32
+msgid "see all tags"
+msgstr "sve oznake"
+
+#: skins/default/templates/500.jinja.html:3
+#: skins/default/templates/500.jinja.html:5
+msgid "Internal server error"
+msgstr "Interna greška poslužitelja"
+
+#: skins/default/templates/500.jinja.html:8
+msgid "system error log is recorded, error will be fixed as soon as possible"
+msgstr "greška na sistemu je zabilježena, greška će biti uklonjena u najkraćem mogućem vremenu"
+
+#: skins/default/templates/500.jinja.html:9
+msgid "please report the error to the site administrators if you wish"
+msgstr "ako želite prijavite grešku administratoru"
+
+#: skins/default/templates/500.jinja.html:12
+msgid "see latest questions"
+msgstr "zadnja pitanja"
+
+#: skins/default/templates/500.jinja.html:13
+msgid "see tags"
+msgstr "sve oznake"
+
+#: skins/default/templates/answer_edit.html:4
+#: skins/default/templates/answer_edit.html:10
+msgid "Edit answer"
+msgstr "Uredi odgovor"
+
+#: skins/default/templates/answer_edit.html:10
+#: skins/default/templates/question_edit.html:9
+#: skins/default/templates/question_retag.html:5
+#: skins/default/templates/revisions.html:7
+msgid "back"
+msgstr "nazad"
+
+#: skins/default/templates/answer_edit.html:14
+msgid "revision"
+msgstr "revizija"
+
+#: skins/default/templates/answer_edit.html:17
+#: skins/default/templates/question_edit.html:16
+msgid "select revision"
+msgstr "odaberite reviziju"
+
+#: skins/default/templates/answer_edit.html:24
+#: skins/default/templates/question_edit.html:35
+msgid "Save edit"
+msgstr "Sačuvaj uređeno"
+
+#: skins/default/templates/answer_edit.html:64
+#: skins/default/templates/ask.html:52
+#: skins/default/templates/question_edit.html:76
+#: skins/default/templates/question/javascript.html:88
+msgid "show preview"
+msgstr "pokaži prikaz"
+
+#: skins/default/templates/ask.html:4
+#: skins/default/templates/widgets/ask_button.html:5
+#: skins/default/templates/widgets/ask_form.html:43
+msgid "Ask Your Question"
+msgstr "Postavi Pitanje"
+
+#: skins/default/templates/badge.html:5
+#: skins/default/templates/badge.html:9
+#: skins/default/templates/user_profile/user_recent.html:19
+#: skins/default/templates/user_profile/user_stats.html:108
+#, python-format
+msgid "%(name)s"
+msgstr "%(name)s"
+
+#: skins/default/templates/badge.html:5
+msgid "Badge"
+msgstr "Značka"
+
+#: skins/default/templates/badge.html:7
+#, python-format
+msgid "Badge \"%(name)s\""
+msgstr "Značka \"%(name)s"
+
+#: skins/default/templates/badge.html:9
+#: skins/default/templates/user_profile/user_recent.html:17
+#: skins/default/templates/user_profile/user_stats.html:106
+#, python-format
+msgid "%(description)s"
+msgstr "%(description)s"
+
+#: skins/default/templates/badge.html:14
+msgid "user received this badge:"
+msgid_plural "users received this badge:"
+msgstr[0] "korisnik je dobio ovu značku:"
+msgstr[1] "korisnici su dobili ove značke:"
+
+#: skins/default/templates/badges.html:3
+#: skins/default/templates/badges.html:5
+msgid "Badges"
+msgstr "Značke"
+
+#: skins/default/templates/badges.html:7
+msgid "Community gives you awards for your questions, answers and votes."
+msgstr "Zajednica vam daje nagrade za vaša pitanja, odgovore i glasove."
+
+#: skins/default/templates/badges.html:8
+#, python-format
+msgid ""
+"Below is the list of available badges and number \n"
+" of times each type of badge has been awarded. Have ideas about fun \n"
+"badges? Please, give us your <a href='%%(feedback_faq_url)s'>feedback</a>\n"
+msgstr ""
+"Ispod se nalazi lista dostupnih znački i koliko \n"
+" puta je svaka značka nagrađena. Imate ideju o zabavnim \n"
+"značkama? Dajte nam svoje <a href='%%(feedback_faq_url)s'>svoje mišljenje</a>\n"
+
+#: skins/default/templates/badges.html:36
+msgid "Community badges"
+msgstr "Badge levels"
+
+#: skins/default/templates/badges.html:38
+msgid "gold badge: the highest honor and is very rare"
+msgstr "zlatna značka: najčasnija i vrlo je rijetka"
+
+#: skins/default/templates/badges.html:41
+msgid ""
+"Gold badge is the highest award in this community. To obtain it have to show \n"
+"profound knowledge and ability in addition to your active participation."
+msgstr ""
+"Zlatna značka je najveća nagrada u ovoj zajednici. Za njeno dobivanje morate \n"
+"uz aktivno sudjelovanje pokazati profinjeno znanje i sposobnost "
+
+#: skins/default/templates/badges.html:47
+msgid "silver badge: occasionally awarded for the very high quality contributions"
+msgstr "srebrna značka: daje se povremeno za vrlo kvalitetan doprinos"
+
+#: skins/default/templates/badges.html:51
+msgid "msgid \"silver badge: occasionally awarded for the very high quality contributions"
+msgstr "msgid \"srebrna značka: daje se povremeno za vrlo kvalitetan doprinos"
+
+#: skins/default/templates/badges.html:54
+#: skins/default/templates/badges.html:58
+msgid "bronze badge: often given as a special honor"
+msgstr "brončana značka: često se daje kao posebna čast"
+
+#: skins/default/templates/close.html:3
+#: skins/default/templates/close.html:5
+msgid "Close question"
+msgstr "Zatvori pitanja"
+
+#: skins/default/templates/close.html:6
+msgid "Close the question"
+msgstr "Zatvori to pitanje"
+
+#: skins/default/templates/close.html:11
+msgid "Reasons"
+msgstr "Razlozi"
+
+#: skins/default/templates/close.html:15
+msgid "OK to close"
+msgstr "Uredu, zatvori"
+
+#: skins/default/templates/faq_static.html:3
+#: skins/default/templates/faq_static.html:5
+#: skins/default/templates/widgets/answer_edit_tips.html:20
+#: skins/default/templates/widgets/question_edit_tips.html:16
+#: views/meta.py:61
+msgid "FAQ"
+msgstr "ČPP"
+
+#: skins/default/templates/faq_static.html:5
+msgid "Frequently Asked Questions "
+msgstr "Često Postavljena Pitanja"
+
+#: skins/default/templates/faq_static.html:6
+msgid "What kinds of questions can I ask here?"
+msgstr "Koja pitanja mogu ovdje postaviti?"
+
+#: skins/default/templates/faq_static.html:7
+msgid "Most importanly - questions should be <strong>relevant</strong> to this community."
+msgstr "Najvažnije - pitanja moraju biti <strong>relevantna</strong> za ovu zajednicu"
+
+#: skins/default/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 "Prije nego postavite pitanje - provjerite da li ima sličnih pitanja. Pitanja možete tražiti po naslovu ili oznakama."
+
+#: skins/default/templates/faq_static.html:10
+msgid "What kinds of questions should be avoided?"
+msgstr "Koja pitanja treba izbjegavati?"
+
+#: skins/default/templates/faq_static.html:11
+msgid "Please avoid asking questions that are not relevant to this community, too subjective and argumentative."
+msgstr "Izbjegavajte postavljati pitanja koja nisu relevantna za ovu zajednicu, previše subjektivna ili raspravna pitanja."
+
+#: skins/default/templates/faq_static.html:13
+msgid "What should I avoid in my answers?"
+msgstr "Što trebam izbjegavati u dogovorima?"
+
+#: skins/default/templates/faq_static.html:14
+msgid "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."
+msgstr "je <strong>pitanje i odgovor</strong> stranica - <strong>nije grupa za raspravu</strong>. Pokušajte izbjegavati rasprave u svojim odgovorima jer znaju razvodniti bit pitanja i odgovora. Za kratke diskusije koristite komentare."
+
+#: skins/default/templates/faq_static.html:15
+msgid "Who moderates this community?"
+msgstr "Tko uređuje ovu zajednicu?"
+
+#: skins/default/templates/faq_static.html:16
+msgid "The short answer is: <strong>you</strong>."
+msgstr "Kratak odgovor je: <strong>vi</strong>."
+
+#: skins/default/templates/faq_static.html:17
+msgid "This website is moderated by the users."
+msgstr "Ovu internet stranicu uređuju korisnici."
+
+#: skins/default/templates/faq_static.html:18
+msgid "Karma system allows users to earn rights to perform a variety of moderation tasks"
+msgstr "Sistem karme omogućava korisnicima da zarade prava na izvođenje raznih uređivačkih zadataka"
+
+#: skins/default/templates/faq_static.html:20
+msgid "How does karma system work?"
+msgstr "Kako funkcionira sistem karme?"
+
+#: skins/default/templates/faq_static.html:21
+msgid "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."
+msgstr "Kada se pitanje ili odgovor pozitivno ocjeni korisnik koji ih je objavio dobiva bodove, koji se zovu \\\"karma bodovi\\\". Ti bodovi služe kao gruba procjena povjerenja zajednice u njega/nju. Prema tim bodovima razne mogućnosti uređivanja se postupno dodjeljuju korisnicima.\" "
+
+#: skins/default/templates/faq_static.html:22
+#, python-format
+msgid "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."
+msgstr "Na primjer, ako postavite zanimljivo pitanje ili date koristan odgovor, uaš unos će biti pozitivno ocijenjen. S druge strane ako je odgovor navodi na pogrešno mišljenje - biti će negativno ocijenjen. Svaki glas za dodat će <strong>%(REP_GAIN_FOR_RECEIVING_UPVOTE)s</strong> bodova, svaki glas protiv će oduzeti <strong>%(REP_LOSS_FOR_RECEIVING_DOWNVOTE)s</strong> bodova. Postoji limit od <strong>%(MAX_REP_GAIN_PER_USER_PER_DAY)s</strong> bodova koji se mogu dnevno dobiti za pitanja i dogovore. Tablica ispod objašnjava potreban broj bodova za izvođenje svakog tipa uređivanja."
+
+#: skins/default/templates/faq_static.html:32
+#: skins/default/templates/user_profile/user_votes.html:13
+msgid "upvote"
+msgstr "pozitivan glas"
+
+#: skins/default/templates/faq_static.html:36
+msgid "add comments"
+msgstr "dodaj komentare"
+
+#: skins/default/templates/faq_static.html:40
+#: skins/default/templates/user_profile/user_votes.html:15
+msgid "downvote"
+msgstr "negativan glas"
+
+#: skins/default/templates/faq_static.html:43
+msgid " accept own answer to own questions"
+msgstr "prihvati svoj odgovor na svoje pitanje"
+
+#: skins/default/templates/faq_static.html:47
+msgid "open and close own questions"
+msgstr "otvori i zatvori svoja pitanja"
+
+#: skins/default/templates/faq_static.html:51
+msgid "retag other's questions"
+msgstr "ponovo označi pitanja drugih korisnika"
+
+#: skins/default/templates/faq_static.html:56
+msgid "edit community wiki questions"
+msgstr "uredi pitanja wiki zajednice"
+
+#: skins/default/templates/faq_static.html:61
+msgid "edit any answer"
+msgstr "uredi bilo koji odgovor"
+
+#: skins/default/templates/faq_static.html:65
+msgid "delete any comment"
+msgstr "obriši bilo koji komentar"
+
+#: skins/default/templates/faq_static.html:69
+msgid "How to change my picture (gravatar) and what is gravatar?"
+msgstr "Kako da promjenim sliku (gavatar) i što je gavatar?"
+
+#: skins/default/templates/faq_static.html:70
+msgid "<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>"
+msgstr "<p>Slika prikazana na profilu korisnika je <strong>gravatar</strong> (što znači <strong>g</strong>lobalno <strong>p</strong>repoznatljiv <strong>avatar</strong>).</p><p>To ovako funkcionira: <strong>kriptiran ključ</strong> (neslomljiv kod) se kreira iz vaše email adrese. Pošaljete svoju sliku (ili sliku vašeg omiljenog alter ega) na intarnet stranicu <a href='http://gravatar.com'><strong>gravatar.com</strong></a> odakle ćete kasnije preuzimati sliku pomoću ključa.</p><p>Tako sve stranice kojima vjerujete mogu prikazati vašu sliku pokraj vaših postova, a vaša email adresa ostaje privatna.</p><p><strong>Uredite vaš račun</strong> sa slikom registriranom na <a href='http://gravatar.com'><strong>gravatar.com</strong></a> (molimo vas da koristite istu email adresu s kojom ste se registrirali kod nas). Zadana slika koja izgleda kao kuhinjske pločice dodjeljuje se automatski.</p>"
+
+#: skins/default/templates/faq_static.html:71
+msgid "To register, do I need to create new password?"
+msgstr "Da li trebam kreirati novu lozinku za registraciju?"
+
+#: skins/default/templates/faq_static.html:72
+msgid "No, you don't have to. You can login through any service that supports OpenID, e.g. Google, Yahoo, AOL, etc.\""
+msgstr "Ne, ne morate. Možete se prijaviti putem bilo kojeg servisa koji podržava OpenID, tj. Google, Yahoo, AOL, itd.\""
+
+#: skins/default/templates/faq_static.html:73
+msgid "\"Login now!\""
+msgstr "\"Prijavi sad!\""
+
+#: skins/default/templates/faq_static.html:75
+msgid "Why other people can edit my questions/answers?"
+msgstr "Zašto drugi korisnici mogu uređivati moja pitanja/odgovore?"
+
+#: skins/default/templates/faq_static.html:76
+msgid "Goal of this site is..."
+msgstr "Cilj ove internet stranice je ..."
+
+#: skins/default/templates/faq_static.html:76
+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 "Zato da se pitanja i odgovori mogu uređivati kao wiki stranice putem iskusnih korisnika ove stranice što unapređuje kvalitetu sadržaja."
+
+#: skins/default/templates/faq_static.html:77
+msgid "If this approach is not for you, we respect your choice."
+msgstr "Ako vam ovaj pristup ne odgovara, poštujemo vaš izbor."
+
+#: skins/default/templates/faq_static.html:79
+msgid "Still have questions?"
+msgstr "Imate drugih pitanja?"
+
+#: skins/default/templates/faq_static.html:80
+#, python-format
+msgid "Please <a href='%%(ask_question_url)s'>ask</a> your question, help make our community better!"
+msgstr "<a href='%%(ask_question_url)s'>Postavi pitanje</a>, pomozi učiti zajednicu boljom!"
+
+#: skins/default/templates/feedback.html:3
+msgid "Feedback"
+msgstr "Povratna informacija"
+
+#: skins/default/templates/feedback.html:5
+msgid "Give us your feedback!"
+msgstr "Dajte nam povratnu informaciju!"
+
+#: skins/default/templates/feedback.html:14
+#, python-format
+msgid ""
+"\n"
+" <span class='big strong'>Dear %(user_name)s</span>, we look forward to hearing your feedback. \n"
+" Please type and send us your message below.\n"
+" "
+msgstr ""
+"\n"
+" <span class='big strong'>Dragi/a %(user_name)s</span>, želimo od vas čuti povratnu informaciju. \n"
+" Pošaljite nam poruku.\n"
+" "
+
+#: skins/default/templates/feedback.html:21
+msgid ""
+"\n"
+" <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 ""
+"\n"
+" <span class='big strong'> Dragi posjetitelju </span>, želimo od vas čuti povratnu informaciju. \n"
+" Pošaljite nam poruku.\n"
+" "
+
+#: skins/default/templates/feedback.html:30
+msgid "(to hear from us please enter a valid email or check the box below)"
+msgstr "(ako želite informacije od nas unesite ispravnu email adresu ili označite okvir za izbor ispod)"
+
+#: skins/default/templates/feedback.html:37
+#: skins/default/templates/feedback.html:46
+msgid "(this field is required)"
+msgstr "(ovo polje je nužno)"
+
+#: skins/default/templates/feedback.html:55
+msgid "(Please solve the captcha)"
+msgstr "(Riješite captchu)"
+
+#: skins/default/templates/feedback.html:63
+msgid "Send Feedback"
+msgstr "Pošalji Povratnu Informaciju"
+
+#: skins/default/templates/feedback_email.txt:2
+#, python-format
+msgid ""
+"\n"
+"Hello, this is a %(site_title)s forum feedback message.\n"
+msgstr ""
+"\n"
+"Pozdrav, ovo je povratna poruka sa %(site_title)s foruma.\n"
+
+#: skins/default/templates/help.html:2
+#: skins/default/templates/help.html:4
+msgid "Help"
+msgstr "Pomoć"
+
+#: skins/default/templates/help.html:7
+#, python-format
+msgid "Welcome %(username)s,"
+msgstr "Dobrodošao/la %(username)s,"
+
+#: skins/default/templates/help.html:9
+msgid "Welcome,"
+msgstr "Dobrodošli,"
+
+#: skins/default/templates/help.html:13
+#, python-format
+msgid "Thank you for using %(app_name)s, here is how it works."
+msgstr "Hvala što koristite %(app_name)s, ovako funkcionira stranica"
+
+#: skins/default/templates/help.html:16
+msgid "This site is for asking and answering questions, not for open-ended discussions."
+msgstr "Ova internet stranica je za postavljanje i odgovaranje na pitanja, ne za bezgranične rasprave."
+
+#: skins/default/templates/help.html:17
+msgid "We encourage everyone to use “question” space for asking and “answer” for answering."
+msgstr "Podupiremo svakog da koristi prostor \"pitanje\" za postavljanje i prostor \"odgovor\" za odgovaranje."
+
+#: skins/default/templates/help.html:20
+msgid ""
+"Despite that, each question and answer can be commented – \n"
+" the comments are good for the limited discussions."
+msgstr ""
+"Usprkos tomu, svako pitanje i odgovor se mogu komentirati – \n"
+" komentari su dobri za ograničene rasprave."
+
+#: skins/default/templates/help.html:24
+#, python-format
+msgid "Voting in %(app_name)s helps to select best answers and thank most helpful users."
+msgstr "Glasanjem u %(app_name)s pomažete pri odabiru najboljih odgovora i zahvaljujete najkorisnijim korisnicima."
+
+#: skins/default/templates/help.html:26
+#, python-format
+msgid ""
+"Please vote when you find helpful information,\n"
+" it really helps the %(app_name)s community."
+msgstr ""
+"Glasajte kad pronađete korisne informacije, \n"
+" to pomaže %(app_name)s zajednici."
+
+#: skins/default/templates/help.html:29
+msgid ""
+"Besides, 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 ""
+"Osim toga, možete @spomenuti korisnike bilo gdje u tekstu da im privučete, \n"
+" pažnju, pratiti korisnike i razgovore te prijaviti neprikladan sadržaj."
+
+#: skins/default/templates/help.html:32
+msgid "Enjoy."
+msgstr "Uživajte."
+
+#: skins/default/templates/import_data.html:2
+#: skins/default/templates/import_data.html:4
+msgid "Import StackExchange data"
+msgstr "Unesi StackExchange podatke"
+
+#: skins/default/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 ""
+"<em>Upozorenje:</em> ako vaša baza podataka nije prazna, napravite kopiju\n"
+" prije izvršenja."
+
+#: skins/default/templates/import_data.html:16
+msgid ""
+"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"
+msgstr ""
+"Pošaljite vašu stackexchange dump .zip datoteku, zatim\n"
+" pričekajte do kraja prijenosa podataka. Ovo može potrajati nekoliko \n"
+" minuta. Imajte na umu da će te dobiti povratni ispis u tekstualnoj datoteci.\n"
+
+#: skins/default/templates/import_data.html:25
+msgid "Import data"
+msgstr "Unesi podatke"
+
+#: skins/default/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 ""
+"Ukoliko naiđete na probleme prilikom korištenja alata za prijenosa podataka, \n"
+" probajte unijeti vaše podatke putem komandne linije: <code>python manage.py load_stackexchange path/to/your-data.zip</code>"
+
+#: skins/default/templates/instant_notification.html:1
+#, python-format
+msgid "<p>Dear %(receiving_user_name)s,</p>"
+msgstr "<p>Dragi/ga %(receiving_user_name)s,</p>"
+
+#: skins/default/templates/instant_notification.html:3
+#, python-format
+msgid ""
+"\n"
+"<p>%(update_author_name)s left a <a href=\"%(post_url)s\">new comment</a>:</p>\n"
+msgstr ""
+"\n"
+"<p>%(update_author_name)s je ostavio <a href=\"%(post_url)s\">novi komentar</a>:</p>\n"
+
+#: skins/default/templates/instant_notification.html:8
+#, python-format
+msgid ""
+"\n"
+"<p>%(update_author_name)s left a <a href=\"%(post_url)s\">new comment</a></p>\n"
+msgstr ""
+"\n"
+"<p>%(update_author_name)s je ostavio <a href=\"%(post_url)s\">novi komentar</a></p>\n"
+
+#: skins/default/templates/instant_notification.html:13
+#, python-format
+msgid ""
+"\n"
+"<p>%(update_author_name)s answered a question \n"
+"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
+msgstr ""
+"\n"
+"<p>%(update_author_name)s je odgovorio na pitanje \n"
+"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
+
+#: skins/default/templates/instant_notification.html:19
+#, python-format
+msgid ""
+"\n"
+"<p>%(update_author_name)s posted a new question \n"
+"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
+msgstr ""
+"\n"
+"<p>%(update_author_name)s je objavio novo pitanje \n"
+"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
+
+#: skins/default/templates/instant_notification.html:25
+#, python-format
+msgid ""
+"\n"
+"<p>%(update_author_name)s updated an answer to the question\n"
+"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
+msgstr ""
+"\n"
+"<p>%(update_author_name)s je ažurirao odtovor na pitanje\n"
+"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
+
+#: skins/default/templates/instant_notification.html:31
+#, python-format
+msgid ""
+"\n"
+"<p>%(update_author_name)s updated a question \n"
+"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
+msgstr ""
+"\n"
+"<p>%(update_author_name)s je ažurirao pitanje \n"
+"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
+
+#: skins/default/templates/instant_notification.html:37
+#, python-format
+msgid ""
+"\n"
+"<div>%(content_preview)s</div>\n"
+"<p>Please note - you can easily <a href=\"%(user_subscriptions_url)s\">change</a>\n"
+"how often you receive these notifications or unsubscribe. Thank you for your interest in our forum!</p>\n"
+msgstr ""
+"\n"
+"<div>%(content_preview)s</div>\n"
+"<p>Imajte na umu - možete jednostavno <a href=\"%(user_subscriptions_url)s\">promijeniti</a>\n"
+"koliko često primate obavijesti ili se odjaviti s pretplate . Hvala na interesu!</p>\n"
+
+#: skins/default/templates/instant_notification.html:42
+msgid "<p>Sincerely,<br/>Forum Administrator</p>"
+msgstr "<p>S štovanjem,<br/>Forum Administrator</p>"
+
+#: skins/default/templates/instant_notification_reply_by_email.html:3
+msgid ""
+"\n"
+"\n"
+"======= Reply above this line. ====-=-=\n"
+msgstr ""
+"\n"
+"\n"
+"======= Odgovorite iznad ove linije. ====-=-=\n"
+
+#: skins/default/templates/instant_notification_reply_by_email.html:8
+#, python-format
+msgid ""
+"\n"
+"You can post an answer or a comment by replying to email notifications. To do that\n"
+"you need %(reply_by_email_karma_threshold)s karma, you have %(receiving_user_karma)s karma. \n"
+msgstr ""
+"\n"
+"Možete objaviti odgovor ili komentar odgovorom na email obavijest. Za to\n"
+"trebate %(reply_by_email_karma_threshold)s karme, vaša karma je%(receiving_user_karma)s. \n"
+
+#: skins/default/templates/macros.html:5
+#, python-format
+msgid "Share this question on %(site)s"
+msgstr "Podijelite ovo pitanje na %(site)s"
+
+#: skins/default/templates/macros.html:16
+#: skins/default/templates/macros.html:436
+#, python-format
+msgid "follow %(alias)s"
+msgstr "prati %(alias)s"
+
+#: skins/default/templates/macros.html:19
+#: skins/default/templates/macros.html:439
+#, python-format
+msgid "unfollow %(alias)s"
+msgstr "prestani pratiti %(alias)s"
+
+#: skins/default/templates/macros.html:20
+#: skins/default/templates/macros.html:440
+#, python-format
+msgid "following %(alias)s"
+msgstr "pratim %(alias)s"
+
+#: skins/default/templates/macros.html:33
+msgid "current number of votes"
+msgstr "trenutan broj glasova"
+
+#: skins/default/templates/macros.html:46
+msgid "anonymous user"
+msgstr "anonimni korisnik"
+
+#: skins/default/templates/macros.html:79
+msgid "this post is marked as community wiki"
+msgstr "ovaj post je označen kao wiki zajednica"
+
+#: skins/default/templates/macros.html:82
+#, python-format
+msgid ""
+"This post is a wiki.\n"
+" Anyone with karma &gt;%(wiki_min_rep)s is welcome to improve it."
+msgstr ""
+"Ovaj post je wiki.\n"
+" Svatko sa &gt;%(wiki_min_rep)s karmom može ga unaprijediti."
+
+#: skins/default/templates/macros.html:88
+msgid "asked"
+msgstr "pitano"
+
+#: skins/default/templates/macros.html:90
+msgid "answered"
+msgstr "odgovoreno"
+
+#: skins/default/templates/macros.html:92
+msgid "posted"
+msgstr "objavljeno"
+
+#: skins/default/templates/macros.html:122
+msgid "updated"
+msgstr "ažurirano"
+
+#: skins/default/templates/macros.html:202
+#, python-format
+msgid "see questions tagged '%(tag)s'"
+msgstr "pogledajte pitanja označena sa '%(tag)s'"
+
+#: skins/default/templates/macros.html:304
+msgid "delete this comment"
+msgstr "obriši ovaj komentar"
+
+#: skins/default/templates/macros.html:507
+#: templatetags/extra_tags.py:43
+#, python-format
+msgid "%(username)s gravatar image"
+msgstr "%(username)s gravatar slika"
+
+#: skins/default/templates/macros.html:516
+#, python-format
+msgid "%(username)s's website is %(url)s"
+msgstr "%(username)s internet stranica je %(url)s"
+
+#: skins/default/templates/macros.html:531
+#: skins/default/templates/macros.html:532
+#: skins/default/templates/macros.html:570
+#: skins/default/templates/macros.html:571
+msgid "previous"
+msgstr "prethodni"
+
+#: skins/default/templates/macros.html:543
+#: skins/default/templates/macros.html:582
+msgid "current page"
+msgstr "trenutna stranica"
+
+#: skins/default/templates/macros.html:545
+#: skins/default/templates/macros.html:552
+#: skins/default/templates/macros.html:584
+#: skins/default/templates/macros.html:591
+#, python-format
+msgid "page %(num)s"
+msgstr "stranica %(num)s"
+
+#: skins/default/templates/macros.html:556
+#: skins/default/templates/macros.html:595
+msgid "next page"
+msgstr "sljedeća stranica"
+
+#: skins/default/templates/macros.html:607
+#, python-format
+msgid "responses for %(username)s"
+msgstr "odazivi za %(username)s"
+
+#: skins/default/templates/macros.html:610
+#, python-format
+msgid "you have %(response_count)s new response"
+msgid_plural "you have %(response_count)s new responses"
+msgstr[0] "imate %(response_count)s novi odaziv"
+msgstr[1] "imate %(response_count)s novih odaziva"
+
+#: skins/default/templates/macros.html:613
+msgid "no new responses yet"
+msgstr "nema novih odaziva"
+
+#: skins/default/templates/macros.html:628
+#: skins/default/templates/macros.html:629
+#, python-format
+msgid "%(new)s new flagged posts and %(seen)s previous"
+msgstr "%(new)s novih postova sa zastavom i %(seen)s prethodnih"
+
+#: skins/default/templates/macros.html:631
+#: skins/default/templates/macros.html:632
+#, python-format
+msgid "%(new)s new flagged posts"
+msgstr "%(new)s novih postova sa zastavom"
+
+#: skins/default/templates/macros.html:637
+#: skins/default/templates/macros.html:638
+#, python-format
+msgid "%(seen)s flagged posts"
+msgstr "%(seen)s postova sa zastavom "
+
+#: skins/default/templates/main_page.html:11
+msgid "Questions"
+msgstr "Pitanja"
+
+#: skins/default/templates/question.html:110
+msgid "post a comment / <strong>some</strong> more"
+msgstr "objavite komentar / <strong>više</strong>"
+
+#: skins/default/templates/question.html:113
+msgid "see <strong>some</strong> more"
+msgstr "pogledaj <strong>više</strong>"
+
+#: skins/default/templates/question.html:117
+#: skins/default/templates/question/javascript.html:20
+msgid "post a comment"
+msgstr "objavi komentar"
+
+#: skins/default/templates/question.html:135
+#: skins/default/templates/question/content.html:40
+msgid "Answer Your Own Question"
+msgstr "Odgovorite na Svoje Pitanje"
+
+#: skins/default/templates/question.html:140
+msgid "Post Your Answer"
+msgstr "Objavite Svoj Odgovor"
+
+#: skins/default/templates/question.html:146
+#: skins/default/templates/widgets/ask_form.html:41
+msgid "Login/Signup to Post"
+msgstr "Prijava/Upis za Objavu"
+
+#: skins/default/templates/question_edit.html:4
+#: skins/default/templates/question_edit.html:9
+msgid "Edit question"
+msgstr "Uredi pitanje"
+
+#: skins/default/templates/question_retag.html:3
+#: skins/default/templates/question_retag.html:5
+msgid "Retag question"
+msgstr "Ponovo označi pitanje"
+
+#: skins/default/templates/question_retag.html:21
+msgid "Retag"
+msgstr "Ponovo označi"
+
+#: skins/default/templates/question_retag.html:28
+msgid "Why use and modify tags?"
+msgstr "Zašto koristiti i mijenjati oznake?"
+
+#: skins/default/templates/question_retag.html:30
+msgid "Tags help to keep the content better organized and searchable"
+msgstr "Oznake pomažu pri organizaciji i pretraživanju sadržaja"
+
+#: skins/default/templates/question_retag.html:32
+msgid "tag editors receive special awards from the community"
+msgstr "urednici oznaka primaju posebnu nagradu od zajednice"
+
+#: skins/default/templates/question_retag.html:59
+msgid "up to 5 tags, less than 20 characters each"
+msgstr "do 5 oznaka, manje od 20 znakova za svaku"
+
+#: skins/default/templates/reopen.html:3
+#: skins/default/templates/reopen.html:5
+msgid "Reopen question"
+msgstr "Ponovo otvori pitanje"
+
+#: skins/default/templates/reopen.html:6
+msgid "Title"
+msgstr "Naslov"
+
+#: skins/default/templates/reopen.html:11
+#, python-format
+msgid ""
+"This question has been closed by \n"
+" <a href=\"%(closed_by_profile_url)s\">%(closed_by_username)s</a>\n"
+msgstr ""
+"Ovo pitanje je zatvorio \n"
+" <a href=\"%(closed_by_profile_url)s\">%(closed_by_username)s</a>\n"
+
+#: skins/default/templates/reopen.html:16
+msgid "Close reason:"
+msgstr "Razlog zatvaranja:"
+
+#: skins/default/templates/reopen.html:19
+msgid "When:"
+msgstr "Kada:"
+
+#: skins/default/templates/reopen.html:22
+msgid "Reopen this question?"
+msgstr "Ponovo otvori ovo pitanje?"
+
+#: skins/default/templates/reopen.html:26
+msgid "Reopen this question"
+msgstr "Ponovo otvori ovo pitanje"
+
+#: skins/default/templates/reply_by_email_error.html:1
+msgid ""
+"\n"
+"<p>The system was unable to process your message successfully, the reason being:<p>\n"
+msgstr ""
+"\n"
+"<p>Sistem nije uspješno obradio vašu poruku zbog:<p>\n"
+
+#: skins/default/templates/revisions.html:4
+#: skins/default/templates/revisions.html:7
+msgid "Revision history"
+msgstr "Povijest revizije"
+
+#: skins/default/templates/revisions.html:23
+msgid "click to hide/show revision"
+msgstr "kliknite za prikaz/skrivanje revizije"
+
+#: skins/default/templates/revisions.html:29
+#, python-format
+msgid "revision %(number)s"
+msgstr "revizija broj %(number)s"
+
+#: skins/default/templates/subscribe_for_tags.html:3
+#: skins/default/templates/subscribe_for_tags.html:5
+msgid "Subscribe for tags"
+msgstr "Pretplatite se na oznake"
+
+#: skins/default/templates/subscribe_for_tags.html:6
+msgid "Please, subscribe for the following tags:"
+msgstr "Pretplatite se na sljedeće oznake:"
+
+#: skins/default/templates/subscribe_for_tags.html:15
+msgid "Subscribe"
+msgstr "Pretplatite se"
+
+#: skins/default/templates/tags.html:8
+#, python-format
+msgid "Tags, matching \"%(stag)s\""
+msgstr "Oznake, slične \"%(stag)s\""
+
+#: skins/default/templates/tags.html:10
+msgid "Tag list"
+msgstr "Lista oznaka"
+
+#: skins/default/templates/tags.html:14
+#: skins/default/templates/users.html:9
+#: skins/default/templates/main_page/tab_bar.html:15
+msgid "Sort by &raquo;"
+msgstr "Sortiraj po"
+
+#: skins/default/templates/tags.html:19
+msgid "sorted alphabetically"
+msgstr "sortirano po abecedi"
+
+#: skins/default/templates/tags.html:20
+msgid "by name"
+msgstr "po imenu"
+
+#: skins/default/templates/tags.html:25
+msgid "sorted by frequency of tag use"
+msgstr "sortirano po učestalosti upotrebe oznake"
+
+#: skins/default/templates/tags.html:26
+msgid "by popularity"
+msgstr "po popularnosti"
+
+#: skins/default/templates/tags.html:31
+#: skins/default/templates/tags.html:56
+msgid "Nothing found"
+msgstr "Ništa nije pronađeno"
+
+#: skins/default/templates/users.html:4
+#: skins/default/templates/users.html:6
+msgid "Users"
+msgstr "People"
+
+#: skins/default/templates/users.html:14
+msgid "see people with the highest reputation"
+msgstr "korisnici sa najvećim ugledom"
+
+#: skins/default/templates/users.html:15
+#: skins/default/templates/user_profile/user_info.html:25
+#: skins/default/templates/user_profile/user_reputation.html:4
+#: skins/default/templates/user_profile/user_tabs.html:23
+msgid "karma"
+msgstr "karma"
+
+#: skins/default/templates/users.html:20
+msgid "see people who joined most recently"
+msgstr "najnoviji korisnici "
+
+#: skins/default/templates/users.html:21
+msgid "recent"
+msgstr "najnoviji"
+
+#: skins/default/templates/users.html:26
+msgid "see people who joined the site first"
+msgstr "najstariji korisnici"
+
+#: skins/default/templates/users.html:32
+msgid "see people sorted by name"
+msgstr "korisnici sortirani po imenu"
+
+#: skins/default/templates/users.html:33
+msgid "by username"
+msgstr " korisničkom imenu"
+
+#: skins/default/templates/users.html:39
+#, python-format
+msgid "users matching query %(suser)s:"
+msgstr "korisnici koji odgovaraju upitu %(suser)s:"
+
+#: skins/default/templates/users.html:42
+msgid "Nothing found."
+msgstr "Ništa nije pronađeno."
+
+#: skins/default/templates/main_page/headline.html:4
+#: views/readers.py:135
+#, python-format
+msgid "%(q_num)s question"
+msgid_plural "%(q_num)s questions"
+msgstr[0] "%(q_num)s pitanje"
+msgstr[1] "%(q_num)s pitanja"
+
+#: skins/default/templates/main_page/headline.html:6
+#, python-format
+msgid "with %(author_name)s's contributions"
+msgstr "sa %(author_name)s doprinosima"
+
+#: skins/default/templates/main_page/headline.html:12
+msgid "Tagged"
+msgstr "Označeno"
+
+#: skins/default/templates/main_page/headline.html:24
+msgid "Search tips:"
+msgstr "Savjeti za pretraživanje:"
+
+#: skins/default/templates/main_page/headline.html:27
+msgid "reset author"
+msgstr "vrati autora u izvorno stanje"
+
+#: skins/default/templates/main_page/headline.html:29
+#: skins/default/templates/main_page/headline.html:32
+#: skins/default/templates/main_page/nothing_found.html:18
+#: skins/default/templates/main_page/nothing_found.html:21
+msgid " or "
+msgstr "ili"
+
+#: skins/default/templates/main_page/headline.html:30
+msgid "reset tags"
+msgstr "vrati oznake u izvorno stanje"
+
+#: skins/default/templates/main_page/headline.html:33
+#: skins/default/templates/main_page/headline.html:36
+msgid "start over"
+msgstr "počni ispočetka"
+
+#: skins/default/templates/main_page/headline.html:38
+msgid " - to expand, or dig in by adding more tags and revising the query."
+msgstr "- za proširenje ili idi dublje dodavanjem više oznaka i mijenjanjem upita."
+
+#: skins/default/templates/main_page/headline.html:41
+msgid "Search tip:"
+msgstr "Savjet za pretragu:"
+
+#: skins/default/templates/main_page/headline.html:41
+msgid "add tags and a query to focus your search"
+msgstr "dodajte oznake i upit za poboljšanje pretrage"
+
+#: skins/default/templates/main_page/nothing_found.html:4
+msgid "There are no unanswered questions here"
+msgstr "Ovdje nema ne odgovorenih pitanja"
+
+#: skins/default/templates/main_page/nothing_found.html:7
+msgid "No questions here. "
+msgstr "Trenutno nema pitanja."
+
+#: skins/default/templates/main_page/nothing_found.html:8
+msgid "Please follow some questions or follow some users."
+msgstr "Možete pratiti pitanja ili korisnike."
+
+#: skins/default/templates/main_page/nothing_found.html:13
+msgid "You can expand your search by "
+msgstr "Možete proširiti pretragu po"
+
+#: skins/default/templates/main_page/nothing_found.html:16
+msgid "resetting author"
+msgstr "vraćanje autora u izvorno stanje"
+
+#: skins/default/templates/main_page/nothing_found.html:19
+msgid "resetting tags"
+msgstr "vraćanje oznaka u izvorno stanje"
+
+#: skins/default/templates/main_page/nothing_found.html:22
+#: skins/default/templates/main_page/nothing_found.html:25
+msgid "starting over"
+msgstr "ponovo iz početka"
+
+#: skins/default/templates/main_page/nothing_found.html:30
+msgid "Please always feel free to ask your question!"
+msgstr "Slobodno postavi pitanje!"
+
+#: skins/default/templates/main_page/questions_loop.html:11
+msgid "Did not find what you were looking for?"
+msgstr "Niste pronašli što ste tražili?"
+
+#: skins/default/templates/main_page/questions_loop.html:12
+msgid "Please, post your question!"
+msgstr "Objavite vaše pitanje!"
+
+#: skins/default/templates/main_page/tab_bar.html:10
+msgid "subscribe to the questions feed"
+msgstr "pretplatite se na pitanja kanal"
+
+#: skins/default/templates/main_page/tab_bar.html:11
+msgid "RSS"
+msgstr "RSS"
+
+#: skins/default/templates/meta/bottom_scripts.html:7
+#, python-format
+msgid "Please note: %(app_name)s requires javascript to work properly, please enable javascript in your browser, <a href=\"%(noscript_url)s\">here is how</a>"
+msgstr "Napomena: %(app_name)s za ispravan rad zahtjeva javascript, omogućite javascript u vašem pregledniku, <a href=\"%(noscript_url)s\">ovako</a> "
+
+#: skins/default/templates/meta/editor_data.html:7
+#, 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] "svaka oznaka mora biti kraća od %(max_chars)s znaka"
+msgstr[1] "svaka oznaka mora biti kraća od %(max_chars)s znakova"
+
+#: skins/default/templates/meta/editor_data.html:9
+#, python-format
+msgid "please use %(tag_count)s tag"
+msgid_plural "please use %(tag_count)s tags or less"
+msgstr[0] "koristite %(tag_count)s znak"
+msgstr[1] "koristite %(tag_count)s znakova ili manje\" "
+
+#: skins/default/templates/meta/editor_data.html:10
+#, python-format
+msgid "please use up to %(tag_count)s tags, less than %(max_chars)s characters each"
+msgstr "koristite do %(tag_count)s oznaka, manje od %(max_chars)s znakova za svaku"
+
+#: skins/default/templates/question/answer_tab_bar.html:3
+#, python-format
+msgid ""
+"\n"
+" %(counter)s Answer\n"
+" "
+msgid_plural ""
+"\n"
+" %(counter)s Answers\n"
+" "
+msgstr[0] ""
+"\n"
+" %(counter)s Odgovor\n"
+" "
+msgstr[1] ""
+"\n"
+" %(counter)s Odgovora\n"
+" "
+
+#: skins/default/templates/question/answer_tab_bar.html:11
+msgid "Sort by »"
+msgstr "Sortiraj po"
+
+#: skins/default/templates/question/answer_tab_bar.html:14
+msgid "oldest answers will be shown first"
+msgstr "stariji odgovori biti će prikazani prvi"
+
+#: skins/default/templates/question/answer_tab_bar.html:17
+msgid "newest answers will be shown first"
+msgstr "noviji odgovori biti će prikazani prvi"
+
+#: skins/default/templates/question/answer_tab_bar.html:20
+msgid "most voted answers will be shown first"
+msgstr "odgovori s najviše glasova biti će prikazani prvi"
+
+#: skins/default/templates/question/new_answer_form.html:16
+msgid "Login/Signup to Answer"
+msgstr "Prijava/Upis za Odgovor"
+
+#: skins/default/templates/question/new_answer_form.html:24
+msgid "Your answer"
+msgstr "Vaš odgovor"
+
+#: skins/default/templates/question/new_answer_form.html:26
+msgid "Be the first one to answer this question!"
+msgstr "Odgovorite prvi na ovo pitanje!"
+
+#: skins/default/templates/question/new_answer_form.html:32
+msgid "<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)!"
+msgstr "<span class='strong big'>Počnite objavljivati odgovore anonimno</span> - vaši odgovori biti će privremeno sačuvani i objavljeni nakon što se prijavite ili kreirate novi korisnički račun. Pokušajte dati <strong>značajan odgovor</strong>, za raspravu, <strong>koristite komentare</strong> i <strong> ne zaboravite glasati</strong> (nakon što se prijavite)!"
+
+#: skins/default/templates/question/new_answer_form.html:36
+msgid "<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)!"
+msgstr "<span class='big strong'>Možete odgovoriti na svoje pitanje</span>, ali pazite da ispravno <strong>odgovorite</strong>. Imajte na umu da uvijek možete <strong>korigirati vaše originalno pitanje</strong>. <strong>Koristite komentare za raspravu</strong> i <strong>ne zaboravite glasati</strong> za odgovore koji vam se sviđaju (ili ne sviđaju)."
+
+#: skins/default/templates/question/new_answer_form.html:38
+msgid "<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!"
+msgstr "<span class='big strong'>Pokušajte dati značajan odgovor</span>. Ako želite komentirati pitanje ili odgovor, <strong>koristite alat za komentiranje</strong>. Upamtite da uvjek možete <strong>izmjeniti vaše odgovore</strong> - nema potrebe za dvostruki odgovor na isto pitanje. Također <strong>ne zaboravite glasati</strong> - to pomaže odabrati najbolja pitanja i odgovore!"
+
+#: skins/default/templates/question/sharing_prompt_phrase.html:2
+#, python-format
+msgid "Know someone who can answer? Share a <a href=\"%(question_url)s\">link</a> to this question via"
+msgstr "Znate nekog tko zna odgovor? Podijelite <a href=\"%(question_url)s\">link</a> na ovo pitanje koristeći"
+
+#: skins/default/templates/question/sharing_prompt_phrase.html:8
+msgid " or"
+msgstr "ili"
+
+#: skins/default/templates/question/sharing_prompt_phrase.html:10
+msgid "email"
+msgstr "email"
+
+#: skins/default/templates/question/sidebar.html:6
+msgid "Question tools"
+msgstr "Alat za pitanja"
+
+#: skins/default/templates/question/sidebar.html:9
+msgid "click to unfollow this question"
+msgstr "kliknite za prestanak praćenja ovog pitanja"
+
+#: skins/default/templates/question/sidebar.html:10
+msgid "Following"
+msgstr "Praćenje"
+
+#: skins/default/templates/question/sidebar.html:11
+msgid "Unfollow"
+msgstr "Prekini praćenje"
+
+#: skins/default/templates/question/sidebar.html:15
+msgid "click to follow this question"
+msgstr "kliknite za praćenje ovog pitanja"
+
+#: skins/default/templates/question/sidebar.html:16
+msgid "Follow"
+msgstr "Prati"
+
+#: skins/default/templates/question/sidebar.html:23
+#, python-format
+msgid "%(count)s follower"
+msgid_plural "%(count)s followers"
+msgstr[0] "%(count)s pratitelj"
+msgstr[1] "%(count)s pratitelja"
+
+#: skins/default/templates/question/sidebar.html:29
+msgid "email the updates"
+msgstr "pošalji dopune emailom"
+
+#: skins/default/templates/question/sidebar.html:32
+msgid "<strong>Here</strong> (once you log in) you will be able to sign up for the periodic email updates about this question."
+msgstr "<strong>Ovdje</strong> (nakon što se prijavite) ćete se moći prijaviti za periodne email obavijesti o dopunama ovog pitanja"
+
+#: skins/default/templates/question/sidebar.html:37
+msgid "subscribe to this question rss feed"
+msgstr "pretplatite se na rss kanal ovog pitanja"
+
+#: skins/default/templates/question/sidebar.html:38
+msgid "subscribe to rss feed"
+msgstr "pretplatite se na rss kanal"
+
+#: skins/default/templates/question/sidebar.html:46
+msgid "Stats"
+msgstr "Statistika"
+
+#: skins/default/templates/question/sidebar.html:48
+msgid "Asked"
+msgstr "Pitano"
+
+#: skins/default/templates/question/sidebar.html:51
+msgid "Seen"
+msgstr "Pogledan"
+
+#: skins/default/templates/question/sidebar.html:51
+msgid "times"
+msgstr "puta"
+
+#: skins/default/templates/question/sidebar.html:54
+msgid "Last updated"
+msgstr "Zadnje ažuriranje"
+
+#: skins/default/templates/question/sidebar.html:62
+msgid "Related questions"
+msgstr "Slična pitanja"
+
+#: skins/default/templates/question/subscribe_by_email_prompt.html:5
+msgid "Email me when there are any new answers"
+msgstr "U slučaju novih odgovora pošalji mi email"
+
+#: skins/default/templates/question/subscribe_by_email_prompt.html:11
+msgid "once you sign in you will be able to subscribe for any updates here"
+msgstr "nakon što se prijavite ovdje ćete se moći pretplatiti na bilo koje dopune"
+
+#: skins/default/templates/question/subscribe_by_email_prompt.html:12
+msgid "<span class='strong'>Here</span> (once you log in) you will be able to sign up for the periodic email updates about this question."
+msgstr "<span class='strong'>Ovdje</span> (nakon što se prijavite) ćete se moći prijaviti za povremene email obavijesti o dopunama ovog pitanja"
+
+#: skins/default/templates/user_profile/user.html:12
+#, python-format
+msgid "%(username)s's profile"
+msgstr "%(username)s profil"
+
+#: skins/default/templates/user_profile/user_edit.html:4
+msgid "Edit user profile"
+msgstr "Uredi korisnički profil"
+
+#: skins/default/templates/user_profile/user_edit.html:7
+msgid "edit profile"
+msgstr "uredi profil"
+
+#: skins/default/templates/user_profile/user_edit.html:21
+#: skins/default/templates/user_profile/user_info.html:15
+msgid "change picture"
+msgstr "promjeni sliku"
+
+#: skins/default/templates/user_profile/user_edit.html:25
+#: skins/default/templates/user_profile/user_info.html:19
+msgid "remove"
+msgstr "ukloni"
+
+#: skins/default/templates/user_profile/user_edit.html:32
+msgid "Registered user"
+msgstr "Registrirani korisnik"
+
+#: skins/default/templates/user_profile/user_edit.html:39
+msgid "Screen Name"
+msgstr "Pokazno ime"
+
+#: skins/default/templates/user_profile/user_edit.html:59
+msgid "(cannot be changed)"
+msgstr "(ne može se promijeniti)"
+
+#: skins/default/templates/user_profile/user_edit.html:101
+#: skins/default/templates/user_profile/user_email_subscriptions.html:22
+msgid "Update"
+msgstr "Ažuriraj"
+
+#: skins/default/templates/user_profile/user_email_subscriptions.html:4
+#: skins/default/templates/user_profile/user_tabs.html:42
+msgid "subscriptions"
+msgstr "preplate"
+
+#: skins/default/templates/user_profile/user_email_subscriptions.html:7
+msgid "Email subscription settings"
+msgstr "Postavke za email pretplate"
+
+#: skins/default/templates/user_profile/user_email_subscriptions.html:9
+msgid "<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."
+msgstr "<span class='big strong'>Podesite učestalost email dopuna.</span> Primajte dopune zanimljivih pitanja putem emaila, <strong><br/>pomozite zajednici</strong> odgovorom na pitanja vaših kolega. Ako ne želite primati emailove - odaberite 'bez emaila' na svim stavkama ispod.<br/>Dopune se šalju jedino ako postoji nova aktivnost na odabranim stavkama."
+
+#: skins/default/templates/user_profile/user_email_subscriptions.html:23
+msgid "Stop Email"
+msgstr "Isključi Email"
+
+#: skins/default/templates/user_profile/user_favorites.html:4
+#: skins/default/templates/user_profile/user_tabs.html:27
+msgid "followed questions"
+msgstr "praćena pitanja"
+
+#: skins/default/templates/user_profile/user_inbox.html:18
+#: skins/default/templates/user_profile/user_tabs.html:12
+msgid "inbox"
+msgstr "sandučić"
+
+#: skins/default/templates/user_profile/user_inbox.html:34
+msgid "Sections:"
+msgstr "Odabiri:"
+
+#: skins/default/templates/user_profile/user_inbox.html:38
+#, python-format
+msgid "forum responses (%(re_count)s)"
+msgstr "forum odgovori (%(re_count)s)"
+
+#: skins/default/templates/user_profile/user_inbox.html:43
+#, python-format
+msgid "flagged items (%(flag_count)s)"
+msgstr "označene stavke (%(flag_count)s)"
+
+#: skins/default/templates/user_profile/user_inbox.html:49
+#: skins/default/templates/user_profile/user_inbox.html:61
+msgid "select:"
+msgstr "odaberi:"
+
+#: skins/default/templates/user_profile/user_inbox.html:51
+#: skins/default/templates/user_profile/user_inbox.html:63
+msgid "seen"
+msgstr "pregledan"
+
+#: skins/default/templates/user_profile/user_inbox.html:52
+#: skins/default/templates/user_profile/user_inbox.html:64
+msgid "new"
+msgstr "novi"
+
+#: skins/default/templates/user_profile/user_inbox.html:53
+#: skins/default/templates/user_profile/user_inbox.html:65
+msgid "none"
+msgstr "nijedan"
+
+#: skins/default/templates/user_profile/user_inbox.html:54
+msgid "mark as seen"
+msgstr "označi kao pogledan"
+
+#: skins/default/templates/user_profile/user_inbox.html:55
+msgid "mark as new"
+msgstr "označi kao nov"
+
+#: skins/default/templates/user_profile/user_inbox.html:56
+msgid "dismiss"
+msgstr "odbaci"
+
+#: skins/default/templates/user_profile/user_inbox.html:66
+msgid "remove flags"
+msgstr "ukloni zastave"
+
+#: skins/default/templates/user_profile/user_inbox.html:68
+msgid "delete post"
+msgstr "obriši post"
+
+#: skins/default/templates/user_profile/user_info.html:36
+msgid "update profile"
+msgstr "ažuriraj profil"
+
+#: skins/default/templates/user_profile/user_info.html:40
+msgid "manage login methods"
+msgstr "uredi načine prijave"
+
+#: skins/default/templates/user_profile/user_info.html:53
+msgid "real name"
+msgstr "pravo ime"
+
+#: skins/default/templates/user_profile/user_info.html:58
+msgid "member since"
+msgstr "član od"
+
+#: skins/default/templates/user_profile/user_info.html:63
+msgid "last seen"
+msgstr "zadnji put viđen"
+
+#: skins/default/templates/user_profile/user_info.html:69
+msgid "website"
+msgstr "internet stranica"
+
+#: skins/default/templates/user_profile/user_info.html:75
+msgid "location"
+msgstr "lokacija"
+
+#: skins/default/templates/user_profile/user_info.html:82
+msgid "age"
+msgstr "dob"
+
+#: skins/default/templates/user_profile/user_info.html:83
+msgid "age unit"
+msgstr "jedinica dobi"
+
+#: skins/default/templates/user_profile/user_info.html:88
+msgid "todays unused votes"
+msgstr "dnevni glasovi"
+
+#: skins/default/templates/user_profile/user_info.html:89
+msgid "votes left"
+msgstr "glasova preostalo"
+
+#: skins/default/templates/user_profile/user_moderate.html:4
+#: skins/default/templates/user_profile/user_tabs.html:48
+msgid "moderation"
+msgstr "uređenje"
+
+#: skins/default/templates/user_profile/user_moderate.html:8
+#, python-format
+msgid "%(username)s's current status is \"%(status)s\""
+msgstr "%(username)s trenutni status je \"%(status)s\""
+
+#: skins/default/templates/user_profile/user_moderate.html:11
+msgid "User status changed"
+msgstr "Promijenjen status korisnika"
+
+#: skins/default/templates/user_profile/user_moderate.html:20
+msgid "Save"
+msgstr "Spremi"
+
+#: skins/default/templates/user_profile/user_moderate.html:25
+#, python-format
+msgid "Your current reputation is %(reputation)s points"
+msgstr "Vaš trenutni ugled iznosi %(reputation)s bodova"
+
+#: skins/default/templates/user_profile/user_moderate.html:27
+#, python-format
+msgid "User's current reputation is %(reputation)s points"
+msgstr "Trenutni ugled korisnika iznosi %(reputation)s bodova"
+
+#: skins/default/templates/user_profile/user_moderate.html:31
+msgid "User reputation changed"
+msgstr "Ugled korisnika promijenjen"
+
+#: skins/default/templates/user_profile/user_moderate.html:38
+msgid "Subtract"
+msgstr "Oduzmi"
+
+#: skins/default/templates/user_profile/user_moderate.html:39
+msgid "Add"
+msgstr "Dodaj"
+
+#: skins/default/templates/user_profile/user_moderate.html:43
+#, python-format
+msgid "Send message to %(username)s"
+msgstr "Pošalji poruke korisniku %(username)s"
+
+#: skins/default/templates/user_profile/user_moderate.html:44
+msgid "An email will be sent to the user with 'reply-to' field set to your email address. Please make sure that your address is entered correctly."
+msgstr "Email će biti poslan korisniku sa 'odgovori' poljem sa vezom na vašu email adresu. Provjerite da li je vaša email adresa ispravna."
+
+#: skins/default/templates/user_profile/user_moderate.html:46
+msgid "Message sent"
+msgstr "Poruka poslana"
+
+#: skins/default/templates/user_profile/user_moderate.html:64
+msgid "Send message"
+msgstr "Pošalji poruku"
+
+#: skins/default/templates/user_profile/user_moderate.html:74
+msgid "Administrators have privileges of normal users, but in addition they can assign/revoke any status to any user, and are exempt from the reputation limits."
+msgstr "Administratori imaju privilegije kao i normalni korisnici, ali mogu dodijeliti/opozvati bilo koji status bilo kojeg korisnika i izuzeti su od limita ugleda."
+
+#: skins/default/templates/user_profile/user_moderate.html:77
+msgid "Moderators have the same privileges as administrators, but cannot add or remove user status of 'moderator' or 'administrator'."
+msgstr "Moderatori imaju iste privilegije kao administratori, ali ne mogu dati ili oduzeti status 'moderator' ili 'administrator'."
+
+#: skins/default/templates/user_profile/user_moderate.html:80
+msgid "'Approved' status means the same as regular user."
+msgstr "Status 'Odobren' znači isto kao i uobičajeni korisnik"
+
+#: skins/default/templates/user_profile/user_moderate.html:83
+msgid "Suspended users can only edit or delete their own posts."
+msgstr "Suspendirani korisnici mogu samo uređivati ili brisati svoje postove."
+
+#: skins/default/templates/user_profile/user_moderate.html:86
+msgid "Blocked users can only login and send feedback to the site administrators."
+msgstr "Blokirani korisnici se mogu samo prijaviti i poslati povratnu informaciju administratorima."
+
+#: skins/default/templates/user_profile/user_network.html:5
+#: skins/default/templates/user_profile/user_tabs.html:18
+msgid "network"
+msgstr "mreža"
+
+#: skins/default/templates/user_profile/user_network.html:10
+#, python-format
+msgid "Followed by %(count)s person"
+msgid_plural "Followed by %(count)s people"
+msgstr[0] "Praćen od %(count)s osobe"
+msgstr[1] "Praćen od %(count)s ljudi"
+
+#: skins/default/templates/user_profile/user_network.html:14
+#, python-format
+msgid "Following %(count)s person"
+msgid_plural "Following %(count)s people"
+msgstr[0] "Prati %(count)s osobu"
+msgstr[1] "Prati %(count)s osoba"
+
+#: skins/default/templates/user_profile/user_network.html:19
+msgid "Your network is empty. Would you like to follow someone? - Just visit their profiles and click \"follow\""
+msgstr "Vaša mreža je prazna. Želite li pratiti nekoga? Posjetite profil drugog korisnika i kliknite \"prati\""
+
+#: skins/default/templates/user_profile/user_network.html:21
+#, python-format
+msgid "%(username)s's network is empty"
+msgstr "%(username)s mreža je prazna"
+
+#: skins/default/templates/user_profile/user_recent.html:4
+#: skins/default/templates/user_profile/user_tabs.html:29
+#: skins/default/templates/user_profile/user_tabs.html:31
+msgid "activity"
+msgstr "aktivnost"
+
+#: skins/default/templates/user_profile/user_recent.html:24
+#: skins/default/templates/user_profile/user_recent.html:28
+msgid "source"
+msgstr "izvor"
+
+#: skins/default/templates/user_profile/user_reputation.html:11
+msgid "Your karma change log."
+msgstr "Podaci o promijeni vaše karme."
+
+#: skins/default/templates/user_profile/user_reputation.html:13
+#, python-format
+msgid "%(user_name)s's karma change log"
+msgstr "Podaci o promjeni karme za %(user_name)s"
+
+#: skins/default/templates/user_profile/user_stats.html:5
+#: skins/default/templates/user_profile/user_tabs.html:7
+msgid "overview"
+msgstr "pregled"
+
+#: skins/default/templates/user_profile/user_stats.html:11
+#, python-format
+msgid "<span class=\"count\">%(counter)s</span> Question"
+msgid_plural "<span class=\"count\">%(counter)s</span> Questions"
+msgstr[0] "<span class=\"count\">%(counter)s</span> Pitanje"
+msgstr[1] "<span class=\"count\">%(counter)s</span> Pitanja"
+
+#: skins/default/templates/user_profile/user_stats.html:16
+msgid "Answer"
+msgid_plural "Answers"
+msgstr[0] "Odgovor"
+msgstr[1] "Odgovori"
+
+#: skins/default/templates/user_profile/user_stats.html:24
+#, python-format
+msgid "the answer has been voted for %(answer_score)s times"
+msgstr "odgovor je glasan %(answer_score)s puta"
+
+#: skins/default/templates/user_profile/user_stats.html:34
+#, python-format
+msgid "(%(comment_count)s comment)"
+msgid_plural "the answer has been commented %(comment_count)s times"
+msgstr[0] "(%(comment_count)s komentar)"
+msgstr[1] "odgovor je komentiran %(comment_count)s puta"
+
+#: skins/default/templates/user_profile/user_stats.html:44
+#, python-format
+msgid "<span class=\"count\">%(cnt)s</span> Vote"
+msgid_plural "<span class=\"count\">%(cnt)s</span> Votes "
+msgstr[0] "<span class=\"count\">%(cnt)s</span> Glas"
+msgstr[1] "<span class=\"count\">%(cnt)s</span> Glasova"
+
+#: skins/default/templates/user_profile/user_stats.html:50
+msgid "thumb up"
+msgstr "palac gore"
+
+#: skins/default/templates/user_profile/user_stats.html:51
+msgid "user has voted up this many times"
+msgstr "korisnik je pozitivno glasao ovoliko puta"
+
+#: skins/default/templates/user_profile/user_stats.html:54
+msgid "thumb down"
+msgstr "palac dolje"
+
+#: skins/default/templates/user_profile/user_stats.html:55
+msgid "user voted down this many times"
+msgstr "korisnik je negativno glasao ovoliko puta"
+
+#: skins/default/templates/user_profile/user_stats.html:63
+#, python-format
+msgid "<span class=\"count\">%(counter)s</span> Tag"
+msgid_plural "<span class=\"count\">%(counter)s</span> Tags"
+msgstr[0] "<span class=\"count\">%(counter)s</span> Oznaka"
+msgstr[1] "<span class=\"count\">%(counter)s</span> Oznake"
+
+#: skins/default/templates/user_profile/user_stats.html:97
+#, python-format
+msgid "<span class=\"count\">%(counter)s</span> Badge"
+msgid_plural "<span class=\"count\">%(counter)s</span> Badges"
+msgstr[0] "<span class=\"count\">%(counter)s</span> Značka"
+msgstr[1] "<span class=\"count\">%(counter)s</span> Značke"
+
+#: skins/default/templates/user_profile/user_stats.html:120
+msgid "Answer to:"
+msgstr "Odgovor na:"
+
+#: skins/default/templates/user_profile/user_tabs.html:5
+msgid "User profile"
+msgstr "Korisnički profil"
+
+#: skins/default/templates/user_profile/user_tabs.html:10
+#: views/users.py:638
+msgid "comments and answers to others questions"
+msgstr "komentari i odgovori na druga pitanja"
+
+#: skins/default/templates/user_profile/user_tabs.html:16
+msgid "followers and followed users"
+msgstr "pratitelji i praćeni korisnici"
+
+#: skins/default/templates/user_profile/user_tabs.html:21
+msgid "Graph of user karma"
+msgstr "graf korisnikove karme"
+
+#: skins/default/templates/user_profile/user_tabs.html:25
+msgid "questions that user is following"
+msgstr "pitanja koje korisnici prate"
+
+#: skins/default/templates/user_profile/user_tabs.html:34
+#: views/users.py:679
+msgid "user vote record"
+msgstr "zapis glasova korisnika"
+
+#: skins/default/templates/user_profile/user_tabs.html:36
+#: skins/default/templates/user_profile/user_votes.html:4
+msgid "votes"
+msgstr "glasovi"
+
+#: skins/default/templates/user_profile/user_tabs.html:40
+#: views/users.py:769
+msgid "email subscription settings"
+msgstr "postavke za email pretplate"
+
+#: skins/default/templates/user_profile/user_tabs.html:46
+#: views/users.py:205
+msgid "moderate this user"
+msgstr "uredi ugled korisnika"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:3
+#: skins/default/templates/widgets/question_edit_tips.html:3
+msgid "Tips"
+msgstr "Savjeti"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:6
+msgid "give an answer interesting to this community"
+msgstr "napišite odgovor zanimljiv ovoj zajednici"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:9
+msgid "try to give an answer, rather than engage into a discussion"
+msgstr "pokušajte dati odgovor, ne se uključiti u raspravu"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:12
+#: skins/default/templates/widgets/question_edit_tips.html:8
+msgid "provide enough details"
+msgstr "dajte dovoljno informacija"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:15
+#: skins/default/templates/widgets/question_edit_tips.html:11
+msgid "be clear and concise"
+msgstr "budite jasni i precizni"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:20
+#: skins/default/templates/widgets/question_edit_tips.html:16
+msgid "see frequently asked questions"
+msgstr "pogledajte često postavljena pitanja"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:27
+#: skins/default/templates/widgets/question_edit_tips.html:22
+msgid "Markdown basics"
+msgstr "Markdown osnove"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:31
+#: skins/default/templates/widgets/question_edit_tips.html:26
+msgid "*italic*"
+msgstr "*kurziv*"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:34
+#: skins/default/templates/widgets/question_edit_tips.html:29
+msgid "**bold**"
+msgstr "**podebljano**"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:38
+#: skins/default/templates/widgets/question_edit_tips.html:33
+msgid "*italic* or _italic_"
+msgstr "*kurziv* ili _kurziv_"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:41
+#: skins/default/templates/widgets/question_edit_tips.html:36
+msgid "**bold** or __bold__"
+msgstr "**podebljano** ili __podebljano__"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:45
+#: skins/default/templates/widgets/answer_edit_tips.html:49
+#: skins/default/templates/widgets/question_edit_tips.html:40
+#: skins/default/templates/widgets/question_edit_tips.html:45
+msgid "text"
+msgstr "tekst"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:49
+#: skins/default/templates/widgets/question_edit_tips.html:45
+msgid "image"
+msgstr "slika"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:53
+#: skins/default/templates/widgets/question_edit_tips.html:49
+msgid "numbered list:"
+msgstr "brojčana lista:"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:58
+#: skins/default/templates/widgets/question_edit_tips.html:54
+msgid "basic HTML tags are also supported"
+msgstr "podržane su osnovne HTML oznake"
+
+#: skins/default/templates/widgets/answer_edit_tips.html:63
+#: skins/default/templates/widgets/question_edit_tips.html:59
+msgid "learn more about Markdown"
+msgstr "naučite više o Markdownu"
+
+#: skins/default/templates/widgets/ask_form.html:6
+msgid "login to post question info"
+msgstr "prijavite se za objavu informacija o pitanju"
+
+#: skins/default/templates/widgets/ask_form.html:7
+msgid "<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."
+msgstr "<span class=\\\"strong big\\\">Možete početi postavljati pitanja anonimno</span>. Nakon što predate post biti ćete preusmjereni na stranicu za prijavu/upis. Vaše pitanje biti će privremeno sačuvano i objavljeno nakon prijave. Proces prijave/upisa je jednostavan. Prijava traje oko 30 sekundi, a prvi upis oko minute."
+
+#: skins/default/templates/widgets/ask_form.html:11
+#, python-format
+msgid "<span class='strong big'>Looks like your email address, %%(email)s has not yet been validated.</span> To post messages you must verify your email, please see <a href='%%(email_validation_faq_url)s'>more details here</a>.<br>You can submit your question now and validate email after that. Your question will saved as pending meanwhile."
+msgstr "<span class='strong big'>Izgleda da vaša email adresa, %%(email)s nije potvrđena.</span> Za objavljivanje poruka morate potvrditi vaš email, pogledajte <a href='%%(email _validation_faq_url)s'>više informacija ovdje</a>.<br>Možete podnijet vaša pitanja sada i potvrditi email kasnije. Vaša pitanja će u međuvremenu biti sačuvana i na čekanju."
+
+#: skins/default/templates/widgets/contributors.html:3
+msgid "Contributors"
+msgstr "Aktivni korisnici"
+
+#: skins/default/templates/widgets/footer.html:33
+#, python-format
+msgid "Content on this site is licensed under a %(license)s"
+msgstr "Sadržaj na ovoj stanici je pod %(license)s licencom"
+
+#: skins/default/templates/widgets/footer.html:38
+msgid "about"
+msgstr "o nama"
+
+#: skins/default/templates/widgets/footer.html:40
+#: skins/default/templates/widgets/user_navigation.html:17
+msgid "help"
+msgstr "pomoć"
+
+#: skins/default/templates/widgets/footer.html:42
+msgid "privacy policy"
+msgstr "pravila o privatnosti"
+
+#: skins/default/templates/widgets/footer.html:51
+msgid "give feedback"
+msgstr "povratna informacija"
+
+#: skins/default/templates/widgets/logo.html:3
+msgid "back to home page"
+msgstr "nazad na početnu stranicu"
+
+#: skins/default/templates/widgets/logo.html:4
+#, python-format
+msgid "%(site)s logo"
+msgstr "%(site)s logo"
+
+#: skins/default/templates/widgets/meta_nav.html:10
+msgid "users"
+msgstr "people"
+
+#: skins/default/templates/widgets/meta_nav.html:15
+msgid "badges"
+msgstr "značke"
+
+#: skins/default/templates/widgets/question_edit_tips.html:5
+msgid "ask a question interesting to this community"
+msgstr "postavi pitanje zanimljivo ovoj zajednici"
+
+#: skins/default/templates/widgets/question_summary.html:12
+msgid "view"
+msgid_plural "views"
+msgstr[0] "pogled"
+msgstr[1] "pogleda"
+
+#: skins/default/templates/widgets/question_summary.html:29
+msgid "answer"
+msgid_plural "answers"
+msgstr[0] "odgovor"
+msgstr[1] "odgovora"
+
+#: skins/default/templates/widgets/question_summary.html:40
+msgid "vote"
+msgid_plural "votes"
+msgstr[0] "glas"
+msgstr[1] "glasova"
+
+#: skins/default/templates/widgets/scope_nav.html:6
+msgid "ALL"
+msgstr "SVA"
+
+#: skins/default/templates/widgets/scope_nav.html:8
+msgid "see unanswered questions"
+msgstr "ne odgovorena pitanja"
+
+#: skins/default/templates/widgets/scope_nav.html:8
+msgid "UNANSWERED"
+msgstr "BEZ ODGOVORA"
+
+#: skins/default/templates/widgets/scope_nav.html:11
+msgid "see your followed questions"
+msgstr "moja praćena pitanja"
+
+#: skins/default/templates/widgets/scope_nav.html:11
+msgid "FOLLOWED"
+msgstr "PRATIM"
+
+#: skins/default/templates/widgets/scope_nav.html:14
+msgid "Please ask your question here"
+msgstr "Postavi pitanje ovdje"
+
+#: skins/default/templates/widgets/user_long_score_and_badge_summary.html:3
+msgid "karma:"
+msgstr "karma:"
+
+#: skins/default/templates/widgets/user_long_score_and_badge_summary.html:7
+msgid "badges:"
+msgstr "značke:"
+
+#: skins/default/templates/widgets/user_navigation.html:9
+msgid "sign out"
+msgstr "odjava"
+
+#: skins/default/templates/widgets/user_navigation.html:12
+msgid "Hi, there! Please sign in"
+msgstr "Pozdrav! Prijavite se"
+
+#: skins/default/templates/widgets/user_navigation.html:15
+msgid "settings"
+msgstr "postavke"
+
+#: templatetags/extra_filters_jinja.py:279
+msgid "no"
+msgstr "0"
+
+#: utils/decorators.py:90
+#: views/commands.py:73
+#: views/commands.py:93
+msgid "Oops, apologies - there was some error"
+msgstr "Uups, oprostite - došlo je do greške"
+
+#: utils/decorators.py:109
+msgid "Please login to post"
+msgstr "Prijavite se za objavu posta"
+
+#: utils/decorators.py:205
+msgid "Spam was detected on your post, sorry for if this is a mistake"
+msgstr "Neželjen sadržaj otkriven je u vašem postu, ispričavamo se ako je ovo greška"
+
+#: utils/forms.py:33
+msgid "this field is required"
+msgstr "ovo polje je nužno"
+
+#: utils/forms.py:60
+msgid "Choose a screen name"
+msgstr "Odaberite prikazno ime"
+
+#: utils/forms.py:69
+msgid "user name is required"
+msgstr "Korisničko ime je nužno"
+
+#: utils/forms.py:70
+msgid "sorry, this name is taken, please choose another"
+msgstr "ovo ime je zauzeto, odaberite drugo"
+
+#: utils/forms.py:71
+msgid "sorry, this name is not allowed, please choose another"
+msgstr "ovo ime nije dozvoljeno, odaberite drugo"
+
+#: utils/forms.py:72
+msgid "sorry, there is no user with this name"
+msgstr "ne postoji korisnik s tim imenom"
+
+#: utils/forms.py:73
+msgid "sorry, we have a serious error - user name is taken by several users"
+msgstr "oprostite, nastala je velika greška - više korisnika ima isto korisničko ime"
+
+#: utils/forms.py:74
+msgid "user name can only consist of letters, empty space and underscore"
+msgstr "korisničko ime može sadržavati samo slova, razmake i znakove podvlačenja"
+
+#: utils/forms.py:75
+msgid "please use at least some alphabetic characters in the user name"
+msgstr "koristite najmanje nekoliko slova u korisničkom imenu"
+
+#: utils/forms.py:138
+msgid "Your email <i>(never shared)</i>"
+msgstr "Vaša email adresa"
+
+#: utils/forms.py:139
+msgid "email address is required"
+msgstr "email adresa je nužna"
+
+#: utils/forms.py:140
+msgid "please enter a valid email address"
+msgstr "unesite ispravnu email adresu"
+
+#: utils/forms.py:141
+msgid "this email is already used by someone else, please choose another"
+msgstr "ovaj email adresa se već koristi, odaberite drugu"
+
+#: utils/forms.py:170
+msgid "password is required"
+msgstr "lozinka je obvezna"
+
+#: utils/forms.py:173
+msgid "Password <i>(please retype)</i>"
+msgstr "Lozinka <i>(ponovo)</i>"
+
+#: utils/forms.py:174
+msgid "please, retype your password"
+msgstr "ponovo napišite vašu lozinku"
+
+#: utils/forms.py:175
+msgid "sorry, entered passwords did not match, please try again"
+msgstr "lozinke ne odgovaraju, pokušajte ponovo"
+
+#: utils/functions.py:82
+msgid "2 days ago"
+msgstr "prije 2 dana"
+
+#: utils/functions.py:84
+msgid "yesterday"
+msgstr "jučer"
+
+#: utils/functions.py:87
+#, python-format
+msgid "%(hr)d hour ago"
+msgid_plural "%(hr)d hours ago"
+msgstr[0] "prije %(hr)d sat"
+msgstr[1] "prije %(hr)d sati"
+
+#: utils/functions.py:93
+#, python-format
+msgid "%(min)d min ago"
+msgid_plural "%(min)d mins ago"
+msgstr[0] "prije %(min)d minute"
+msgstr[1] "prije %(min)d minuta"
+
+#: utils/mail.py:147
+msgid ""
+"<p>To ask by email, please:</p>\n"
+"<ul>\n"
+" <li>Format the subject line as: [Tag1; Tag2] Question title</li>\n"
+" <li>Type details of your question into the email body</li>\n"
+"</ul>\n"
+"<p>Note that tags may consist of more than one word, and tags\n"
+"may be separated by a semicolon or a comma</p>\n"
+msgstr ""
+"<p>Za pitanje putem emaila:</p>\n"
+"<ul>\n"
+" <li>Formirajte subjekt liniju ovako: [Oznaka1; Oznaka2] Naslov pitanja</li>\n"
+" <li>U tijelo emaila unesite detalje vašeg pitanja</li>\n"
+"</ul>\n"
+"<p>Imajte na umu da se oznake mogu sastojati od više riječi i \n"
+"mogu biti odvojene točka-zarezom ili zarezom</p>\n"
+
+#: utils/mail.py:167
+#, python-format
+msgid "<p>Sorry, there was an error posting your question please contact the %(site)s administrator</p>"
+msgstr "<p>Prilikom objave vašeg pitanja dogodila se greška. Kontaktirajte %(site)s administratora</p>"
+
+#: utils/mail.py:173
+#, python-format
+msgid "<p>Sorry, in order to post questions on %(site)s by email, please <a href=\"%(url)s\">register first</a></p>"
+msgstr "<p>Za objavu pitanja na %(site)s stranici putem emaila, <a href=\"%(url)s\">prvo se registrirajte</a></p>"
+
+#: utils/mail.py:181
+msgid "<p>Sorry, your question could not be posted due to insufficient privileges of your user account</p>"
+msgstr "<p>Vaše pitanje nije objavljeno zbog nedovoljnih prava vašeg korisničkog računa</p>"
+
+#: views/avatar_views.py:99
+msgid "Successfully uploaded a new avatar."
+msgstr "Uspješno ste poslali novi avatar."
+
+#: views/avatar_views.py:140
+msgid "Successfully updated your avatar."
+msgstr "Uspješno ste ažurirali vaš avatar."
+
+#: views/avatar_views.py:180
+msgid "Successfully deleted the requested avatars."
+msgstr "Uspješno ste obrisali zatražene avatare."
+
+#: views/commands.py:83
+msgid "Sorry, but anonymous users cannot access the inbox"
+msgstr "Anonimni korisnici nemaju pravo pristupa sandučiću"
+
+#: views/commands.py:112
+msgid "Sorry, anonymous users cannot vote"
+msgstr "Anonimni korisnici ne mogu glasati"
+
+#: views/commands.py:129
+msgid "Sorry you ran out of votes for today"
+msgstr "Ostali ste bez glasova danas"
+
+#: views/commands.py:135
+#, python-format
+msgid "You have %(votes_left)s votes left for today"
+msgstr "Ostalo vam je %(votes_left)s glasova za danas"
+
+#: views/commands.py:210
+msgid "Sorry, something is not right here..."
+msgstr "Nešto nije u redu ..."
+
+#: views/commands.py:229
+msgid "Sorry, but anonymous users cannot accept answers"
+msgstr "Anonimni korisnici ne mogu prihvaćati odgovore"
+
+#: views/commands.py:339
+#, python-format
+msgid "Your subscription is saved, but email address %(email)s needs to be validated, please see <a href=\"%(details_url)s\">more details here</a>"
+msgstr "Vaša pretplata je sačuvana, ali email adresa %(email)s mora biti potvrđena, pogledajte više detalja <a href=\"%(details_url)s\">ovdje</a>"
+
+#: views/commands.py:348
+msgid "email update frequency has been set to daily"
+msgstr "učestalost email dopune je postavljena na dnevno"
+
+#: views/commands.py:464
+#, python-format
+msgid "Tag subscription was canceled (<a href=\"%(url)s\">undo</a>)."
+msgstr "Pretplata na oznaku je otkazana (<a href=\"%(url)s\">vrati</a>)."
+
+#: views/commands.py:473
+#, python-format
+msgid "Please sign in to subscribe for: %(tags)s"
+msgstr "Prijavite se za pretplatu na: %(tags)s"
+
+#: views/commands.py:600
+msgid "Please sign in to vote"
+msgstr "Prijavite se za glasanje"
+
+#: views/commands.py:620
+msgid "Please sign in to delete/restore posts"
+msgstr "Prijavite se za brisanje/obnovu postova"
+
+#: views/meta.py:37
+#, python-format
+msgid "About %(site)s"
+msgstr "O %(site)s stranici"
+
+#: views/meta.py:92
+msgid "Q&A forum feedback"
+msgstr "P&O forum povratna informacija"
+
+#: views/meta.py:93
+msgid "Thanks for the feedback!"
+msgstr "Hvala na povratnoj informaciji!"
+
+#: views/meta.py:102
+msgid "We look forward to hearing your feedback! Please, give it next time :)"
+msgstr "Zanima nas vaše mišljenje! Dajte ga sljedeći put :)"
+
+#: views/meta.py:106
+msgid "Privacy policy"
+msgstr "Pravila o privatnosti"
+
+#: views/readers.py:133
+#, python-format
+msgid "%(q_num)s question, tagged"
+msgid_plural "%(q_num)s questions, tagged"
+msgstr[0] "%(q_num)s pitanje, označeno"
+msgstr[1] "%(q_num)s pitanja, označeno"
+
+#: views/readers.py:388
+msgid "Sorry, the comment you are looking for has been deleted and is no longer accessible"
+msgstr "Komentar koji tražite je obrisan i više nije dostupan"
+
+#: views/users.py:206
+msgid "moderate user"
+msgstr "uredi korisnika"
+
+#: views/users.py:381
+msgid "user profile"
+msgstr "korisnički profil"
+
+#: views/users.py:382
+msgid "user profile overview"
+msgstr "pregled korisničkog profila"
+
+#: views/users.py:551
+msgid "recent user activity"
+msgstr "zadnje aktivnosti korisnika"
+
+#: views/users.py:552
+msgid "profile - recent activity"
+msgstr "profil - zadnje aktivnosti"
+
+#: views/users.py:639
+msgid "profile - responses"
+msgstr "profil - odazivi"
+
+#: views/users.py:680
+msgid "profile - votes"
+msgstr "profil - glasovi"
+
+#: views/users.py:701
+msgid "user karma"
+msgstr "korisnikova karma"
+
+#: views/users.py:702
+msgid "Profile - User's Karma"
+msgstr "Profil - Korisnikova Karma"
+
+#: views/users.py:720
+msgid "users favorite questions"
+msgstr "omiljena pitanja korisnika"
+
+#: views/users.py:721
+msgid "profile - favorite questions"
+msgstr "profil - omiljena pitanja"
+
+#: views/users.py:741
+#: views/users.py:745
+msgid "changes saved"
+msgstr "promjene sačuvane"
+
+#: views/users.py:751
+msgid "email updates canceled"
+msgstr "email dopune opozvane"
+
+#: views/users.py:770
+msgid "profile - email subscriptions"
+msgstr "profil - email pretplate"
+
+#: views/writers.py:60
+msgid "Sorry, anonymous users cannot upload files"
+msgstr "Anonimni korisnici ne mogu postati datoteke"
+
+#: views/writers.py:73
+#, python-format
+msgid "allowed file types are '%(file_types)s'"
+msgstr "dopušteni tipovi datoteka su '%(file_types)s'"
+
+#: views/writers.py:84
+#, python-format
+msgid "maximum upload file size is %(file_size)sK"
+msgstr "maksimalna veličina poslane datoteke je %(file_size)sK"
+
+#: views/writers.py:92
+msgid "Error uploading file. Please contact the site administrator. Thank you."
+msgstr "Nastala je greška prilikom slanja datoteke. Kontaktirajte administratora. Hvala."
+
+#: views/writers.py:189
+msgid "<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."
+msgstr "<span class=\\\"strong big\\\">Možete početi postavljati pitanja anonimno</span>. Nakon što predate post biti ćete preusmjereni na stranicu za prijavu/upis. Vaše pitanje biti će privremeno sačuvano i objavljeno nakon prijave. Proces prijave/upisa je jednostavan. Prijava traje oko 30 sekundi, a prvi upis oko minute."
+
+#: views/writers.py:466
+msgid "Please log in to answer questions"
+msgstr "Prijavite se za odgovaranje na pitanja"
+
+#: views/writers.py:572
+#, python-format
+msgid "Sorry, you appear to be logged out and cannot post comments. Please <a href=\"%(sign_in_url)s\">sign in</a>."
+msgstr "Niste prijavljeni stoga ne možete objavljivati komentare. <a href=\"%(sign_in_url)s\">Prijavite se</a>."
+
+#: views/writers.py:589
+msgid "Sorry, anonymous users cannot edit comments"
+msgstr "Anonimni korisnici ne mogu uređivati komentare"
+
+#: views/writers.py:619
+#, python-format
+msgid "Sorry, you appear to be logged out and cannot delete comments. Please <a href=\"%(sign_in_url)s\">sign in</a>."
+msgstr "Niste prijavljeni stoga ne možete brisati komentare. <a href=\"%(sign_in_url)s\">Prijavite se</a>."
+
+#: views/writers.py:640
+msgid "sorry, we seem to have some technical difficulties"
+msgstr "Oprostite, imamo tehničkih poteškoća"
+
+#~ msgid "logout"
+#~ msgstr "sign out"
+
+#~ msgid ""
+#~ "As a registered user you can login with your OpenID, log out of the site "
+#~ "or permanently remove your account."
+#~ msgstr ""
+#~ "Clicking <strong>Logout</strong> will log you out from the forum but will "
+#~ "not sign you off from your OpenID provider.</p><p>If you wish to sign off "
+#~ "completely - please make sure to log out from your OpenID provider as "
+#~ "well."
+
+#~ msgid "Email verification subject line"
+#~ msgstr "Verification Email from Q&A forum"
+
+#~ msgid ""
+#~ "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 "
+#~ "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 "
+#~ "- create a unique <a href='%(gravatar_faq_url)s'><strong>gravatar</"
+#~ "strong></a> personal image.</p>"
diff --git a/askbot/locale/hr/LC_MESSAGES/djangojs.mo b/askbot/locale/hr/LC_MESSAGES/djangojs.mo
new file mode 100644
index 00000000..292f645e
--- /dev/null
+++ b/askbot/locale/hr/LC_MESSAGES/djangojs.mo
Binary files differ
diff --git a/askbot/locale/hr/LC_MESSAGES/djangojs.po b/askbot/locale/hr/LC_MESSAGES/djangojs.po
new file mode 100644
index 00000000..9f68c382
--- /dev/null
+++ b/askbot/locale/hr/LC_MESSAGES/djangojs.po
@@ -0,0 +1,295 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: 0.7\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-04-18 18:58-0500\n"
+"PO-Revision-Date: 2012-10-22 03:03+0100\n"
+"Last-Translator: Dario Kolak <dkolak@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: skins/common/media/jquery-openid/jquery.openid.js:73
+#, perl-format
+msgid "Are you sure you want to remove your %s login?"
+msgstr "Jeste li sigurni da želite ukloniti svoj %s prijavu?"
+
+#: skins/common/media/jquery-openid/jquery.openid.js:90
+msgid "Please add one or more login methods."
+msgstr "Dodajte jednu ili više načina prijave."
+
+#: skins/common/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 "Nemate način prijave, dodajte jednu ili više klikom na ikone ispod."
+
+#: skins/common/media/jquery-openid/jquery.openid.js:135
+msgid "passwords do not match"
+msgstr "lozinke ne odgovaraju"
+
+#: skins/common/media/jquery-openid/jquery.openid.js:161
+msgid "Show/change current login methods"
+msgstr "Prikaži/promijeni trenutne načine prijave"
+
+#: skins/common/media/jquery-openid/jquery.openid.js:226
+#, perl-format
+msgid "Please enter your %s, then proceed"
+msgstr "Unesite vaš %s zatim nastavite"
+
+#: skins/common/media/jquery-openid/jquery.openid.js:228
+msgid "Connect your %(provider_name)s account to %(site)s"
+msgstr "Spojite svoj %(provider_name)s korisnički račun i %(site)s"
+
+#: skins/common/media/jquery-openid/jquery.openid.js:322
+#, perl-format
+msgid "Change your %s password"
+msgstr "Promjenite svoju %s lozinku"
+
+#: skins/common/media/jquery-openid/jquery.openid.js:323
+msgid "Change password"
+msgstr "Promijeni lozinku"
+
+#: skins/common/media/jquery-openid/jquery.openid.js:326
+#, perl-format
+msgid "Create a password for %s"
+msgstr "Promijeni lozinku za %s"
+
+#: skins/common/media/jquery-openid/jquery.openid.js:327
+msgid "Create password"
+msgstr "Kreiraj lozinku"
+
+#: skins/common/media/jquery-openid/jquery.openid.js:343
+msgid "Create a password-protected account"
+msgstr "Kreirajte korisnički račun zaštićen lozinkom"
+
+#: skins/common/media/js/post.js:28
+msgid "loading..."
+msgstr "učitavanje ..."
+
+#: skins/common/media/js/post.js:318
+msgid "insufficient privilege"
+msgstr "nedovoljne privilegije"
+
+#: skins/common/media/js/post.js:319
+msgid "cannot pick own answer as best"
+msgstr "sorry, you cannot accept your own answer"
+
+#: skins/common/media/js/post.js:324
+msgid "please login"
+msgstr "prijavite se"
+
+#: skins/common/media/js/post.js:326
+msgid "anonymous users cannot follow questions"
+msgstr "anonimni korisnici ne mogu pratiti pitanja"
+
+#: skins/common/media/js/post.js:327
+msgid "anonymous users cannot subscribe to questions"
+msgstr "anonimni korisnici se ne mogu pretplatiti na pitanja"
+
+#: skins/common/media/js/post.js:328
+msgid "anonymous users cannot vote"
+msgstr "sorry, anonymous users cannot vote "
+
+#: skins/common/media/js/post.js:330
+msgid "please confirm offensive"
+msgstr "are you sure this post is offensive, contains spam, advertising, malicious remarks, etc.?"
+
+#: skins/common/media/js/post.js:331
+#, fuzzy
+msgid "please confirm removal of offensive flag"
+msgstr "are you sure this post is offensive, contains spam, advertising, malicious remarks, etc.?"
+
+#: skins/common/media/js/post.js:332
+msgid "anonymous users cannot flag offensive posts"
+msgstr "anonimni korisnici ne mogu označavati postove kao uvredljive"
+
+#: skins/common/media/js/post.js:333
+msgid "confirm delete"
+msgstr "are you sure you want to delete this?"
+
+#: skins/common/media/js/post.js:334
+msgid "anonymous users cannot delete/undelete"
+msgstr "sorry, anonymous users cannot delete or undelete posts"
+
+#: skins/common/media/js/post.js:335
+msgid "post recovered"
+msgstr "your post is now restored!"
+
+#: skins/common/media/js/post.js:336
+msgid "post deleted"
+msgstr "your post has been deleted"
+
+#: skins/common/media/js/post.js:1206
+msgid "add comment"
+msgstr "dodaj komentar"
+
+#: skins/common/media/js/post.js:1209
+msgid "save comment"
+msgstr "save comment"
+
+#: skins/common/media/js/post.js:1874
+msgid "Please enter question title (>10 characters)"
+msgstr "Unesite naslov pitanja (>10 znakova)"
+
+#: skins/common/media/js/tag_selector.js:15
+msgid "Tag \"<span></span>\" matches:"
+msgstr "Oznaka \"<span></span>\" odgovara:"
+
+#: skins/common/media/js/tag_selector.js:84
+#, perl-format
+msgid "and %s more, not shown..."
+msgstr "i %s više, nije prikazano ..."
+
+#: skins/common/media/js/user.js:14
+msgid "Please select at least one item"
+msgstr "Odaberite barem jednu stavku"
+
+#: skins/common/media/js/user.js:58
+msgid "Delete this notification?"
+msgid_plural "Delete these notifications?"
+msgstr[0] "Obrisati ovu obavijest ?"
+msgstr[1] "Obrisati ove obavijesti?"
+
+#: skins/common/media/js/user.js:65
+msgid "Close this entry?"
+msgid_plural "Close these entries?"
+msgstr[0] "Zatvoriti ovaj unos?"
+msgstr[1] "Zatvoriti ove unose?"
+
+#: skins/common/media/js/user.js:72
+msgid "Remove all flags on this entry?"
+msgid_plural "Remove all flags on these entries?"
+msgstr[0] "Ukloniti sve zastave na ovom unosu?"
+msgstr[1] "Ukloniti sve zastave na ovim unosima?"
+
+#: skins/common/media/js/user.js:79
+msgid "Delete this entry?"
+msgid_plural "Delete these entries?"
+msgstr[0] "Obrisati ovaj unos?"
+msgstr[1] "Obrisati ove unose?"
+
+#: skins/common/media/js/user.js:159
+msgid "Please <a href=\"%(signin_url)s\">signin</a> to follow %(username)s"
+msgstr "<a href=\"%(signin_url)s\">Prijavite se</a> za praćenje korsnika %(username)s"
+
+#: skins/common/media/js/user.js:191
+#, perl-format
+msgid "unfollow %s"
+msgstr "prestani pratit %s"
+
+#: skins/common/media/js/user.js:194
+#, perl-format
+msgid "following %s"
+msgstr "pratim %s"
+
+#: skins/common/media/js/user.js:200
+#, perl-format
+msgid "follow %s"
+msgstr "prati %s"
+
+#: skins/common/media/js/utils.js:44
+msgid "click to close"
+msgstr "kliknite za zatvaranje"
+
+#: skins/common/media/js/wmd/wmd.js:26
+msgid "bold"
+msgstr "podebljano"
+
+#: skins/common/media/js/wmd/wmd.js:27
+msgid "italic"
+msgstr "kurzivno"
+
+#: skins/common/media/js/wmd/wmd.js:28
+msgid "link"
+msgstr "veza"
+
+#: skins/common/media/js/wmd/wmd.js:29
+msgid "quote"
+msgstr "navodni znak"
+
+#: skins/common/media/js/wmd/wmd.js:30
+msgid "preformatted text"
+msgstr "uređen tekst"
+
+#: skins/common/media/js/wmd/wmd.js:31
+msgid "image"
+msgstr "slika"
+
+#: skins/common/media/js/wmd/wmd.js:32
+msgid "attachment"
+msgstr "privitak"
+
+#: skins/common/media/js/wmd/wmd.js:33
+msgid "numbered list"
+msgstr "numerirana lista"
+
+#: skins/common/media/js/wmd/wmd.js:34
+msgid "bulleted list"
+msgstr "lista s oznakama"
+
+#: skins/common/media/js/wmd/wmd.js:35
+msgid "heading"
+msgstr "zaglavlje"
+
+#: skins/common/media/js/wmd/wmd.js:36
+msgid "horizontal bar"
+msgstr "horizontalna linija"
+
+#: skins/common/media/js/wmd/wmd.js:37
+msgid "undo"
+msgstr "vratiti"
+
+#: skins/common/media/js/wmd/wmd.js:38
+#: skins/common/media/js/wmd/wmd.js:1053
+msgid "redo"
+msgstr "ponovo učiniti"
+
+#: skins/common/media/js/wmd/wmd.js:47
+msgid "enter image url"
+msgstr "enter URL of the image, e.g. http://www.example.com/image.jpg or upload an image file"
+
+#: skins/common/media/js/wmd/wmd.js:48
+msgid "enter url"
+msgstr "enter Web address, e.g. http://www.example.com \"page title\""
+
+#: skins/common/media/js/wmd/wmd.js:49
+msgid "upload file attachment"
+msgstr "Please choose and upload a file:"
+
+#~ msgid "tags cannot be empty"
+#~ msgstr "please enter at least one tag"
+
+#, fuzzy
+#~ msgid "%s content minchars"
+#~ msgstr "please enter more than %s characters"
+
+#~ msgid "%s title minchars"
+#~ msgstr "please enter at least %s characters"
+
+#~ msgid "Follow"
+#~ msgstr "Follow"
+
+#~ msgid "<div>Following</div><div class=\"unfollow\">Unfollow</div>"
+#~ msgstr "<div>Following</div><div class=\"unfollow\">Unfollow</div>"
+
+#~ msgid "enter %s more characters"
+#~ msgstr "please enter at least %s more characters"
+
+#~ msgid "confirm abandon comment"
+#~ msgstr "Are you sure you do not want to post this comment?"
+
+#~ msgid "confirm delete comment"
+#~ msgstr "do you really want to delete this comment?"
+
+#~ msgid "click to edit this comment"
+#~ msgstr "click to edit this comment"
+
+#~ msgid "edit"
+#~ msgstr "edit"
diff --git a/askbot/locale/ko/LC_MESSAGES/django.mo b/askbot/locale/ko/LC_MESSAGES/django.mo
index f22dabc6..5d0373dd 100644
--- a/askbot/locale/ko/LC_MESSAGES/django.mo
+++ b/askbot/locale/ko/LC_MESSAGES/django.mo
Binary files differ
diff --git a/askbot/locale/ko/LC_MESSAGES/django.po b/askbot/locale/ko/LC_MESSAGES/django.po
index bd9e27dc..8dab23ca 100644
--- a/askbot/locale/ko/LC_MESSAGES/django.po
+++ b/askbot/locale/ko/LC_MESSAGES/django.po
@@ -1,85 +1,92 @@
# English translation for CNPROG package.
# Copyright (C) 2009 Gang Chen, 2010 Askbot
# This file is distributed under the same license as the CNPROG package.
+#
+# Translators:
+# <16thetower@gmail.com>, 2012.
+# <chantrek@gmail.com>, 2012.
# Evgeny Fadeev <evgeny.fadeev@gmail.com>, 2009.
-msgid ""
-msgstr ""
-"Project-Id-Version: 0.7\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-04-18 18:51-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"
-"Language: ko\n"
+# <nocaca@daum.net>, 2012.
+# seok woojing <ultra066@gmail.com>, 2012.
+# Whoami Jeong <>, 2012.
+# 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: 2012-04-18 18:58-0500\n"
+"PO-Revision-Date: 2012-12-25 15:43+0000\n"
+"Last-Translator: Yong Choi <sk8er.choi@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"
"Content-Transfer-Encoding: 8bit\n"
+"Language: ko\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Translate Toolkit 1.9.0\n"
#: exceptions.py:13
msgid "Sorry, but anonymous visitors cannot access this function"
-msgstr ""
+msgstr "죄송합니다. 로그인 하지 않으면 이 기능을 사용 할 수 없습니다."
#: feed.py:28 feed.py:90
msgid " - "
-msgstr ""
+msgstr " - "
#: feed.py:28
msgid "Individual question feed"
-msgstr ""
+msgstr "개별 질문 피드"
#: feed.py:90
msgid "latest questions"
-msgstr ""
+msgstr "최근 질문들"
#: forms.py:74
msgid "select country"
-msgstr ""
+msgstr "국가 선택"
#: forms.py:83
msgid "Country"
-msgstr ""
+msgstr "국가"
#: forms.py:91
msgid "Country field is required"
-msgstr ""
+msgstr "국가를 선택해야 합니다"
#: forms.py:104 skins/default/templates/widgets/answer_edit_tips.html:45
#: skins/default/templates/widgets/answer_edit_tips.html:49
#: skins/default/templates/widgets/question_edit_tips.html:40
#: skins/default/templates/widgets/question_edit_tips.html:45
msgid "title"
-msgstr ""
+msgstr "제목"
#: forms.py:105
msgid "please enter a descriptive title for your question"
-msgstr ""
+msgstr "질문 내용을 요약하여 제목을 붙여주세요"
#: forms.py:113
#, python-format
msgid "title must be > %d character"
msgid_plural "title must be > %d characters"
-msgstr[0] ""
+msgstr[0] "제목은 %d 자보다 길어야 합니다"
#: forms.py:123
#, python-format
msgid "The title is too long, maximum allowed size is %d characters"
-msgstr ""
+msgstr "제목은 %d 자까지 쓰실 수 있습니다"
#: forms.py:130
#, python-format
msgid "The title is too long, maximum allowed size is %d bytes"
-msgstr ""
+msgstr "제목은 %d 바이트까지 쓰실 수 있습니다"
#: forms.py:149
msgid "content"
-msgstr ""
+msgstr "내용"
#: forms.py:185 skins/common/templates/widgets/edit_post.html:21
#: skins/default/templates/widgets/meta_nav.html:5
msgid "tags"
-msgstr ""
+msgstr "태그"
#: forms.py:188
#, python-format
@@ -89,495 +96,492 @@ msgid ""
msgid_plural ""
"Tags are short keywords, with no spaces within. Up to %(max_tags)d tags can "
"be used."
-msgstr[0] ""
+msgstr[0] "태그는 짧은 키워드로서, 공백이 포함되지 않습니다. %(max_tags)d 개까지의 태그를 사용할 수 있습니다."
#: forms.py:222 skins/default/templates/question_retag.html:58
msgid "tags are required"
-msgstr ""
+msgstr "태그를 붙여주세요"
#: forms.py:232
#, python-format
msgid "please use %(tag_count)d tag or less"
msgid_plural "please use %(tag_count)d tags or less"
-msgstr[0] ""
+msgstr[0] "%(tag_count)d 개 이하의 태그를 사용해주세요"
#: forms.py:240
#, python-format
msgid "At least one of the following tags is required : %(tags)s"
-msgstr ""
+msgstr "다음 태그들 중 적어도 하나는 선택해야 합니다 : %(tags)s"
#: forms.py:249
#, 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[0] "각 태그는 %(max_chars)d 자 이하여야 합니다"
#: forms.py:258
msgid "In tags, please use letters, numbers and characters \"-+.#\""
-msgstr ""
+msgstr "태그에는 글자, 숫자, \"-+.#\" 문자를 사용합니다"
#: forms.py:294
msgid "community wiki (karma is not awarded & many others can edit wiki post)"
-msgstr ""
+msgstr "커뮤니티 위키(위키 게시물은 다른 사람들이 편집할 수 있음 & 카르마는 부여되지 않음)"
#: forms.py:295
msgid ""
-"if you choose community wiki option, the question and answer do not generate "
-"points and name of author will not be shown"
-msgstr ""
+"if you choose community wiki option, the question and answer do not generate"
+" points and name of author will not be shown"
+msgstr "커뮤니티 위키 옵션을 선택하면 질문과 답변을 해도 포인트가 쌓이지 않으며 작성자의 이름도 표시되지 않습니다."
#: forms.py:311
msgid "update summary:"
-msgstr ""
+msgstr "변경사항 요약:"
#: forms.py:312
msgid ""
"enter a brief summary of your revision (e.g. fixed spelling, grammar, "
"improved style, this field is optional)"
-msgstr ""
+msgstr "바뀐 내용을 간단히 요약해주세요(맞춤법, 띄어쓰기, 문체 수정 등)."
#: forms.py:386
msgid "Enter number of points to add or subtract"
-msgstr ""
+msgstr "더하거나 뺄 점수를 입력하세요"
#: forms.py:400 const/__init__.py:253
msgid "approved"
-msgstr ""
+msgstr "승인됨"
#: forms.py:401 const/__init__.py:254
msgid "watched"
-msgstr ""
+msgstr "감시"
#: forms.py:402 const/__init__.py:255
msgid "suspended"
-msgstr ""
+msgstr "정지됨"
#: forms.py:403 const/__init__.py:256
msgid "blocked"
-msgstr ""
+msgstr "차단됨"
#: forms.py:405
msgid "administrator"
-msgstr ""
+msgstr "운영자"
#: forms.py:406 const/__init__.py:252
msgid "moderator"
-msgstr ""
+msgstr "조정자"
#: forms.py:426
msgid "Change status to"
-msgstr ""
+msgstr "상태를 변경"
#: forms.py:453
msgid "which one?"
-msgstr ""
+msgstr "선택"
#: forms.py:474
msgid "Cannot change own status"
-msgstr ""
+msgstr "자신의 상태를 변경할 수 없습니다."
#: forms.py:480
msgid "Cannot turn other user to moderator"
-msgstr ""
+msgstr "다른 사용자를 중재자로 전환할 수 없습니다"
#: forms.py:487
msgid "Cannot change status of another moderator"
-msgstr ""
+msgstr "다른 조정자의 상태를 변경할 수 없습니다."
#: forms.py:493
msgid "Cannot change status to admin"
-msgstr ""
+msgstr "운영자로 바꿀 수 없습니다"
#: forms.py:499
#, python-format
msgid ""
"If you wish to change %(username)s's status, please make a meaningful "
"selection."
-msgstr ""
+msgstr "%(username)s 의 상태를 바꾸시길 원하신다면, 의미 있는 선택을 해주세요."
#: forms.py:508
msgid "Subject line"
-msgstr ""
+msgstr "제목"
#: forms.py:515
msgid "Message text"
-msgstr ""
+msgstr "내용"
#: forms.py:530
msgid "Your name (optional):"
-msgstr ""
+msgstr "귀하의 이름 (선택):"
#: forms.py:531
-#, fuzzy
msgid "Email:"
-msgstr ""
-"<strong>Your Email</strong> (<i>must be valid, never shown to others</i>)"
+msgstr "이메일:"
#: forms.py:533
msgid "Your message:"
-msgstr ""
+msgstr "귀하의 메시지 :"
#: forms.py:538
msgid "I don't want to give my email or receive a response:"
-msgstr ""
+msgstr "이메일을 제공하거나 응답을 받고싶지 않습니다:"
#: forms.py:560
msgid "Please mark \"I dont want to give my mail\" field."
-msgstr ""
+msgstr "\"메일을 제공하고 싶지 않음\" 항목에 표시하세요."
#: forms.py:599
msgid "ask anonymously"
-msgstr ""
+msgstr "익명으로 질문"
#: forms.py:601
msgid "Check if you do not want to reveal your name when asking this question"
-msgstr ""
+msgstr "이 질문을 할때 이름을 숨기고 싶다면 체크하세요"
#: forms.py:624
msgid ""
-"Subject line is expected in the format: [tag1, tag2, tag3,...] question title"
-msgstr ""
+"Subject line is expected in the format: [tag1, tag2, tag3,...] question "
+"title"
+msgstr "주제 행 형식: [태그1, 태그2, 태그3,...] 질문 제목"
#: forms.py:769
msgid ""
"You have asked this question anonymously, if you decide to reveal your "
"identity, please check this box."
-msgstr ""
+msgstr "익명으로 질문을 올린 후, 다시 이름을 보이게 하고 싶다면 체크하세요."
#: forms.py:773
msgid "reveal identity"
-msgstr ""
+msgstr "이름 보이기"
#: forms.py:831
msgid ""
"Sorry, only owner of the anonymous question can reveal his or her identity, "
"please uncheck the box"
-msgstr ""
+msgstr "죄송합니다. 작성자만이 자신의 이름을 나타나게 할 수 있습니다."
#: forms.py:844
msgid ""
"Sorry, apparently rules have just changed - it is no longer possible to ask "
"anonymously. Please either check the \"reveal identity\" box or reload this "
"page and try editing the question again."
-msgstr ""
+msgstr "죄송합니다. 방금 규칙이 바뀐 것 같습니다 - 더이상 익명으로 질문할 수 없습니다. “이름 보이기” 를 체크하시던가, 페이지를 새로고침 한 후 다시 질문을 작성하세요."
#: forms.py:888
msgid "Real name"
-msgstr ""
+msgstr "실제 이름"
#: forms.py:895
msgid "Website"
-msgstr ""
+msgstr "웹사이트"
#: forms.py:902
msgid "City"
-msgstr ""
+msgstr "도시"
#: forms.py:911
msgid "Show country"
-msgstr ""
+msgstr "국가표시"
#: forms.py:916
msgid "Date of birth"
-msgstr ""
+msgstr "생일"
#: forms.py:917
msgid "will not be shown, used to calculate age, format: YYYY-MM-DD"
-msgstr ""
+msgstr "표시되지 않고 나이를 계산하는데 이용됩니다. 날짜형식: YYYY-MM-DD"
#: forms.py:923
msgid "Profile"
-msgstr ""
+msgstr "프로필"
#: forms.py:932
msgid "Screen name"
-msgstr ""
+msgstr "닉네임"
#: forms.py:963 forms.py:964
msgid "this email has already been registered, please use another one"
-msgstr ""
+msgstr "이미 등록된 이메일입니다. 다른 이메일을 사용해 주세요."
#: forms.py:971
msgid "Choose email tag filter"
-msgstr ""
+msgstr "이메일 태그 필터 선택"
#: forms.py:1018
msgid "Asked by me"
-msgstr ""
+msgstr "내 질문"
#: forms.py:1021
msgid "Answered by me"
-msgstr ""
+msgstr "내 답변"
#: forms.py:1024
msgid "Individually selected"
-msgstr ""
+msgstr "개별적으로 선택한 것"
#: forms.py:1027
msgid "Entire forum (tag filtered)"
-msgstr ""
+msgstr "게시판 전체 (태그 선별)"
#: forms.py:1031
msgid "Comments and posts mentioning me"
-msgstr ""
+msgstr "나를 언급한 댓글 및 게시물"
#: forms.py:1112
msgid "please choose one of the options above"
-msgstr ""
+msgstr "위의 옵션들 중 하나를 선택해 주세요"
#: forms.py:1115
msgid "okay, let's try!"
-msgstr ""
+msgstr "좋아요, 받아보겠습니다!"
#: forms.py:1118
-#, fuzzy, python-format
+#, python-format
msgid "no %(sitename)s email please, thanks"
-msgstr "no askbot email please, thanks"
+msgstr "%(sitename)s 이메일을 받지 않겠습니다"
#: lamson_handlers.py:126 tests/reply_by_email_tests.py:49
msgid "======= Reply above this line. ====-=-="
-msgstr ""
+msgstr "======= 이 선 위로 답변. ====-=-="
#: lamson_handlers.py:130
msgid ""
"Your message was malformed. Please make sure to qoute the "
"original notification you received at the end of your reply."
-msgstr ""
+msgstr "메시지의 형식이 올바르지 않습니다. 답변의 끝에 받은 원래의 알림을 인용하였는지 확인해주세요."
#: lamson_handlers.py:147
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 ""
+msgstr "시스템이 알지 못하는 이메일 주소에 답변하였거나, 알림을 받은 주소가 아닌 다른 주소로부터 답변하셨습니다"
#: urls.py:41
msgid "about/"
-msgstr ""
+msgstr "about/"
#: urls.py:42
msgid "faq/"
-msgstr ""
+msgstr "faq/"
#: urls.py:43
msgid "privacy/"
-msgstr ""
+msgstr "privacy/"
#: urls.py:44
msgid "help/"
-msgstr ""
+msgstr "help/"
#: urls.py:46 urls.py:51
msgid "answers/"
-msgstr ""
+msgstr "answers/"
#: urls.py:46 urls.py:87 urls.py:212
msgid "edit/"
-msgstr ""
+msgstr "edit/"
#: urls.py:51 urls.py:117
msgid "revisions/"
-msgstr ""
+msgstr "revisions/"
#: urls.py:61
-#, fuzzy
msgid "questions"
-msgstr "Tips"
+msgstr "questions"
#: urls.py:82 urls.py:87 urls.py:92 urls.py:97 urls.py:102 urls.py:107
#: urls.py:112 urls.py:117 urls.py:123 urls.py:299
msgid "questions/"
-msgstr ""
+msgstr "questions/"
#: urls.py:82
msgid "ask/"
-msgstr ""
+msgstr "ask/"
#: urls.py:92
msgid "retag/"
-msgstr ""
+msgstr "retag/"
#: urls.py:97
msgid "close/"
-msgstr ""
+msgstr "close/"
#: urls.py:102
msgid "reopen/"
-msgstr ""
+msgstr "reopen/"
#: urls.py:107
msgid "answer/"
-msgstr ""
+msgstr "answer/"
#: urls.py:112
msgid "vote/"
-msgstr ""
+msgstr "vote/"
#: urls.py:123
msgid "widgets/"
-msgstr ""
+msgstr "widgets/"
#: urls.py:158
msgid "tags/"
-msgstr ""
+msgstr "tags/"
#: urls.py:201
msgid "subscribe-for-tags/"
-msgstr ""
+msgstr "subscribe-for-tags/"
#: urls.py:206 urls.py:212 urls.py:218 urls.py:226
msgid "users/"
-msgstr ""
+msgstr "users/"
#: urls.py:219
msgid "subscriptions/"
-msgstr ""
+msgstr "subscriptions/"
#: urls.py:231
msgid "users/update_has_custom_avatar/"
-msgstr ""
+msgstr "users/update_has_custom_avatar/"
#: urls.py:236 urls.py:241
msgid "badges/"
-msgstr ""
+msgstr "badges/"
#: urls.py:246
msgid "messages/"
-msgstr ""
+msgstr "messages/"
#: urls.py:246
msgid "markread/"
-msgstr ""
+msgstr "markread/"
#: urls.py:262
msgid "upload/"
-msgstr ""
+msgstr "upload/"
#: urls.py:263
msgid "feedback/"
-msgstr ""
+msgstr "feedback/"
#: urls.py:305
msgid "question/"
-msgstr ""
+msgstr "question/"
#: urls.py:312 setup_templates/settings.py:210
#: skins/common/templates/authopenid/providers_javascript.html:7
msgid "account/"
-msgstr ""
+msgstr "account/"
#: conf/access_control.py:8
-#, fuzzy
msgid "Access control settings"
-msgstr "User login"
+msgstr "접근 제어 설정"
#: conf/access_control.py:17
msgid "Allow only registered user to access the forum"
-msgstr ""
+msgstr "등록된 사용자만이 포럼에 접근할 수 있습니다"
#: conf/badges.py:13
msgid "Badge settings"
-msgstr ""
+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"
-msgstr ""
+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"
-msgstr ""
+msgstr "정리의 달인: 최소 태그 사용 수"
#: conf/badges.py:230
msgid "Enthusiast: minimum days"
-msgstr ""
+msgstr "개근상: 최소 일수"
#: conf/email.py:15
msgid "Email and email alert settings"
-msgstr ""
+msgstr "이메일 및 이메일 경고 설정"
#: conf/email.py:24
msgid "Prefix for the email subject line"
@@ -587,358 +591,347 @@ msgstr "Welcome to the Q&A forum"
msgid ""
"This setting takes default from the django settingEMAIL_SUBJECT_PREFIX. A "
"value entered here will overridethe default."
-msgstr ""
+msgstr "이 설정들은 django의 EMAIL_SUBJECT_PREFIX 설정을 가져옵니다. 값을 기입하면 기본설정을 덮어씁니다."
#: conf/email.py:38
msgid "Enable email alerts"
-msgstr ""
+msgstr "이메일 경고 사용"
#: conf/email.py:47
msgid "Maximum number of news entries in an email alert"
-msgstr ""
+msgstr "이메일 알림에 들어갈 최대 뉴스 개수"
#: conf/email.py:57
msgid "Default notification frequency all questions"
-msgstr ""
+msgstr "모든 질문에 대한 기본 알림 주기"
#: conf/email.py:59
msgid "Option to define frequency of emailed updates for: all questions."
-msgstr ""
+msgstr "다음 내용에 대해서 이메일 업데이트 주기를 선택합니다: 모든 질문들."
#: conf/email.py:71
msgid "Default notification frequency questions asked by the user"
-msgstr ""
+msgstr "사용자에 의해서 질문이 요청되었을 때 얼마나 자주 알림을 받을지에 대한 기본값"
#: conf/email.py:73
msgid ""
"Option to define frequency of emailed updates for: Question asked by the "
"user."
-msgstr ""
+msgstr "다음 내용에 대해서 이메일 업데이트 주기를 선택합니다: 사용자에 의해 요청된 질문."
#: conf/email.py:85
msgid "Default notification frequency questions answered by the user"
-msgstr ""
+msgstr "사용자에 의해 답변된 질문에 대해 얼마나 자주 알림을 받을 지에 대한 기본값"
#: conf/email.py:87
msgid ""
"Option to define frequency of emailed updates for: Question answered by the "
"user."
-msgstr ""
+msgstr "다음 내용에 대해서 이메일 업데이트 주기를 선택합니다: 사용자에 의해 답변된 질문."
#: conf/email.py:99
msgid ""
-"Default notification frequency questions individually "
-"selected by the user"
-msgstr ""
+"Default notification frequency questions individually"
+" selected by the user"
+msgstr "사용자에 의해 개별적으로 선택된 질문에 대해 얼마나 자주 알림을 받을 지에 대한 기본값"
#: conf/email.py:102
msgid ""
"Option to define frequency of emailed updates for: Question individually "
"selected by the user."
-msgstr ""
+msgstr "다음 내용에 대해서 이메일 업데이트 주기를 선택합니다: 사용자에 의해 개별적으로 선택된 질문."
#: conf/email.py:114
msgid ""
"Default notification frequency for mentions and "
"comments"
-msgstr ""
+msgstr "댓글과 언급에 대해 얼마나 자주 알림을 받을 지에 대한 기본값"
#: conf/email.py:117
msgid ""
"Option to define frequency of emailed updates for: Mentions and comments."
-msgstr ""
+msgstr "다음 내용에 대해서 이메일 업데이트 주기를 선택합니다: 언급과 댓글."
#: conf/email.py:128
msgid "Send periodic reminders about unanswered questions"
-msgstr ""
+msgstr "답변 없는 질문에 대해서 주기적인 알림을 보냄"
#: conf/email.py:130
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 "주의: 이 기능을 사용하기 위해서는 관리 명령어인 \"send_unanswered_question_reminders\"를 실행해야 합니다.(예를 들어 cron job에 등록하여 적절히 주기적으로)"
#: conf/email.py:143
msgid "Days before starting to send reminders about unanswered questions"
-msgstr ""
+msgstr "몇일 후부터 답변 없는 질문에 대해 알림을 날릴지"
#: conf/email.py:154
msgid ""
"How often to send unanswered question reminders (in days between the "
"reminders sent)."
-msgstr ""
+msgstr "답변되지 않은 질문에 대한 알림 주기를 설정합니다(알림이 보내진지 몇일 만에)"
#: conf/email.py:166
msgid "Max. number of reminders to send about unanswered questions"
-msgstr ""
+msgstr "답변되지 않은 질문 알림의 최대 개수"
#: conf/email.py:177
msgid "Send periodic reminders to accept the best answer"
-msgstr ""
+msgstr "으뜸 답변을 선택하도록 주기적으로 알림을 보냄"
#: conf/email.py:179
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 ""
+"command \"send_accept_answer_reminders\" (for example, via a cron job - with"
+" an appropriate frequency) "
+msgstr "주의: 이 기능을 사용하기 위해서는 관리 명령어인 \"send_accept_answer_reminders\"를 실행해야 합니다.(예를 들어 cron job에 등록하여 적절히 주기적으로)"
#: conf/email.py:192
msgid "Days before starting to send reminders to accept an answer"
-msgstr ""
+msgstr "답변을 선택하도록 독촉 발송을 시작하기 몇일 전"
#: conf/email.py:203
msgid ""
"How often to send accept answer reminders (in days between the reminders "
"sent)."
-msgstr ""
+msgstr "얼마나 자주 답변 선택 독촉을 보낼것인가(독촉이 발송되고 몇일)"
#: conf/email.py:215
msgid "Max. number of reminders to send to accept the best answer"
-msgstr ""
+msgstr "으뜸 답변 선택 알림을 보낼 최대 횟수"
#: conf/email.py:227
msgid "Require email verification before allowing to post"
-msgstr ""
+msgstr "글을 올리기 위해서는 이메일 인증이 필요합니다"
#: conf/email.py:228
msgid ""
"Active email verification is done by sending a verification key in email"
-msgstr ""
+msgstr "보내드린 이메일의 인증키를 통해 활성 이메일 인증이 되었습니다"
#: conf/email.py:237
msgid "Allow only one account per email address"
-msgstr ""
+msgstr "한 계정당 하나의 이메일만 허용"
#: conf/email.py:246
msgid "Fake email for anonymous user"
-msgstr ""
+msgstr "익명 사용자를 위한 가짜 이메일"
#: conf/email.py:247
msgid "Use this setting to control gravatar for email-less user"
-msgstr ""
+msgstr "이메일 없는 사용자를 위한 그라바타 제어를 목적으로 설정을 사용"
#: conf/email.py:256
-#, fuzzy
msgid "Allow posting questions by email"
-msgstr ""
-"<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."
+msgstr "이메일을 통해서 질문 쓰기 허용"
#: conf/email.py:258
msgid ""
-"Before enabling this setting - please fill out IMAP settings in the settings."
-"py file"
-msgstr ""
+"Before enabling this setting - please fill out IMAP settings in the "
+"settings.py file"
+msgstr "이 설정을 활성화하기 전에 settings.py 파일 안의 IMAP 관련 설정들을 해주세요."
#: conf/email.py:269
msgid "Replace space in emailed tags with dash"
-msgstr ""
+msgstr "이메일 태그에서 공백을 대시로 바꾸기"
#: conf/email.py:271
msgid ""
"This setting applies to tags written in the subject line of questions asked "
"by email"
-msgstr ""
+msgstr "이메일을 통해 들어오는 질문의 제목에 쓰여진 태그를 적용하는 설정입니다"
#: conf/email.py:284
-#, fuzzy
msgid "Enable posting answers and comments by email"
-msgstr ""
-"<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."
+msgstr "이메일을 통한 답변 게시 및 댓글을 허용"
#: conf/email.py:287
msgid "To enable this feature make sure lamson is running"
-msgstr ""
+msgstr "이 기능을 사용하려면 lamson이 동작하고 있어야 합니다"
#: conf/email.py:298
msgid "Reply by email hostname"
-msgstr ""
+msgstr "Reply by 이메일 호스트명"
#: conf/email.py:311
msgid ""
-"Email replies having fewer words than this number will be posted as comments "
-"instead of answers"
-msgstr ""
+"Email replies having fewer words than this number will be posted as comments"
+" instead of answers"
+msgstr "이 숫자보다 적은 단어로 된 이메일 답장은 질문에 대한 답변이 아닌 댓글로서 게시됩니다"
#: conf/external_keys.py:11
msgid "Keys for external services"
-msgstr ""
+msgstr "외부 서비스를 위한 키"
#: conf/external_keys.py:19
msgid "Google site verification key"
-msgstr ""
+msgstr "구글 사이트 인증 키"
#: conf/external_keys.py:21
#, python-format
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 ""
+"This key helps google index your site please obtain is at <a "
+"href=\"%(url)s?hl=%(lang)s\">google webmasters tools site</a>"
+msgstr "이 키는 구글이 당신의 사이트를 색인하도록 도우며, <a href=\"%(url)s?hl=%(lang)s\">구글 웹마스터 도구 사이트</a>에서 얻을 수 있습니다"
#: conf/external_keys.py:36
msgid "Google Analytics key"
-msgstr ""
+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 "당신의 사이트를 모니터링하는데 Google Analytics를 사용하고 싶다면, <a href=\"%(url)s\">Google Analytics</a> 에서 하실 수 있습니다"
#: conf/external_keys.py:51
msgid "Enable recaptcha (keys below are required)"
-msgstr ""
+msgstr "reCAPTCHA 켜기 (아래의 키가 필요합니다.)"
#: conf/external_keys.py:62
msgid "Recaptcha public key"
-msgstr ""
+msgstr "reCAPTCHA 공개 키"
#: conf/external_keys.py:70
msgid "Recaptcha private key"
-msgstr ""
+msgstr "reCAPTCHA 개인 키"
#: conf/external_keys.py:72
#, python-format
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 ""
+"robots. Please get this and a public key at the <a "
+"href=\"%(url)s\">%(url)s</a>"
+msgstr "Recaptcha는 스팸 로봇들의 공격과 실제 사람을 구분하는데 도움을 주는 도구입니다. <a href=\"%(url)s\">%(url)s</a>에서 Recaptcha와 공개 키를 얻으세요."
#: conf/external_keys.py:84
msgid "Facebook public API key"
-msgstr ""
+msgstr "페이스북 공개 API 키"
#: conf/external_keys.py:86
#, python-format
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 ""
+"method at your site. Please obtain these keys at <a "
+"href=\"%(url)s\">facebook create app</a> site"
+msgstr "페이스북 API 키와 페이스북 시크릿은 당신의 사이트가 페이스북 커넥트 로그인을 사용할 수 있도록 해줍니다. <a href=\"%(url)s\">페이스북 앱 생성</a> 사이트에서 위의 키들을 얻으세요."
#: conf/external_keys.py:99
msgid "Facebook secret key"
-msgstr ""
+msgstr "페이스북 시크릿 키"
#: conf/external_keys.py:107
msgid "Twitter consumer key"
-msgstr ""
+msgstr "트위터 컨슈머 키"
#: conf/external_keys.py:109
#, python-format
msgid ""
-"Please register your forum at <a href=\"%(url)s\">twitter applications site</"
-"a>"
-msgstr ""
+"Please register your forum at <a href=\"%(url)s\">twitter applications "
+"site</a>"
+msgstr "<a href=\"%(url)s\">twitter applications site</a>에 귀하의 포럼을 등록해 주세요."
#: conf/external_keys.py:120
msgid "Twitter consumer secret"
-msgstr ""
+msgstr "트위터 컨슈머 시크릿"
#: conf/external_keys.py:128
msgid "LinkedIn consumer key"
-msgstr ""
+msgstr "링크드인 컨슈머 키"
#: conf/external_keys.py:130
#, python-format
msgid ""
-"Please register your forum at <a href=\"%(url)s\">LinkedIn developer site</a>"
-msgstr ""
+"Please register your forum at <a href=\"%(url)s\">LinkedIn developer "
+"site</a>"
+msgstr "<a href=\"%(url)s\">LinkedIn developer site</a>에 귀하의 포럼을 등록해주세요"
#: conf/external_keys.py:141
msgid "LinkedIn consumer secret"
-msgstr ""
+msgstr "링크드인 컨슈머 시크릿"
#: conf/external_keys.py:149
msgid "ident.ca consumer key"
-msgstr ""
+msgstr "ident.ca 컨슈머 키"
#: conf/external_keys.py:151
#, python-format
msgid ""
"Please register your forum at <a href=\"%(url)s\">Identi.ca applications "
"site</a>"
-msgstr ""
+msgstr "<a href=\"%(url)s\">Identi.ca applications site</a>에 귀하의 포럼을 등록해주세요"
#: conf/external_keys.py:162
msgid "ident.ca consumer secret"
-msgstr ""
+msgstr "ident.ca 컨슈머 시크릿"
#: conf/flatpages.py:11
msgid "Flatpages - about, privacy policy, etc."
-msgstr ""
+msgstr "일반 페이지 - 소개, 개인정보 정책, 기타."
#: conf/flatpages.py:19
msgid "Text of the Q&A forum About page (html format)"
-msgstr ""
+msgstr "Q&A 포럼 소개 페이지에 들어갈 글 (html 형식)"
#: 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 "\"소개\" 페이지에서 <a href=\"http://validator.w3.org/\">HTML 유효성 검사기를 사용</a>하여 입력한 내용을 점검하고 저장합니다."
#: conf/flatpages.py:32
msgid "Text of the Q&A forum FAQ page (html format)"
-msgstr ""
+msgstr "Q&A 포럼 FAQ 페이지에 들어갈 글 (html 형식)"
#: 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 "\"faq\" 페이지에서 <a href=\"http://validator.w3.org/\">HTML 유효성 검사기를 사용</a>하여 입력한 내용을 점검하고 저장합니다."
#: conf/flatpages.py:46
msgid "Text of the Q&A forum Privacy Policy (html format)"
-msgstr ""
+msgstr "Q&A 포럼 개인정보 정책 페이지에 들어갈 글 (html 형식)"
#: conf/flatpages.py:49
msgid ""
"Save, then <a href=\"http://validator.w3.org/\">use HTML validator</a> on "
"the \"privacy\" page to check your input."
-msgstr ""
+msgstr "\"개인정보\" 페이지에서 <a href=\"http://validator.w3.org/\">HTML 유효성 검사기를 사용</a>하여 입력한 내용을 점검하고 저장합니다."
#: conf/forum_data_rules.py:12
msgid "Data entry and display rules"
-msgstr ""
+msgstr "데이터 입출력 규칙"
#: conf/forum_data_rules.py:21
msgid "Enable embedding videos. "
-msgstr ""
+msgstr "비디오 포함 허용"
#: conf/forum_data_rules.py:23
#, 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:33
msgid "Check to enable community wiki feature"
-msgstr ""
+msgstr "커뮤니티 위키 기능을 사용하려면 체크"
#: conf/forum_data_rules.py:42
msgid "Allow asking questions anonymously"
-msgstr ""
+msgstr "익명으로 질문하는것을 허용"
#: conf/forum_data_rules.py:44
msgid ""
-"Users do not accrue reputation for anonymous questions and their identity is "
-"not revealed until they change their mind"
-msgstr ""
+"Users do not accrue reputation for anonymous questions and their identity is"
+" not revealed until they change their mind"
+msgstr "익명의 질문에 대해서는 평판이 쌓이지 않으며 스스로 마음을 바꾸지 않는 한 신원이 밝혀지지 않습니다"
#: conf/forum_data_rules.py:56
msgid "Allow posting before logging in"
-msgstr ""
+msgstr "로그인 전에 글쓰기 허용"
#: conf/forum_data_rules.py:58
msgid ""
@@ -946,334 +939,331 @@ 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 "로그인하기전에 사용자가 질문이나 답변 등록을 할 수 있게 하려면 체크해주세요. 사용자가 로그인 할 때마다 펜딩된 포스트를 체크하도록 로그인 시스템 조정이 필요할 수 있습니다. 애스크봇 로그인 시스템은 이 기능을 지원합니다."
#: conf/forum_data_rules.py:73
-#, fuzzy
msgid "Allow swapping answer with question"
-msgstr "Post Your Answer"
+msgstr "답변을 질문으로 바꿔치기 허용하기"
#: conf/forum_data_rules.py:75
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 "이 설정은 zendesk와 같은 다른 포럼들로부터 자료를 가져오는 경우, 자동 데이터 임포트가 원래의 질문을 올바로 탐지하는 데에 실패하였을 때에 도움을 줍니다."
#: conf/forum_data_rules.py:87
msgid "Maximum length of tag (number of characters)"
-msgstr ""
+msgstr "태그의 최대 길이(문자수)"
#: conf/forum_data_rules.py:96
msgid "Minimum length of title (number of characters)"
-msgstr ""
+msgstr "제목의 최대 길이(문자수)"
#: conf/forum_data_rules.py:106
msgid "Minimum length of question body (number of characters)"
-msgstr ""
+msgstr "질문 본문의 최소 길이(문자수)"
#: conf/forum_data_rules.py:117
msgid "Minimum length of answer body (number of characters)"
-msgstr ""
+msgstr "답변 본문의 최소 길이(문자수)"
#: conf/forum_data_rules.py:126
msgid "Are tags required?"
-msgstr ""
+msgstr "태그가 필요한가요?"
#: conf/forum_data_rules.py:135
msgid "Mandatory tags"
-msgstr ""
+msgstr "필수 태그"
#: conf/forum_data_rules.py:138
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 "질문에는 최소한 한 개 이상의 태그가 필요합니다. 와일드카드 태그 기능이 활성화 되어 있다면 필수 태그에 와일드카드를 사용할 수 있습니다."
#: conf/forum_data_rules.py:150
msgid "Force lowercase the tags"
-msgstr ""
+msgstr "태그에 소문자만 허용"
#: conf/forum_data_rules.py:152
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 "주의: 체크한 후에는, 데이터베이스를 백업하고, 전체 태그들의 이름을 바꿔주는 다음 명령을 수행하세요: <code>python manage.py fix_question_tags</code>"
#: conf/forum_data_rules.py:166
msgid "Format of tag list"
-msgstr ""
+msgstr "태크 목록의 형식"
#: conf/forum_data_rules.py:168
msgid ""
-"Select the format to show tags in, either as a simple list, or as a tag cloud"
-msgstr ""
+"Select the format to show tags in, either as a simple list, or as a tag "
+"cloud"
+msgstr "간단한 목록나 태그 클라우드 중 선택"
#: conf/forum_data_rules.py:180
-#, fuzzy
msgid "Use wildcard tags"
-msgstr "Tags"
+msgstr "와일드카드 태그 사용하기"
#: conf/forum_data_rules.py:182
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 "와일드카드 태그는 한번에 많은 태그들을 팔로우하거나 무시할 수 있습니다. 마지막에 한 개의 와일드카드를 갖는 와일드카드 태그가 유효합니다"
#: conf/forum_data_rules.py:195
msgid "Default max number of comments to display under posts"
-msgstr ""
+msgstr "게시물 아래에 표시되는 댓글의 최대 개수의 기본값"
#: conf/forum_data_rules.py:206
#, python-format
msgid "Maximum comment length, must be < %(max_len)s"
-msgstr ""
+msgstr "최대 댓글 개수는 %(max_len)s 보다 작아야합니다"
#: conf/forum_data_rules.py:216
msgid "Limit time to edit comments"
-msgstr ""
+msgstr "댓글 수정 제한 시간"
#: conf/forum_data_rules.py:218
msgid "If unchecked, there will be no time limit to edit the comments"
-msgstr ""
+msgstr "체크하지 않으면, 댓글 수정에 시간 제한을 두지 않습니다"
#: conf/forum_data_rules.py:229
msgid "Minutes allowed to edit a comment"
-msgstr ""
+msgstr "댓글 수정 허용 시간"
#: conf/forum_data_rules.py:230
msgid "To enable this setting, check the previous one"
-msgstr ""
+msgstr "이 설정을 활성화 하려면 이전 항목을 체크하세요"
#: conf/forum_data_rules.py:239
msgid "Save comment by pressing <Enter> key"
-msgstr ""
+msgstr "<Enter>를 눌러서 댓글을 저장하세요"
#: conf/forum_data_rules.py:248
msgid "Minimum length of search term for Ajax search"
-msgstr ""
+msgstr "Ajax 검색 조건의 최소 길이"
#: conf/forum_data_rules.py:249
msgid "Must match the corresponding database backend setting"
-msgstr ""
+msgstr "해당 데이터베이스 백엔드 설정을 일치시켜야 합니다"
#: conf/forum_data_rules.py:258
msgid "Do not make text query sticky in search"
-msgstr ""
+msgstr "Do not make text query sticky in search"
#: conf/forum_data_rules.py:260
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 "검색 질의의 \"달라붙는\" 성질을 비활성화하려면 체크합니다. 검색 막대를 기본 위치에서 떨어진 곳으로 옮기고자 하거나 텍스트 검색 질의가 달라붙는 속성을 좋아하지 않는다면 유용합니다."
#: conf/forum_data_rules.py:273
msgid "Maximum number of tags per question"
-msgstr ""
+msgstr "질문당 최대 태그 개수"
#: conf/forum_data_rules.py:285
msgid "Number of questions to list by default"
-msgstr ""
+msgstr "목록당 최대 질문 기본 개수"
#: conf/forum_data_rules.py:295
msgid "What should \"unanswered question\" mean?"
-msgstr ""
+msgstr "\"답변 없는 질문\"은 무엇을 의미합니까?"
#: conf/ldap.py:9
msgid "LDAP login configuration"
-msgstr ""
+msgstr "LDAP 로그인 설정"
#: conf/ldap.py:17
msgid "Use LDAP authentication for the password login"
-msgstr ""
+msgstr "비밀번호 로그인에 LDAP 인증을 사용"
#: conf/ldap.py:26
msgid "LDAP URL"
-msgstr ""
+msgstr "LDAP URL"
#: conf/ldap.py:35
msgid "LDAP BASE DN"
-msgstr ""
+msgstr "LDAP BASE DN"
#: conf/ldap.py:43
msgid "LDAP Search Scope"
-msgstr ""
+msgstr "LDAP 검색 범위"
#: conf/ldap.py:52
msgid "LDAP Server USERID field name"
-msgstr ""
+msgstr "LDAP 서버 USERID 필드명"
#: conf/ldap.py:61
msgid "LDAP Server \"Common Name\" field name"
-msgstr ""
+msgstr "LDAP 서버 \"공통 이름\" 필드명"
#: conf/ldap.py:70
msgid "LDAP Server EMAIL field name"
-msgstr ""
+msgstr "LDAP 서버 EMAIL 필드명"
#: conf/leading_sidebar.py:12
-#, fuzzy
msgid "Common left sidebar"
-msgstr "Tags"
+msgstr "공통 왼쪽 사이드바"
#: conf/leading_sidebar.py:20
msgid "Enable left sidebar"
-msgstr ""
+msgstr "왼쪽 사이드바 활성화"
#: conf/leading_sidebar.py:29
msgid "HTML for the left sidebar"
-msgstr ""
+msgstr "왼쪽 사이드바의 HTML"
#: 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 "이 구역을 왼쪽 사이드바의 내용을 HTML 형식으로 입력하는 데에 사용하세요. 이 옵션을 사용할 때에는, HTML 검증 서비스를 사용하여 입력이 올바르며 모든 브라우저에서 잘 동작하는지 확인해주세요."
#: conf/license.py:13
msgid "Content License"
-msgstr ""
+msgstr "컨텐츠 라이선스"
#: conf/license.py:21
msgid "Show license clause in the site footer"
-msgstr ""
+msgstr "사이트 바닥글에 라이선스 조항 보이기"
#: conf/license.py:30
msgid "Short name for the license"
-msgstr ""
+msgstr "라이선스의 약식 이름"
#: conf/license.py:39
msgid "Full name of the license"
-msgstr ""
+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"
-msgstr ""
+msgstr "라이선스 페이지로의 링크 추가"
#: conf/license.py:57
msgid "License homepage"
-msgstr ""
+msgstr "라이선스 홈페이지"
#: conf/license.py:59
msgid "URL of the official page with all the license legal clauses"
-msgstr ""
+msgstr "라이선스 법적 조항 공식 페이지의 URL"
#: conf/license.py:69
msgid "Use license logo"
-msgstr ""
+msgstr "라이선스 로고 사용"
#: conf/license.py:78
msgid "License logo image"
-msgstr ""
+msgstr "라이선스 로고 이미지"
#: conf/login_providers.py:13
msgid "Login provider setings"
-msgstr ""
+msgstr "로그인 서비스 제공자 설정"
#: conf/login_providers.py:22
-msgid ""
-"Show alternative login provider buttons on the password \"Sign Up\" page"
-msgstr ""
+msgid "Show alternative login provider buttons on the password \"Sign Up\" page"
+msgstr "비밀번호 \"가입\" 페이지에 대체 로그인 제공자 버튼을 보여줍니다."
#: conf/login_providers.py:31
msgid "Always display local login form and hide \"Askbot\" button."
-msgstr ""
+msgstr "항상 로컬 로그인 폼을 표시하고 \"Askbot\" 버튼을 숨김"
#: conf/login_providers.py:40
msgid "Activate to allow login with self-hosted wordpress site"
-msgstr ""
+msgstr "직접 호스팅하는 워드프레스 사이트로 로그인하는 기능을 활성화"
#: conf/login_providers.py:41
msgid ""
"to activate this feature you must fill out the wordpress xml-rpc setting "
"bellow"
-msgstr ""
+msgstr "이 기능을 활성화 시키기 위해서는 아래의 워드프레스 xml-rpc설정을 작성해야함"
#: conf/login_providers.py:50
msgid ""
-"Fill it with the wordpress url to the xml-rpc, normally http://mysite.com/"
-"xmlrpc.php"
-msgstr ""
+"Fill it with the wordpress url to the xml-rpc, normally "
+"http://mysite.com/xmlrpc.php"
+msgstr "워드프레스의 xml-rpc url을 입력합니다. 예: 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 "활성화하기 위해서, 설정 -> 쓰기 -> 원격 전송으로 이동하여 XML-RPC 상자를 확인하세요"
#: conf/login_providers.py:60
msgid "Upload your icon"
-msgstr ""
+msgstr "아이콘을 업로드하세요"
#: conf/login_providers.py:90
#, python-format
msgid "Activate %(provider)s login"
-msgstr ""
+msgstr "%(provider)s 로그인 활성화"
#: conf/login_providers.py:95
#, python-format
msgid ""
"Note: to really enable %(provider)s login some additional parameters will "
"need to be set in the \"External keys\" section"
-msgstr ""
+msgstr "주의: %(provider)s 로그인을 정말로 활성화하려면 \"외부 키\" 섹션에서 추가적인 파라미터를 설정하여야 합니다"
#: conf/markup.py:15
msgid "Markup in posts"
-msgstr ""
+msgstr "게시물 내의 마크업"
#: conf/markup.py:41
msgid "Enable code-friendly Markdown"
-msgstr ""
+msgstr "코드 친화적 마크다운 활성화"
#: conf/markup.py:43
msgid ""
-"If checked, underscore characters will not trigger italic or bold formatting "
-"- bold and italic text can still be marked up with asterisks. Note that "
+"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."
-msgstr ""
+msgstr "체크한 경우, 밑줄 문자는 이탤릭체나 볼드 형식으로 바뀌지 않습니다. 즉, 볼드와 이탤릭 텍스트는 계속 별표로 표시됩니다. \"MathJax 지원\"은 이 기능을 묵시적으로 사용함에 유의하세요. LaTeX 입력에서는 밑줄을 많이 사용하기 때문에 그렇습니다. "
#: conf/markup.py:58
msgid "Mathjax support (rendering of LaTeX)"
-msgstr ""
+msgstr "Mathjax 지원 (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 "이 기능을 활성화하면, <a href=\"%(url)s\">mathjax</a>가 귀하의 서버의 자기 디렉토리에 설치되어 있어야 합니다."
#: conf/markup.py:74
msgid "Base url of MathJax deployment"
-msgstr ""
+msgstr "MathJax 디플로이먼트 Base url"
#: 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 "주의 - <strong>MathJax는 askbot에 포함되지 않습니다</strong>. 귀하가 스스로 배포하여야 하며, 별도의 도메인에 두고 \"mathjax\" 디렉토리를 가리키는 url을 입력하는 것을 권장합니다(예: http://mysite.com/mathjax)"
#: conf/markup.py:91
msgid "Enable autolinking with specific patterns"
-msgstr ""
+msgstr "특정 패턴에 대한 자동 링크 활성화"
#: conf/markup.py:93
msgid ""
-"If you enable this feature, the application will be able to detect patterns "
-"and auto link to URLs"
-msgstr ""
+"If you enable this feature, the application will be able to detect patterns"
+" and auto link to URLs"
+msgstr "이 기능을 활성화하면, 애플리케이션이 패턴을 인식하여 URL을 자동 링크할 수 있습니다"
#: conf/markup.py:106
msgid "Regexes to detect the link patterns"
-msgstr ""
+msgstr "링크 패턴을 감지하기 위해 Regexes"
#: conf/markup.py:108
msgid ""
@@ -1282,177 +1272,176 @@ 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 "유효한 정규표현식을 행마다 한 개 씩 입력하십시오. 예를 들어 #bug123과 같이 버그를 나타내는 패턴을 인식하려면, #bug(\\d+)와 같은 정규표현식을 사용합니다. 괄호 내에서 캡처되는 패턴은 링크 url 템플릿으로 전달됩니다. 정규표현식에 대한 자료를 찾아보시기 바랍니다."
#: conf/markup.py:127
msgid "URLs for autolinking"
-msgstr ""
+msgstr "자동 링크 URL"
#: conf/markup.py:129
msgid ""
"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 "
+"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."
-msgstr ""
+msgstr "이곳에는, 이전의 설정에서 입력한 패턴의 url 템플릿을, 각 행마다 한 개 씩 입력합니다. <strong>이 설정의 행 수가 이전과 동일한지 확인하시기 바랍니다</strong> 예를 들어, 템플릿 https://bugzilla.redhat.com/show_bug.cgi?id=\\1 가 위의 패턴과 함께 보이면 게시물 #123은 redhat 버그 트래커의 버그 123으로 링크를 생성합니다."
#: conf/minimum_reputation.py:12
msgid "Karma thresholds"
-msgstr ""
+msgstr "카르마 한계치"
#: conf/minimum_reputation.py:22
msgid "Upvote"
-msgstr ""
+msgstr "찬성표"
#: conf/minimum_reputation.py:31
msgid "Downvote"
-msgstr ""
+msgstr "반대표"
#: conf/minimum_reputation.py:40
-#, fuzzy
msgid "Answer own question immediately"
-msgstr "Post Your Answer"
+msgstr "자신의 질문에 즉시 답하기"
#: conf/minimum_reputation.py:49
msgid "Accept own answer"
-msgstr ""
+msgstr "자신의 답변을 채택"
#: conf/minimum_reputation.py:58
msgid "Flag offensive"
-msgstr ""
+msgstr "공격적인 게시물 신고하기"
#: conf/minimum_reputation.py:67
msgid "Leave comments"
-msgstr ""
+msgstr "댓글 남기기"
#: conf/minimum_reputation.py:76
msgid "Delete comments posted by others"
-msgstr ""
+msgstr "다른 사람이 쓴 댓글을 삭제"
#: conf/minimum_reputation.py:85
msgid "Delete questions and answers posted by others"
-msgstr ""
+msgstr "다른 사람이 게시한 질문과 답변을 삭제"
#: conf/minimum_reputation.py:94
msgid "Upload files"
-msgstr ""
+msgstr "파일 업로드"
#: conf/minimum_reputation.py:103
msgid "Close own questions"
-msgstr ""
+msgstr "자신의 질문을 종료"
#: conf/minimum_reputation.py:112
msgid "Retag questions posted by other people"
-msgstr ""
+msgstr "다른 사람이 올린 질문의 태그를 변경"
#: conf/minimum_reputation.py:121
msgid "Reopen own questions"
-msgstr ""
+msgstr "자신의 질문을 다시 열기"
#: conf/minimum_reputation.py:130
msgid "Edit community wiki posts"
-msgstr ""
+msgstr "커뮤니티 위키 게시물 편집"
#: conf/minimum_reputation.py:139
msgid "Edit posts authored by other people"
-msgstr ""
+msgstr "다른 사람이 작성한 게시물을 편집"
#: conf/minimum_reputation.py:148
msgid "View offensive flags"
-msgstr ""
+msgstr "공격적인 게시물에 대한 신고 보기"
#: conf/minimum_reputation.py:157
msgid "Close questions asked by others"
-msgstr ""
+msgstr "다른 사용자의 질문을 종료"
#: conf/minimum_reputation.py:166
msgid "Lock posts"
-msgstr ""
+msgstr "게시물 잠금"
#: conf/minimum_reputation.py:175
msgid "Remove rel=nofollow from own homepage"
-msgstr ""
+msgstr "홈페이지로부터 rel=nofollow 제거"
#: conf/minimum_reputation.py:177
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:190
msgid "Post answers and comments by email"
-msgstr ""
+msgstr "이메일을 통해 답변 및 댓글 게시"
#: conf/reputation_changes.py:13
msgid "Karma loss and gain rules"
-msgstr ""
+msgstr "카르마 증감 규칙"
#: conf/reputation_changes.py:23
msgid "Maximum daily reputation gain per user"
-msgstr ""
+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 ""
+msgstr "동일한 리비전에 대하여 3번 신고된 포스트 소유자가 받는 감점"
#: conf/reputation_changes.py:138
msgid "Loss for owner of post that was flagged 5 times per same revision"
-msgstr ""
+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"
-msgstr ""
+msgstr "메인 페이지 사이드바"
#: conf/sidebar_main.py:20 conf/sidebar_profile.py:20
#: conf/sidebar_question.py:19
msgid "Custom sidebar header"
-msgstr ""
+msgstr "맞춤 사이드바 머리글"
#: conf/sidebar_main.py:23 conf/sidebar_profile.py:23
#: conf/sidebar_question.py:22
@@ -1461,95 +1450,94 @@ 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 "이 구역에는 HTML 형식의 사이드바의 상단에 들어갈 내용을 입력합니다. 이 옵션을 사용할 때에는(사이드바 바닥글과 마찬가지로), HTML 검증 서비스를 사용하여 입력이 올바르며 모든 브라우저에서 잘 동작하는지 확인하시기 바랍니다."
#: conf/sidebar_main.py:36
msgid "Show avatar block in sidebar"
-msgstr ""
+msgstr "사이드바에 아바타 블록을 표시"
#: conf/sidebar_main.py:38
msgid "Uncheck this if you want to hide the avatar block from the sidebar "
-msgstr ""
+msgstr "사이드바에서 아바타 블록을 숨기고 싶으면 체크를 해제합니다"
#: conf/sidebar_main.py:49
msgid "Limit how many avatars will be displayed on the sidebar"
-msgstr ""
+msgstr "사이드바에 보여지게 될 아바타 개수를 정할 수 있습니다"
#: conf/sidebar_main.py:59
msgid "Show tag selector in sidebar"
-msgstr ""
+msgstr "사이드바에서 태그 선택기를 보이게 합니다"
#: conf/sidebar_main.py:61
msgid ""
"Uncheck this if you want to hide the options for choosing interesting and "
"ignored tags "
-msgstr ""
+msgstr "관심 있거나 무시할 태그를 선택하는 옵션을 숨기고 싶으면 체크를 해제합니다."
#: conf/sidebar_main.py:72
msgid "Show tag list/cloud in sidebar"
-msgstr ""
+msgstr "사이드바에 태그 목록/클라우드 보이기"
#: conf/sidebar_main.py:74
msgid ""
"Uncheck this if you want to hide the tag cloud or tag list from the sidebar "
-msgstr ""
+msgstr "사이드바로부터 태그 클라우드 또는 태그 목록을 숨기고 싶으면 체크를 해제합니다"
#: conf/sidebar_main.py:85 conf/sidebar_profile.py:36
#: conf/sidebar_question.py:75
msgid "Custom sidebar footer"
-msgstr ""
+msgstr "사이드바 맞춤 바닥글"
#: conf/sidebar_main.py:88 conf/sidebar_profile.py:39
#: conf/sidebar_question.py:78
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 "
-"validation service to make sure that your input is valid and works well in "
-"all browsers."
-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."
+msgstr "이 구역에는 HTML 형식의 사이드바의 하단에 들어갈 내용을 입력합니다. 이 옵션을 사용할 때에는(사이드바 머리글과 마찬가지로), HTML 검증 서비스를 사용하여 입력이 올바르며 모든 브라우저에서 잘 동작하는지 확인하시기 바랍니다."
#: conf/sidebar_profile.py:12
msgid "User profile sidebar"
-msgstr ""
+msgstr "사용자 프로필 사이드바"
#: conf/sidebar_question.py:11
-#, fuzzy
msgid "Question page sidebar"
-msgstr "Tags"
+msgstr "질문 페이지 사이드바"
#: conf/sidebar_question.py:35
msgid "Show tag list in sidebar"
-msgstr ""
+msgstr "사이드바에 태그 목록 보이기"
#: conf/sidebar_question.py:37
msgid "Uncheck this if you want to hide the tag list from the sidebar "
-msgstr ""
+msgstr "사이드바로부터 태그 목록을 숨기고 싶으면 체크를 해제합니다"
#: conf/sidebar_question.py:48
msgid "Show meta information in sidebar"
-msgstr ""
+msgstr "사이드바에 메타 정보를 보입니다"
#: conf/sidebar_question.py:50
msgid ""
"Uncheck this if you want to hide the meta information about the question "
"(post date, views, last updated). "
-msgstr ""
+msgstr "질문에 대한 메타 정보(게시일, 조회수, 마지막 업데이트)를 숨기고 싶으면 체크를 해제합니다."
#: conf/sidebar_question.py:62
msgid "Show related questions in sidebar"
-msgstr ""
+msgstr "관련된 질문을 사이드바에 보이기"
#: conf/sidebar_question.py:64
msgid "Uncheck this if you want to hide the list of related questions. "
-msgstr ""
+msgstr "관련된 질문 목록을 숨기고 싶으면 체크를 해제합니다"
#: conf/site_modes.py:64
msgid "Bootstrap mode"
-msgstr ""
+msgstr "부트스트랩 모드"
#: conf/site_modes.py:74
msgid "Activate a \"Bootstrap\" mode"
-msgstr ""
+msgstr "\"부트스트랩\" 모드를 활성화합니다"
#: conf/site_modes.py:76
msgid ""
@@ -1557,67 +1545,67 @@ msgid ""
"more suitable for the smaller communities, <strong>WARNING:</strong> your "
"current value for Minimum reputation, Bagde Settings and Vote Rules will be "
"changed after you modify this setting."
-msgstr ""
+msgstr "부트스트랩 모드는 평판 및 특정 배지 한계치를 낮추며, 작은 규모의 커뮤니티에 알맞습니다. <strong>경고:</strong> 이 설정을 수정하면 현재의 최소 평판, 배지 설정 및 투표 규칙의 값이 변경됩니다."
#: conf/site_settings.py:12
msgid "URLS, keywords & greetings"
-msgstr ""
+msgstr "URL, 키워드 및 인사말"
#: conf/site_settings.py:21
msgid "Site title for the Q&A forum"
-msgstr ""
+msgstr "Q&A 포럼의 사이트 제목"
#: conf/site_settings.py:30
msgid "Comma separated list of Q&A site keywords"
-msgstr ""
+msgstr "Q&A 사이트 키워드의 쉼표로 구분한 목록"
#: conf/site_settings.py:39
msgid "Copyright message to show in the footer"
-msgstr ""
+msgstr "바닥글에 표시할 카피라이트 메시지"
#: conf/site_settings.py:49
msgid "Site description for the search engines"
-msgstr ""
+msgstr "검색 엔진을 위한 사이트 설명"
#: conf/site_settings.py:58
msgid "Short name for your Q&A forum"
-msgstr ""
+msgstr "Q&A 포럼의 짧은 이름"
#: conf/site_settings.py:67
msgid "Base URL for your Q&A forum, must start with http or https"
-msgstr ""
+msgstr "Q&A 포럼의, http 또는 https로 시작하는 기본 URL"
#: conf/site_settings.py:78
msgid "Check to enable greeting for anonymous user"
-msgstr ""
+msgstr "익명 사용자를 위한 인사말 활성화"
#: conf/site_settings.py:89
msgid "Text shown in the greeting message shown to the anonymous user"
-msgstr ""
+msgstr "익명의 사용자에게 보일 인사말"
#: conf/site_settings.py:93
msgid "Use HTML to format the message "
-msgstr ""
+msgstr "메세지 포맷을 HTML 문법을 이용하여 표시"
#: conf/site_settings.py:102
msgid "Feedback site URL"
-msgstr ""
+msgstr "피드백 사이트 URL"
#: conf/site_settings.py:104
msgid "If left empty, a simple internal feedback form will be used instead"
-msgstr ""
+msgstr "비어있는 경우, 간단한 내부 피드백 양식이 대신 사용됩니다"
#: conf/skin_counter_settings.py:11
msgid "Skin: view, vote and answer counters"
-msgstr ""
+msgstr "스킨: 뷰, 투표와 답변 카운터"
#: conf/skin_counter_settings.py:19
msgid "Vote counter value to give \"full color\""
-msgstr ""
+msgstr "“풀 칼라”를 제공하기 위해 카운터 값에 투표하세요"
#: conf/skin_counter_settings.py:29
msgid "Background color for votes = 0"
-msgstr ""
+msgstr "votes = 0에 대한 배경색"
#: conf/skin_counter_settings.py:30 conf/skin_counter_settings.py:41
#: conf/skin_counter_settings.py:52 conf/skin_counter_settings.py:62
@@ -1630,197 +1618,197 @@ msgstr ""
#: conf/skin_counter_settings.py:228 conf/skin_counter_settings.py:239
#: conf/skin_counter_settings.py:252 conf/skin_counter_settings.py:262
msgid "HTML color name or hex value"
-msgstr ""
+msgstr "HTML 색상명 또는 헥사값"
#: conf/skin_counter_settings.py:40
msgid "Foreground color for votes = 0"
-msgstr ""
+msgstr "votes=0에 대한 전경색"
#: conf/skin_counter_settings.py:51
msgid "Background color for votes"
-msgstr ""
+msgstr "투표에 대한 배경색"
#: conf/skin_counter_settings.py:61
msgid "Foreground color for votes"
-msgstr ""
+msgstr "투표에 대한 전경색"
#: conf/skin_counter_settings.py:71
msgid "Background color for votes = MAX"
-msgstr ""
+msgstr "votes = MAX에 대한 배경색"
#: conf/skin_counter_settings.py:84
msgid "Foreground color for votes = MAX"
-msgstr ""
+msgstr "vote = MAX에 대한 전경색"
#: conf/skin_counter_settings.py:95
msgid "View counter value to give \"full color\""
-msgstr ""
+msgstr "\"풀 컬러\"를 주기 위한 카운터 값 보기"
#: conf/skin_counter_settings.py:105
msgid "Background color for views = 0"
-msgstr ""
+msgstr "views = 0에 대한 배경색"
#: conf/skin_counter_settings.py:116
msgid "Foreground color for views = 0"
-msgstr ""
+msgstr "views = 0에 대한 전경색"
#: conf/skin_counter_settings.py:127
msgid "Background color for views"
-msgstr ""
+msgstr "views의 배경색"
#: conf/skin_counter_settings.py:137
msgid "Foreground color for views"
-msgstr ""
+msgstr "views의 전경색"
#: conf/skin_counter_settings.py:147
msgid "Background color for views = MAX"
-msgstr ""
+msgstr "views = MAX에 대한 배경색"
#: conf/skin_counter_settings.py:162
msgid "Foreground color for views = MAX"
-msgstr ""
+msgstr "views = MAX에 대한 전경색"
#: conf/skin_counter_settings.py:173
msgid "Answer counter value to give \"full color\""
-msgstr ""
+msgstr "\"풀 컬러\"를 주기 위한 답변 횟수"
#: conf/skin_counter_settings.py:185
msgid "Background color for answers = 0"
-msgstr ""
+msgstr "answers = 0에 대한 배경색"
#: conf/skin_counter_settings.py:195
msgid "Foreground color for answers = 0"
-msgstr ""
+msgstr "answers = 0에 대한 전경색"
#: conf/skin_counter_settings.py:205
msgid "Background color for answers"
-msgstr ""
+msgstr "답변에 대한 배경색"
#: conf/skin_counter_settings.py:215
msgid "Foreground color for answers"
-msgstr ""
+msgstr "답변에 대한 전경색"
#: conf/skin_counter_settings.py:227
msgid "Background color for answers = MAX"
-msgstr ""
+msgstr "answers = MAX에 대한 배경색"
#: conf/skin_counter_settings.py:238
msgid "Foreground color for answers = MAX"
-msgstr ""
+msgstr "answers = MAX에 대한 전경색"
#: conf/skin_counter_settings.py:251
msgid "Background color for accepted"
-msgstr ""
+msgstr "채택된 답변의 배경색"
#: conf/skin_counter_settings.py:261
msgid "Foreground color for accepted answer"
-msgstr ""
+msgstr "채택된 답변의 전경색"
#: conf/skin_general_settings.py:15
msgid "Logos and HTML <head> parts"
-msgstr ""
+msgstr "로고 및 HTML <head> 부분"
#: conf/skin_general_settings.py:23
msgid "Q&A site logo"
-msgstr ""
+msgstr "질문답변 사이트 로고"
#: conf/skin_general_settings.py:25
msgid "To change the logo, select new file, then submit this whole form."
-msgstr ""
+msgstr "로고를 변경하려면, 새 파일을 선택한 다음, 전체 폼을 제출하세요."
#: conf/skin_general_settings.py:37
msgid "Show logo"
-msgstr ""
+msgstr "로고 보기"
#: conf/skin_general_settings.py:39
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 "기본 위치에서 나타나는 포럼 머리글의 로고를 원한다면 체크를 해주시고, 원치 않는다면 체크를 해제해주세요."
#: conf/skin_general_settings.py:51
msgid "Site favicon"
-msgstr ""
+msgstr "사이트 즐겨찾기 아이콘"
#: conf/skin_general_settings.py:53
#, python-format
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 "
+"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 "브라우저 사용자 인터페이스에서 사이트를 구분하는 데에 쓰이는 작은 16x16 또는 32x32 픽셀 아이콘 이미지. 파비콘에 대한 정보는 <a href=\"%(favicon_info_url)s\">이 페이지</a>를 참고하세요."
#: conf/skin_general_settings.py:69
msgid "Password login button"
-msgstr ""
+msgstr "비밀번호 로그인 버튼"
#: conf/skin_general_settings.py:71
msgid ""
-"An 88x38 pixel image that is used on the login screen for the password login "
-"button."
-msgstr ""
+"An 88x38 pixel image that is used on the login screen for the password login"
+" button."
+msgstr "로그인 화면에서 비밀번호 로그인 버튼에 사용되는 88x38 픽셀 이미지."
#: conf/skin_general_settings.py:84
msgid "Show all UI functions to all users"
-msgstr ""
+msgstr "사용자를 위한 UI 기능 모두 보기"
#: conf/skin_general_settings.py:86
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 ""
+"reputation. However to use those functions, moderation rules, reputation and"
+" other limits will still apply."
+msgstr "체크한 경우, 사용자의 평판에 관계 없이 모든 포럼 기능이 사용자에게 보여집니다. 이 기능을 사용하더라도, 조정 규칙과 평판 및 기타 제한은 계속 적용됩니다."
#: conf/skin_general_settings.py:101
msgid "Select skin"
-msgstr ""
+msgstr "스킨 선택"
#: conf/skin_general_settings.py:112
msgid "Customize HTML <HEAD>"
-msgstr ""
+msgstr "HTML <HEAD> 사용자 지정"
#: conf/skin_general_settings.py:121
msgid "Custom portion of the HTML <HEAD>"
-msgstr ""
+msgstr "HTML <HEAD> 사용자 지정 부분"
#: conf/skin_general_settings.py:123
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 "
-"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."
-msgstr ""
+"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."
+msgstr "<strong>이 옵션을 사용하기 위하여</strong>, 위의 \"Customize HTML &lt;HEAD&gt;\"을 체크하세요. 이 상자의 내용은 HTML 출력의 &lt;HEAD&gt; 부분에 삽입되며, 그곳에는 &lt;script&gt;, &lt;link&gt;, &lt;meta&gt; 등이 추가될 수 있습니다. 외부의 자바스크립트를 &lt;HEAD&gt;에 추가하는 것은 페이지의 로딩을 느리게 할 수 있기 때문에 추천하지 않습니다. 대신에, 바닥글에 링크하는 것이 보다 효과적입니다. <strong>주의:</strong> 이 설정을 사용한다면, W3C HTML 유효성 검사 서비스를 사용하여 사이트를 테스트해보시기 바랍니다."
#: conf/skin_general_settings.py:145
msgid "Custom header additions"
-msgstr ""
+msgstr "맞춤 머리글 추가"
#: conf/skin_general_settings.py:147
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 "
+"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."
-msgstr ""
+msgstr "헤더는 컨텐트의 가장 위쪽에 있는 사용자 정보와 사이트 링크를 포함하는 막대이며, 모든 페이지에 공통으로 나타납니다. 이 영역은 HTML 형식으로 헤더를 입력하기 위해 사용하세요. 사이트 헤더를 커스터마이즈할 때 (푸터 및 HTML &lt;HEAD&gt;에도), HTML 유효성 검증 서비스를 사용하여 입력이 정확하며 모든 브라우저에서 작동하는지 확인하세요."
#: conf/skin_general_settings.py:162
msgid "Site footer mode"
-msgstr ""
+msgstr "사이트 바닥글 모드"
#: conf/skin_general_settings.py:164
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 "바닥글 컨텐츠의 하단으로서, 모든 페이지에 공통으로 적용됩니다. 기본 푸터를 사용할 수도 있고, 수정 또는 비활성화할 수도 있습니다."
#: conf/skin_general_settings.py:181
msgid "Custom footer (HTML format)"
-msgstr ""
+msgstr "사용자 지정 바닥글(HTML 형식)"
#: conf/skin_general_settings.py:183
msgid ""
@@ -1829,828 +1817,801 @@ 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>이 기능을 활성화하려면</strong>, 위의 \"사이트 바닥글 모드\"의 '커스터마이즈' 옵션을 선택하세요. 이 영역에는 HTML 형식의 바닥글 내용을 입력합니다. 사이트 바닥글을 커스터마이징할 때 (머리글과 HTML &lt;HEAD&gt;와 마찬가지로), HTML 유효성 검증 서비스를 사용하여 입력이 올바르고 모든 브라우저에서 잘 동작하는지 확인하시기 바랍니다."
#: conf/skin_general_settings.py:198
msgid "Apply custom style sheet (CSS)"
-msgstr ""
+msgstr "스타일 시트(CSS) 허용"
#: conf/skin_general_settings.py:200
msgid ""
"Check if you want to change appearance of your form by adding custom style "
"sheet rules (please see the next item)"
-msgstr ""
+msgstr "맞춤 스타일 시트 규칙을 추가함으로써 양식의 외양을 바꾸려면 체크합니다(다음 항목 참조)"
#: conf/skin_general_settings.py:212
msgid "Custom style sheet (CSS)"
-msgstr ""
+msgstr "스타일 시트(CSS)"
#: conf/skin_general_settings.py:214
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 "
-"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 ""
+"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 "<strong>이 기능을 사용하기 위해서는</strong>, 위의 \"맞춤 스타일 시트 적용\"을 체크합니다. 이 창에서 추가된 CSS 규칙은 디폴트 스타일 시트 규칙 이후에 적용됩니다. 맞춤 스타일 시트는 url \"&lt;forum url&gt;/custom.css\"에서 동적으로 서브되며, \"&lt;forum url&gt; 부분이 urls.py의 url 구성에 의존합니다(기본값은 비어 있는 문자열)."
#: conf/skin_general_settings.py:230
msgid "Add custom javascript"
-msgstr ""
+msgstr "사용자 지정 자바스크립트 추가"
#: conf/skin_general_settings.py:233
msgid "Check to enable javascript that you can enter in the next field"
-msgstr ""
+msgstr "다음 필드에서 사용가능한 자바스크립트를 선택하세요"
#: conf/skin_general_settings.py:243
msgid "Custom javascript"
-msgstr ""
+msgstr "사용자 지정 자바스크립트"
#: conf/skin_general_settings.py:245
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 "
-"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)."
-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)."
+msgstr "사이트에서 실행하고자 하는 평범한 자바스크립트를 타이핑하거나 붙여넣습니다. 그 스크립트에 대한 링크가 HTML 출력의 하단에 삽입되며 url \"&lt;forum url&gt;/custom.js\"에서 서브됩니다. 여러분의 자바스크립트가 사이트의 기능을 망가뜨릴 수 있으며 이는 브라우저에 따라 차이가 있음에 유념하시기 바랍니다(<strong>맞춤 코드를 활성화하려면</strong>, 위의 \"맞춤 자바스크립트 추가\" 옵션을 체크합니다)."
#: conf/skin_general_settings.py:263
msgid "Skin media revision number"
-msgstr ""
+msgstr "스킨 미디어 변경 번호"
#: conf/skin_general_settings.py:265
msgid "Will be set automatically but you can modify it if necessary."
-msgstr ""
+msgstr "자동으로 설정되지만 필요한 경우 수정할 수 있습니다"
#: conf/skin_general_settings.py:276
msgid "Hash to update the media revision number automatically."
-msgstr ""
+msgstr "미디어 리비전 번호를 자동으로 업데이트하기 위하여 해시합니다."
#: conf/skin_general_settings.py:280
msgid "Will be set automatically, it is not necesary to modify manually."
-msgstr ""
+msgstr "자동으로 설정되며, 수작업으로 변경할 필요가 없습니다."
#: conf/social_sharing.py:11
msgid "Sharing content on social networks"
-msgstr ""
+msgstr "소셜 네트워크에 컨텐츠 공유하기"
#: conf/social_sharing.py:20
msgid "Check to enable sharing of questions on Twitter"
-msgstr ""
+msgstr "트위터에 질문 공유하기 선택"
#: conf/social_sharing.py:29
msgid "Check to enable sharing of questions on Facebook"
-msgstr ""
+msgstr "페이스북에 질문 공유하기 선택"
#: conf/social_sharing.py:38
msgid "Check to enable sharing of questions on LinkedIn"
-msgstr ""
+msgstr "Linkedln에 질문 공유하기 선택"
#: conf/social_sharing.py:47
msgid "Check to enable sharing of questions on Identi.ca"
-msgstr ""
+msgstr "Identi.ca에 질문 공유하기 선택"
#: conf/social_sharing.py:56
msgid "Check to enable sharing of questions on Google+"
-msgstr ""
+msgstr "Google+에 질문 공유하기 선택"
#: conf/spam_and_moderation.py:10
msgid "Akismet spam protection"
-msgstr ""
+msgstr "Akismet 스팸 보호"
#: conf/spam_and_moderation.py:18
msgid "Enable Akismet spam detection(keys below are required)"
-msgstr ""
+msgstr "Akismet 스팸 방지 사용(키가 필요함)"
#: 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 "<a href=\"%(url)s\">Akismet 사이트</a> 를 방문하여 Akismet 키를 얻어오기"
#: conf/spam_and_moderation.py:31
msgid "Akismet key for spam detection"
-msgstr ""
+msgstr "스팸 탐지를 위한 Akismet 키"
#: conf/super_groups.py:5
msgid "Reputation, Badges, Votes & Flags"
-msgstr ""
+msgstr "평판, 배지, 투표 및 신고"
#: conf/super_groups.py:6
msgid "Static Content, URLS & UI"
-msgstr ""
+msgstr "정적 컨텐츠, URL 및 UI"
#: conf/super_groups.py:7
msgid "Data rules & Formatting"
-msgstr ""
+msgstr "데이터 규칙 및 포매팅"
#: conf/super_groups.py:8
msgid "External Services"
-msgstr ""
+msgstr "외부 서비스"
#: conf/super_groups.py:9
msgid "Login, Users & Communication"
-msgstr ""
+msgstr "로그인, 사용자 및 커뮤니케이션"
#: conf/user_settings.py:14
-#, fuzzy
msgid "User settings"
-msgstr "User login"
+msgstr "사용자 설정"
#: conf/user_settings.py:23
msgid "Allow editing user screen name"
-msgstr ""
+msgstr "사용자 닉네임 수정 허용"
#: conf/user_settings.py:32
-#, fuzzy
msgid "Allow users change own email addresses"
-msgstr "Your email <i>(never shared)</i>"
+msgstr "사용자가 자신의 이메일 주소를 변경하는 것을 허용"
#: conf/user_settings.py:41
msgid "Allow account recovery by email"
-msgstr ""
+msgstr "이메일을 이용한 계정 복구 허용"
#: conf/user_settings.py:50
msgid "Allow adding and removing login methods"
-msgstr ""
+msgstr "로그인 방법 추가, 제거 허용"
#: conf/user_settings.py:60
msgid "Minimum allowed length for screen name"
-msgstr ""
+msgstr "닉네임을 위한 허용된 최소 길이"
#: conf/user_settings.py:68
msgid "Default avatar for users"
-msgstr ""
+msgstr "사용자의 기본 아바타"
#: conf/user_settings.py:70
msgid ""
"To change the avatar image, select new file, then submit this whole form."
-msgstr ""
+msgstr "아바타 이미지를 변경하기 위하여, 새 파일을 선택한 다음, 이 전체 양식을 제출해주세요."
#: conf/user_settings.py:83
msgid "Use automatic avatars from gravatar.com"
-msgstr ""
+msgstr "gravatar.com으로부터 자동 아바타 사용"
#: conf/user_settings.py:85
msgid ""
"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>."
-msgstr ""
+"information, please visit <a href=\"http://askbot.org/doc/optional-"
+"modules.html#uploaded-avatars\">this page</a>."
+msgstr "아바타를 위해 gravatar.com을 사용하시려면 이 옵션을 체크하세요. 완전히 효력을 발휘하는 데에 10분이 소요될 수 있음에 유의하시기 바랍니다. 아바타 업로드도 활성화할 수 있습니다. 자세한 내용은 알고 싶으면 <a href=\"http://askbot.org/doc/optional-modules.html#uploaded-avatars\">이 페이지</a>를 방문하세요."
#: conf/user_settings.py:97
msgid "Default Gravatar icon type"
-msgstr ""
+msgstr "기본 Gravatar 아이콘 종류"
#: conf/user_settings.py:99
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 "이 옵션은 그라바타 이미지와 연계하지 않고도 이메일 주소로부터 디폴트 아바타 형식을 설정하도록 해줍니다. 자세한 내용은 <a href=\"http://en.gravatar.com/site/implement/images/\">이 페이지</a>를 참조하세요."
#: conf/user_settings.py:109
msgid "Name for the Anonymous user"
-msgstr ""
+msgstr "익명 사용자 이름"
#: conf/vote_rules.py:14
msgid "Vote and flag limits"
-msgstr ""
+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"
-msgstr ""
+msgstr "남은 일일 투표에 대한 경고 한계치"
#: conf/vote_rules.py:51
msgid "Number of days to allow canceling votes"
-msgstr ""
+msgstr "투표 취소를 허용하는 일수"
#: conf/vote_rules.py:60
msgid "Number of days required before answering own question"
-msgstr ""
+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 ""
+msgstr "질문 게시자가 답변을 채택하는 경우를 제외하고, 답변을 채택하기 위한 최소 일자"
#: conf/widgets.py:13
msgid "Embeddable widgets"
-msgstr ""
+msgstr "내장가능한 위젯들"
#: conf/widgets.py:25
-#, fuzzy
msgid "Number of questions to show"
-msgstr "answered question"
+msgstr "보여줄 질문의 개수"
#: conf/widgets.py:28
msgid ""
"To embed the widget, add the following code to your site (and fill in "
-"correct base url, preferred tags, width and height):<iframe src="
-"\"{{base_url}}/widgets/questions?tags={{comma-separated-tags}}\" width=\"100%"
-"\" height=\"300\"scrolling=\"no\"><p>Your browser does not support iframes.</"
-"p></iframe>"
-msgstr ""
+"correct base url, preferred tags, width and height):<iframe "
+"src=\"{{base_url}}/widgets/questions?tags={{comma-separated-tags}}\" "
+"width=\"100%\" height=\"300\"scrolling=\"no\"><p>Your browser does not "
+"support iframes.</p></iframe>"
+msgstr "위젯을 내장하기 위해서 다음의 코드를 사이트에 추가하십시오 (그리고 올바른 base url, 선호 태그, width 와 height 로 채우시기 바랍니다):<iframe src=\"{{base_url}}/widgets/questions?tags={{쉼표로-구분된-태그들}}\" width=\"100%\" height=\"300\"scrolling=\"no\"><p>브라우저가 iframe을 지워하지 않습니다.</p></iframe>"
#: conf/widgets.py:73
-#, fuzzy
msgid "CSS for the questions widget"
-msgstr "Post Your Answer"
+msgstr "질문 위젯을 위한 CSS"
#: conf/widgets.py:81
-#, fuzzy
msgid "Header for the questions widget"
-msgstr "Post Your Answer"
+msgstr "질문 위젯을 위한 머리글"
#: conf/widgets.py:90
-#, fuzzy
msgid "Footer for the questions widget"
-msgstr "Post Your Answer"
+msgstr "질문 위젯을 위한 바닥글"
#: const/__init__.py:10
msgid "duplicate question"
-msgstr ""
+msgstr "중복된 질문"
#: const/__init__.py:11
msgid "question is off-topic or not relevant"
-msgstr ""
+msgstr "주제에서 벗어나거나 관련 없는 질문"
#: const/__init__.py:12
msgid "too subjective and argumentative"
-msgstr ""
+msgstr "너무 주관적이며 논쟁적임"
#: const/__init__.py:13
msgid "not a real question"
-msgstr ""
+msgstr "진정한 질문이 아님"
#: const/__init__.py:14
msgid "the question is answered, right answer was accepted"
-msgstr ""
+msgstr "질문에 대한 답변이 달렸으며, 올바른 답변이 채택되었습니다"
#: const/__init__.py:15
msgid "question is not relevant or outdated"
-msgstr ""
+msgstr "질문이 부적합하거나 더 이상 쓸모가 없음"
#: const/__init__.py:16
msgid "question contains offensive or malicious remarks"
-msgstr ""
+msgstr "질문이 공격적이거나 유해한 표현을 담고 있음"
#: const/__init__.py:17
msgid "spam or advertising"
-msgstr ""
+msgstr "스팸이거나 광고성"
#: const/__init__.py:18
msgid "too localized"
-msgstr ""
+msgstr "너무 지역적임"
#: const/__init__.py:43
#: skins/default/templates/question/answer_tab_bar.html:18
msgid "newest"
-msgstr ""
+msgstr "최신의"
#: const/__init__.py:44 skins/default/templates/users.html:27
#: skins/default/templates/question/answer_tab_bar.html:15
msgid "oldest"
-msgstr ""
+msgstr "가입일"
#: const/__init__.py:45
msgid "active"
-msgstr ""
+msgstr "활발한"
#: const/__init__.py:46
msgid "inactive"
-msgstr ""
+msgstr "활발하지 않은"
#: const/__init__.py:47
msgid "hottest"
-msgstr ""
+msgstr "뜨거운 "
#: const/__init__.py:48
msgid "coldest"
-msgstr ""
+msgstr "냉랭한"
#: const/__init__.py:49
#: skins/default/templates/question/answer_tab_bar.html:21
msgid "most voted"
-msgstr ""
+msgstr "최다 투표"
#: const/__init__.py:50
msgid "least voted"
-msgstr ""
+msgstr "적게 투표된"
#: const/__init__.py:51
msgid "relevance"
-msgstr ""
+msgstr "관련성"
#: const/__init__.py:63
#: skins/default/templates/user_profile/user_inbox.html:50
#: skins/default/templates/user_profile/user_inbox.html:62
msgid "all"
-msgstr ""
+msgstr "모든 것"
#: const/__init__.py:64
msgid "unanswered"
-msgstr ""
+msgstr "답변되지 않은"
#: const/__init__.py:65
msgid "favorite"
-msgstr ""
+msgstr "즐겨찾기"
#: const/__init__.py:70
-#, fuzzy
msgid "list"
-msgstr "Tags"
+msgstr "목록"
#: const/__init__.py:71
msgid "cloud"
-msgstr ""
+msgstr "클라우드"
#: const/__init__.py:79
msgid "Question has no answers"
-msgstr ""
+msgstr "답변이 없는 질문"
#: const/__init__.py:80
msgid "Question has no accepted answers"
-msgstr ""
+msgstr "답변을 채택하지 않은 질문"
#: const/__init__.py:125
msgid "asked a question"
-msgstr ""
+msgstr "질문하였습니다"
#: const/__init__.py:126
msgid "answered a question"
-msgstr ""
+msgstr "질문에 답변하였습니다"
#: const/__init__.py:127 const/__init__.py:203
msgid "commented question"
-msgstr ""
+msgstr "질문에 댓글을 달았습니다"
#: const/__init__.py:128 const/__init__.py:204
msgid "commented answer"
-msgstr ""
+msgstr "코멘트달린 답변"
#: const/__init__.py:129
msgid "edited question"
-msgstr ""
+msgstr "질문을 편집했습니다"
#: const/__init__.py:130
msgid "edited answer"
-msgstr ""
+msgstr "답변을 편집했습니다"
#: const/__init__.py:131
-#, fuzzy
msgid "received badge"
-msgstr "received badge"
+msgstr "받은 배지"
#: const/__init__.py:132
msgid "marked best answer"
-msgstr ""
+msgstr "으뜸 답변으로 표시됨"
#: const/__init__.py:133
msgid "upvoted"
-msgstr ""
+msgstr "upvoted"
#: const/__init__.py:134
msgid "downvoted"
-msgstr ""
+msgstr "downvoted"
#: const/__init__.py:135
msgid "canceled vote"
-msgstr ""
+msgstr "취소된 투표"
#: const/__init__.py:136
msgid "deleted question"
-msgstr ""
+msgstr "질문을 삭제했습니다"
#: const/__init__.py:137
msgid "deleted answer"
-msgstr ""
+msgstr "삭제된 답변"
#: const/__init__.py:138
msgid "marked offensive"
-msgstr ""
+msgstr "공격적이라고 표시됨"
#: const/__init__.py:139
msgid "updated tags"
-msgstr ""
+msgstr "업데이트된 태그"
#: const/__init__.py:140
msgid "selected favorite"
-msgstr ""
+msgstr "선택된 즐겨찾기"
#: const/__init__.py:141
msgid "completed user profile"
-msgstr ""
+msgstr "완전한 사용자 프로필"
#: const/__init__.py:142
msgid "email update sent to user"
-msgstr ""
+msgstr "이메일 업데이트를 사용자에게 발송하였습니다"
#: const/__init__.py:145
msgid "reminder about unanswered questions sent"
-msgstr ""
+msgstr "답변이 없는 질문에 대한 알림을 발송하였습니다"
#: const/__init__.py:149
msgid "reminder about accepting the best answer sent"
-msgstr ""
+msgstr "으뜸 답변을 채택하도록 알림을 발송했습니다"
#: const/__init__.py:151
msgid "mentioned in the post"
-msgstr ""
+msgstr "포스트내에서 언급되었음"
#: const/__init__.py:202
-#, fuzzy
msgid "answered question"
-msgstr "Post Your Answer"
+msgstr "답변된 질문"
#: const/__init__.py:205
-#, fuzzy
msgid "accepted answer"
-msgstr "oldest"
+msgstr "채택된 답변"
#: const/__init__.py:209
msgid "[closed]"
-msgstr ""
+msgstr "[종료됨]"
#: const/__init__.py:210
msgid "[deleted]"
-msgstr ""
+msgstr "[삭제되었음]"
#: const/__init__.py:211 views/readers.py:566
msgid "initial version"
-msgstr ""
+msgstr "이니셜 버젼"
#: const/__init__.py:212
msgid "retagged"
-msgstr ""
+msgstr "태그 수정됨"
#: const/__init__.py:220
msgid "off"
-msgstr ""
+msgstr "off"
#: const/__init__.py:221
msgid "exclude ignored"
-msgstr ""
+msgstr "무시된 것을 제외"
#: const/__init__.py:222
msgid "only selected"
-msgstr ""
+msgstr "선택된 목록"
#: const/__init__.py:226
msgid "instantly"
-msgstr ""
+msgstr "즉시"
#: const/__init__.py:227
msgid "daily"
-msgstr ""
+msgstr "매일"
#: const/__init__.py:228
msgid "weekly"
-msgstr ""
+msgstr "매주"
#: const/__init__.py:229
msgid "no email"
-msgstr ""
+msgstr "받지 않음"
#: const/__init__.py:236
msgid "identicon"
-msgstr ""
+msgstr "사용자 아이콘"
#: const/__init__.py:237
msgid "mystery-man"
-msgstr ""
+msgstr "mystery-man"
#: const/__init__.py:238
msgid "monsterid"
-msgstr ""
+msgstr "monsterid"
#: const/__init__.py:239
-#, fuzzy
msgid "wavatar"
-msgstr "How to change my picture (gravatar) and what is gravatar?"
+msgstr "wavatar"
#: const/__init__.py:240
msgid "retro"
-msgstr ""
+msgstr "retro"
#: const/__init__.py:287 skins/default/templates/badges.html:38
msgid "gold"
-msgstr ""
+msgstr "금"
#: const/__init__.py:288 skins/default/templates/badges.html:48
msgid "silver"
-msgstr ""
+msgstr "은"
#: const/__init__.py:289 skins/default/templates/badges.html:55
msgid "bronze"
-msgstr ""
+msgstr "동"
#: const/__init__.py:301
msgid "None"
-msgstr ""
+msgstr "없음"
#: const/__init__.py:302
msgid "Gravatar"
-msgstr ""
+msgstr "Gravatar"
#: const/__init__.py:303
msgid "Uploaded Avatar"
-msgstr ""
+msgstr "업로드 된 아바타"
#: const/message_keys.py:21
-#, fuzzy
msgid "most relevant questions"
-msgstr "ask a question interesting to this community"
+msgstr "가장 많이 관련된 질문"
#: const/message_keys.py:22
-#, fuzzy
msgid "click to see most relevant questions"
-msgstr "ask a question interesting to this community"
+msgstr "가장 많이 관련된 질문 보기 선택"
#: const/message_keys.py:23
msgid "by relevance"
-msgstr ""
+msgstr "관련된 순"
#: const/message_keys.py:24
-#, fuzzy
msgid "click to see the oldest questions"
-msgstr ""
-"<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."
+msgstr "오래된 질문 보기 선택"
#: const/message_keys.py:25
msgid "by date"
-msgstr ""
+msgstr "날짜 순"
#: const/message_keys.py:26
msgid "click to see the newest questions"
-msgstr ""
+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"
-msgstr ""
+msgstr "최근 답변 순 질문 보기 선택"
#: const/message_keys.py:31
-#, fuzzy
msgid "by answers"
-msgstr "oldest"
+msgstr "답변 순"
#: const/message_keys.py:32
msgid "click to see the most answered questions"
-msgstr ""
+msgstr "많은 답변된 질문 보기 선택"
#: const/message_keys.py:33
msgid "click to see least voted questions"
-msgstr ""
+msgstr "적은 투표 질문 보기 선택"
#: const/message_keys.py:34
-#, fuzzy
msgid "by votes"
-msgstr "votes"
+msgstr "투표 순"
#: const/message_keys.py:35
-#, fuzzy
msgid "click to see most voted questions"
-msgstr ""
-"<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."
+msgstr "많이 투표된 질문 보기 선택"
#: const/message_keys.py:40
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:45 models/__init__.py:788
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:166
msgid ""
"Welcome! Please set email address (important!) in your profile and adjust "
"screen name, if necessary."
-msgstr ""
+msgstr "환영합니다! 프로필이나 닉네임에서 필요시 이메일 주소를 설정해주세요(중요!)"
#: deps/django_authopenid/forms.py:110 deps/django_authopenid/views.py:142
msgid "i-names are not supported"
-msgstr ""
+msgstr "i-names를 지원하지 않습니다."
#: deps/django_authopenid/forms.py:233
#, python-format
msgid "Please enter your %(username_token)s"
-msgstr ""
+msgstr "%(username_token)s을 입력해주세요"
#: deps/django_authopenid/forms.py:259
msgid "Please, enter your user name"
-msgstr ""
+msgstr "사용자명을 입력해주세요"
#: deps/django_authopenid/forms.py:263
msgid "Please, enter your password"
-msgstr ""
+msgstr "비밀번호를 입력해주세요"
#: deps/django_authopenid/forms.py:270 deps/django_authopenid/forms.py:274
msgid "Please, enter your new password"
-msgstr ""
+msgstr "새로운 비밀번호를 입력해주세요"
#: deps/django_authopenid/forms.py:285
msgid "Passwords did not match"
-msgstr ""
+msgstr "비밀번호가 일치하지 않습니다."
#: deps/django_authopenid/forms.py:297
#, python-format
msgid "Please choose password > %(len)s characters"
-msgstr ""
+msgstr "비밀번호는 %(len)s 자보다 길어야 합니다"
#: deps/django_authopenid/forms.py:335
msgid "Current password"
-msgstr ""
+msgstr "현재 비밀번호"
#: deps/django_authopenid/forms.py:346
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"
-msgstr ""
+msgstr "죄송합니다. 등록된 이메일 주소가 아닙니다."
#: deps/django_authopenid/forms.py:435
msgid "Your user name (<i>required</i>)"
-msgstr ""
+msgstr "사용자명 (<i>필수</i>)"
#: deps/django_authopenid/forms.py:450
msgid "sorry, there is no such user name"
-msgstr ""
+msgstr "미안합니다. 그런 사용자명은 없습니다"
#: deps/django_authopenid/urls.py:9 deps/django_authopenid/urls.py:12
#: deps/django_authopenid/urls.py:15 setup_templates/settings.py:210
msgid "signin/"
-msgstr ""
+msgstr "signin/"
#: deps/django_authopenid/urls.py:10
msgid "signout/"
-msgstr ""
+msgstr "signout/"
#: deps/django_authopenid/urls.py:12
msgid "complete/"
-msgstr ""
+msgstr "complete/"
#: deps/django_authopenid/urls.py:15
msgid "complete-oauth/"
-msgstr ""
+msgstr "complete-oauth/"
#: deps/django_authopenid/urls.py:19
msgid "register/"
-msgstr ""
+msgstr "register/"
#: deps/django_authopenid/urls.py:21
msgid "signup/"
-msgstr ""
+msgstr "signup/"
#: deps/django_authopenid/urls.py:25
msgid "logout/"
-msgstr ""
+msgstr "logout/"
#: deps/django_authopenid/urls.py:30
msgid "recover/"
-msgstr ""
+msgstr "recover/"
#: deps/django_authopenid/util.py:378
#, python-format
msgid "%(site)s user name and password"
-msgstr ""
+msgstr "%(site)s 사용자명과 비밀번호"
#: deps/django_authopenid/util.py:384
#: skins/common/templates/authopenid/signin.html:115
msgid "Create a password-protected account"
-msgstr ""
+msgstr "비밀번호로 보호되는 계정을 생성"
#: deps/django_authopenid/util.py:385
msgid "Change your password"
-msgstr ""
+msgstr "비밀번호 변경"
#: deps/django_authopenid/util.py:473
msgid "Sign in with Yahoo"
-msgstr ""
+msgstr "Yahoo 로그인"
#: deps/django_authopenid/util.py:480
msgid "AOL screen name"
-msgstr ""
+msgstr "AOL 닉네임"
#: deps/django_authopenid/util.py:488
msgid "OpenID url"
-msgstr ""
+msgstr "OpenID 주소"
#: deps/django_authopenid/util.py:517
msgid "Flickr user name"
-msgstr ""
+msgstr "Flickr 사용자명"
#: deps/django_authopenid/util.py:525
msgid "Technorati user name"
-msgstr ""
+msgstr "테크노라티 사용자명"
#: deps/django_authopenid/util.py:533
msgid "WordPress blog name"
-msgstr ""
+msgstr "워드프레스 블로그 이름"
#: deps/django_authopenid/util.py:541
msgid "Blogger blog name"
-msgstr ""
+msgstr "Blogger 블로그 이름"
#: deps/django_authopenid/util.py:549
msgid "LiveJournal blog name"
-msgstr ""
+msgstr "LiveJournal 블로그 이름"
#: deps/django_authopenid/util.py:557
msgid "ClaimID user name"
-msgstr ""
+msgstr "ClaimID 사용자명"
#: deps/django_authopenid/util.py:565
msgid "Vidoop user name"
-msgstr ""
+msgstr "Vidoop 사용자명"
#: deps/django_authopenid/util.py:573
msgid "Verisign user name"
-msgstr ""
+msgstr "Verisign 사용자명"
#: deps/django_authopenid/util.py:608
#, python-format
msgid "Change your %(provider)s password"
-msgstr ""
+msgstr "%(provider)s 비밀번호 변경"
#: deps/django_authopenid/util.py:612
#, python-format
msgid "Click to see if your %(provider)s signin still works for %(site_name)s"
-msgstr ""
+msgstr "%(site_name)s에서 %(provider)s 로그인이 작동하는지 보려면 클릭하세요"
#: deps/django_authopenid/util.py:621
#, python-format
msgid "Create password for %(provider)s"
-msgstr ""
+msgstr "%(provider)s 비밀번호 생성"
#: deps/django_authopenid/util.py:625
#, python-format
msgid "Connect your %(provider)s account to %(site_name)s"
-msgstr ""
+msgstr "%(provider)s의 계정을 %(site_name)s에 연결"
#: deps/django_authopenid/util.py:634
#, python-format
msgid "Signin with %(provider)s user name and password"
-msgstr ""
+msgstr "%(provider)s의 사용자명과 비밀번호로 로그인"
#: deps/django_authopenid/util.py:641
#, python-format
msgid "Sign in with your %(provider)s account"
-msgstr ""
+msgstr "%(provider)s의 계정으로 로그인"
#: deps/django_authopenid/views.py:149
#, python-format
msgid "OpenID %(openid_url)s is invalid"
-msgstr ""
+msgstr "OpenID %(openid_url)s이 유효하지 않습니다"
#: deps/django_authopenid/views.py:261 deps/django_authopenid/views.py:408
#: deps/django_authopenid/views.py:436
@@ -2658,206 +2619,186 @@ msgstr ""
msgid ""
"Unfortunately, there was some problem when connecting to %(provider)s, "
"please try again or use another provider"
-msgstr ""
+msgstr "%(provider)s에 연결하는 데에 문제가 있습니다. 다시 시도하거나 다른 제공자를 사용하세요"
#: deps/django_authopenid/views.py:358
msgid "Your new password saved"
-msgstr ""
+msgstr "새 비밀번호가 저장되었습니다"
#: deps/django_authopenid/views.py:462
msgid "The login password combination was not correct"
-msgstr ""
+msgstr "로그인 비밀번호 조합이 올바르지 않습니다"
#: deps/django_authopenid/views.py:564
msgid "Please click any of the icons below to sign in"
-msgstr ""
+msgstr "아래의 아이콘 중 하나를 선택하여 로그인하세요"
#: deps/django_authopenid/views.py:566
msgid "Account recovery email sent"
-msgstr ""
+msgstr "계정 복구 이메일을 발송하였습니다"
#: deps/django_authopenid/views.py:569
msgid "Please add one or more login methods."
-msgstr ""
+msgstr "한 가지 이상의 로그인 방법을 추가하세요"
#: deps/django_authopenid/views.py:571
msgid "If you wish, please add, remove or re-validate your login methods"
-msgstr ""
+msgstr "로그인 방법을 추가, 제거, 재확인하실 수 있습니다"
#: deps/django_authopenid/views.py:573
msgid "Please wait a second! Your account is recovered, but ..."
-msgstr ""
+msgstr "잠깐만 기다려 주세요! 계정이 복구되었습니다만, ..."
#: deps/django_authopenid/views.py:575
msgid "Sorry, this account recovery key has expired or is invalid"
-msgstr ""
+msgstr "죄송합니다. 이 계정 복구 키는 만료되었거나 유효하지 않습니다"
#: deps/django_authopenid/views.py:648
#, python-format
msgid "Login method %(provider_name)s does not exist"
-msgstr ""
+msgstr "로그인 방법 %(provider_name)s이 존재하지 않습니다"
#: deps/django_authopenid/views.py:654
msgid "Oops, sorry - there was some error - please try again"
-msgstr ""
+msgstr "앗, 죄송하지만 문제가 있습니다. 다시 시도해 주세요"
#: deps/django_authopenid/views.py:745
#, python-format
msgid "Your %(provider)s login works fine"
-msgstr ""
+msgstr "%(provider)s 로그인이 잘 동작합니다"
#: deps/django_authopenid/views.py:1056 deps/django_authopenid/views.py:1062
#, python-format
msgid "your email needs to be validated see %(details_url)s"
-msgstr ""
-"Your email needs to be validated. Please see details <a "
-"id='validate_email_alert' href='%(details_url)s'>here</a>."
+msgstr "이메일에 대한 확인이 필요합니다. 자세한 내용은 <a id='validate_email_alert' href='%(details_url)s'>이곳</a>을 참고하시기 바랍니다."
#: deps/django_authopenid/views.py:1083
#, python-format
msgid "Recover your %(site)s account"
-msgstr ""
+msgstr "%(site)s 계정 복구"
#: deps/django_authopenid/views.py:1155
msgid "Please check your email and visit the enclosed link."
-msgstr ""
+msgstr "이메일을 확인하시고 포함된 링크를 방문해주세요."
#: deps/livesettings/models.py:101 deps/livesettings/models.py:140
msgid "Site"
-msgstr ""
+msgstr "사이트"
#: deps/livesettings/values.py:69
msgid "Main"
-msgstr ""
+msgstr "메인"
#: deps/livesettings/values.py:128
msgid "Base Settings"
-msgstr ""
+msgstr "기본 설정"
#: deps/livesettings/values.py:235
msgid "Default value: \"\""
-msgstr ""
+msgstr "기본값: \"\""
#: deps/livesettings/values.py:242
msgid "Default value: "
-msgstr ""
+msgstr "기본값: "
#: deps/livesettings/values.py:245
#, python-format
msgid "Default value: %s"
-msgstr ""
+msgstr "기본 값: %s"
#: deps/livesettings/values.py:629
#, python-format
msgid "Allowed image file types are %(types)s"
-msgstr ""
+msgstr "이미지 파일 타입을 %(types)s로 허용"
#: deps/livesettings/templates/livesettings/_admin_site_views.html:4
msgid "Sites"
-msgstr ""
+msgstr "사이트"
#: deps/livesettings/templates/livesettings/group_settings.html:11
#: deps/livesettings/templates/livesettings/site_settings.html:23
-#, fuzzy
msgid "Documentation"
-msgstr "karma"
+msgstr "첨부 문서"
#: deps/livesettings/templates/livesettings/group_settings.html:11
#: deps/livesettings/templates/livesettings/site_settings.html:23
#: skins/common/templates/authopenid/signin.html:143
-#, fuzzy
msgid "Change password"
-msgstr "Password"
+msgstr "비밀번호 변경"
#: deps/livesettings/templates/livesettings/group_settings.html:11
#: deps/livesettings/templates/livesettings/site_settings.html:23
msgid "Log out"
-msgstr ""
+msgstr "로그 아웃"
#: deps/livesettings/templates/livesettings/group_settings.html:14
#: deps/livesettings/templates/livesettings/site_settings.html:26
msgid "Home"
-msgstr ""
+msgstr "홈"
#: deps/livesettings/templates/livesettings/group_settings.html:15
-#, fuzzy
msgid "Edit Group Settings"
-msgstr "Post Your Answer"
+msgstr "그룹 설정 편집"
#: deps/livesettings/templates/livesettings/group_settings.html:22
#: deps/livesettings/templates/livesettings/site_settings.html:50
msgid "Please correct the error below."
msgid_plural "Please correct the errors below."
-msgstr[0] ""
+msgstr[0] "다음의 오류를 수정해주세요."
#: deps/livesettings/templates/livesettings/group_settings.html:28
#, python-format
msgid "Settings included in %(name)s."
-msgstr ""
+msgstr "%(name)s에 설정이 포함됨."
#: deps/livesettings/templates/livesettings/group_settings.html:62
#: deps/livesettings/templates/livesettings/site_settings.html:97
msgid "You don't have permission to edit values."
-msgstr ""
+msgstr "값을 편집할 권한이 없습니다."
#: deps/livesettings/templates/livesettings/site_settings.html:27
-#, fuzzy
msgid "Edit Site Settings"
-msgstr "Post Your Answer"
+msgstr "사이트 설정 수정"
#: deps/livesettings/templates/livesettings/site_settings.html:43
msgid "Livesettings are disabled for this site."
-msgstr ""
+msgstr "이 사이트에서는 Livesettings가 비활성화되었습니다."
#: deps/livesettings/templates/livesettings/site_settings.html:44
msgid "All configuration options must be edited in the site settings.py file"
-msgstr ""
+msgstr "모든 구성 옵션은 사이트의 settings.py 파일에서 편집하여야 합니다"
#: deps/livesettings/templates/livesettings/site_settings.html:66
-#, fuzzy, python-format
+#, python-format
msgid "Group settings: %(name)s"
-msgstr "Post Your Answer"
+msgstr "그룹 설정: %(name)s"
#: deps/livesettings/templates/livesettings/site_settings.html:93
msgid "Uncollapse all"
-msgstr ""
+msgstr "전체 확대"
#: importers/stackexchange/management/commands/load_stackexchange.py:141
msgid "Congratulations, you are now an Administrator"
-msgstr ""
+msgstr "축하합니다. 관리자가 되셨습니다."
#: management/commands/send_accept_answer_reminders.py:58
#, python-format
msgid "Accept the best answer for %(question_count)d of your questions"
-msgstr ""
+msgstr "귀하의 질문의 %(question_count)d에 대한 으뜸 답변을 선택하세요"
#: management/commands/send_accept_answer_reminders.py:63
-#, fuzzy
msgid "Please accept the best answer for this question:"
-msgstr ""
-"<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!"
+msgstr "이 질문에 대한 으뜸 답변을 선택하세요:"
#: management/commands/send_accept_answer_reminders.py:65
-#, fuzzy
msgid "Please accept the best answer for these questions:"
-msgstr ""
-"<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!"
+msgstr "이 질문들에 대한 으뜸 답변을 선택하세요:"
#: management/commands/send_email_alerts.py:414
#, python-format
msgid "%(question_count)d updated question about %(topics)s"
msgid_plural "%(question_count)d updated questions about %(topics)s"
-msgstr[0] ""
+msgstr[0] "%(topics)s에 관한 질문 %(question_count)d개가 업데이트됨"
#: management/commands/send_email_alerts.py:425
#, python-format
@@ -2865,107 +2806,102 @@ msgid ""
"<p>Dear %(name)s,</p><p>The following question has been updated "
"%(sitename)s</p>"
msgid_plural ""
-"<p>Dear %(name)s,</p><p>The following %(num)d questions have been updated on "
-"%(sitename)s:</p>"
-msgstr[0] ""
+"<p>Dear %(name)s,</p><p>The following %(num)d questions have been updated on"
+" %(sitename)s:</p>"
+msgstr[0] "<p>%(name)s 님,</p><p>The following %(num)d questions have been updated on %(sitename)s:</p>"
#: management/commands/send_email_alerts.py:449
msgid "new question"
-msgstr ""
+msgstr "새로운 질문"
#: management/commands/send_email_alerts.py:474
#, python-format
msgid ""
-"<p>Please remember that you can always <a hrefl\"%(email_settings_link)s"
-"\">adjust</a> frequency of the email updates or turn them off entirely.<br/"
-">If you believe that this message was sent in an error, please email about "
-"it the forum administrator at %(admin_email)s.</p><p>Sincerely,</p><p>Your "
-"friendly %(sitename)s server.</p>"
-msgstr ""
+"<p>Please remember that you can always <a "
+"hrefl\"%(email_settings_link)s\">adjust</a> frequency of the email updates "
+"or turn them off entirely.<br/>If you believe that this message was sent in "
+"an error, please email about it the forum administrator at "
+"%(admin_email)s.</p><p>Sincerely,</p><p>Your friendly %(sitename)s "
+"server.</p>"
+msgstr "<p>이메일 업데이트의 주기와 수신여부를 항상 <a hrefl\"%(email_settings_link)s\">조정</a>할 수 있음을 기억하세요.<br/>이 메시지가 오류에 의하여 발송된 것이라고 생각하신다면, %(admin_email)s로 이메일을 보내어 포럼 관리자에게 알려주시기 바랍니다.</p><p>친애하는,</p><p>%(sitename)s 서버로부터.</p>"
#: management/commands/send_unanswered_question_reminders.py:60
#, python-format
msgid "%(question_count)d unanswered question about %(topics)s"
msgid_plural "%(question_count)d unanswered questions about %(topics)s"
-msgstr[0] ""
+msgstr[0] "%(topics)s에 관한 질문 중 %(question_count)d개가 답변되지 않음"
#: middleware/forum_mode.py:53
-#, fuzzy, python-format
+#, python-format
msgid "Please log in to use %s"
-msgstr ""
-"<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."
+msgstr "%s를 사용하기 위해 로그인해주세요"
#: models/__init__.py:320
msgid ""
"Sorry, you cannot accept or unaccept best answers because your account is "
"blocked"
-msgstr ""
+msgstr "죄송합니다. 계정이 차단되어 으뜸 답변을 선택 또는 거부할 수 없습니다"
#: models/__init__.py:324
msgid ""
"Sorry, you cannot accept or unaccept best answers because your account is "
"suspended"
-msgstr ""
+msgstr "죄송합니다. 계정이 정지되어 으뜸 답변을 선택 또는 거부할 수 없습니다"
#: models/__init__.py:337
#, 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:359
#, 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:367
#, 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:390
-#, fuzzy
msgid "Sorry, you cannot vote for your own posts"
-msgstr "Sorry, you cannot vote for your own posts"
+msgstr "미안합니다. 자신의 포스트에 투표하실 수 없습니다"
#: models/__init__.py:394
msgid "Sorry your account appears to be blocked "
-msgstr ""
+msgstr "미안합니다. 계정이 차단된 것 같습니다"
#: models/__init__.py:399
msgid "Sorry your account appears to be suspended "
-msgstr ""
+msgstr "미안합다. 계정이 정지된 것 같습니다"
#: models/__init__.py:409
#, python-format
msgid ">%(points)s points required to upvote"
-msgstr ">%(points)s points required to upvote "
+msgstr "찬성하기 위해 >%(points)s 점 필요"
#: models/__init__.py:415
#, python-format
msgid ">%(points)s points required to downvote"
-msgstr ">%(points)s points required to downvote "
+msgstr "반대표에 >%(points)s 점 필요"
#: models/__init__.py:430
msgid "Sorry, blocked users cannot upload files"
-msgstr ""
+msgstr "죄송합니다. 차단된 사용자는 파일을 업로드할 수 없습니다"
#: models/__init__.py:431
msgid "Sorry, suspended users cannot upload files"
-msgstr ""
+msgstr "미안합니다. 정지된 사용자는 파일을 업로드할 수 없습니다"
#: models/__init__.py:433
#, python-format
msgid "sorry, file uploading requires karma >%(min_rep)s"
-msgstr ""
+msgstr "미안합니다. 파일 업로드에는 karma >%(min_rep)s가 필요합니다"
#: models/__init__.py:482
#, python-format
@@ -2975,56 +2911,57 @@ msgid ""
msgid_plural ""
"Sorry, comments (except the last one) are editable only within %(minutes)s "
"minutes from posting"
-msgstr[0] ""
+msgstr[0] "미안합니다. 댓글은 게시한지 %(minutes)s 분 이내에만 수정할 수 있습니다(마지막 것은 제외) ."
#: models/__init__.py:494
msgid "Sorry, but only post owners or moderators can edit comments"
-msgstr ""
+msgstr "미안합니다. 게시물의 소유자 또는 조정자만이 댓글을 수정할 수 있습니다"
#: models/__init__.py:519
msgid ""
"Sorry, since your account is suspended you can comment only your own posts"
-msgstr ""
+msgstr "미안합니다. 계정이 정지되었기 때문에 자신의 게시물에 대해서만 댓글을 달 수 있습니다"
#: models/__init__.py:523
#, 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 ""
+msgstr "미안합니다. 게시물에 댓글을 달기 위해서는 %(min_rep)s 점의 평판이 필요합니다. 그렇더라도 자신의 게시물에는 댓글을 달 수 있으며 자신의 질문에도 답변할 수 있습니다"
#: models/__init__.py:553
msgid ""
"This post has been deleted and can be seen only by post owners, site "
"administrators and moderators"
-msgstr ""
+msgstr "이 게시물은 삭제되었으며 게시물의 소유자, 사이트 관리자 및 조정자만 볼 수 있습니다"
#: models/__init__.py:570
msgid ""
-"Sorry, only moderators, site administrators and post owners can edit deleted "
-"posts"
-msgstr ""
+"Sorry, only moderators, site administrators and post owners can edit deleted"
+" posts"
+msgstr "미안합니다. 조정자, 사이트 관리자 및 게시물의 소유자만이 삭제된 게시물을 편집할 수 있습니다"
#: models/__init__.py:585
msgid "Sorry, since your account is blocked you cannot edit posts"
-msgstr ""
+msgstr "미안합니다. 계정이 차단되어 게시물을 편집하실 수 없습니다"
#: models/__init__.py:589
-msgid "Sorry, since your account is suspended you can edit only your own posts"
-msgstr ""
+msgid ""
+"Sorry, since your account is suspended you can edit only your own posts"
+msgstr "미안합니다. 계정이 정지되었으므로 자신의 게시물만 편집할 수 있습니다"
#: models/__init__.py:594
#, 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:601
#, 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:664
msgid ""
@@ -3033,693 +2970,686 @@ msgid ""
msgid_plural ""
"Sorry, cannot delete your question since it has some upvoted answers posted "
"by other users"
-msgstr[0] ""
+msgstr[0] "미안합니다. 다른 사용자가 게시한 답변에 추천이 있으므로 질문을 삭제할 수 없습니다."
#: models/__init__.py:679
msgid "Sorry, since your account is blocked you cannot delete posts"
-msgstr ""
+msgstr "미안합니다. 계정이 차단되었으므로 게시물을 삭제할 수 없습니다"
#: models/__init__.py:683
msgid ""
"Sorry, since your account is suspended you can delete only your own posts"
-msgstr ""
+msgstr "미안합니다. 계정이 정지되었으므로 자신의 게시물만 삭제할 수 있습니다"
#: models/__init__.py:687
#, python-format
msgid ""
"Sorry, to deleted other people' posts, a minimum reputation of %(min_rep)s "
"is required"
-msgstr ""
+msgstr "미안합니다. 다른 사람의 게시물을 삭제하려면 최소 %(min_rep)s의 평판이 필요합니다"
#: models/__init__.py:707
msgid "Sorry, since your account is blocked you cannot close questions"
-msgstr ""
+msgstr "미안합니다. 계정이 차단되었으므로 질문을 종료할 수 없습니다"
#: models/__init__.py:711
msgid "Sorry, since your account is suspended you cannot close questions"
-msgstr ""
+msgstr "미안합니다. 계정이 정지되었으므로 질문을 종료할 수 없습니다"
#: models/__init__.py:715
#, 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:724
#, 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:748
#, 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:754
#, python-format
msgid ""
-"Sorry, to reopen own question a minimum reputation of %(min_rep)s is required"
-msgstr ""
+"Sorry, to reopen own question a minimum reputation of %(min_rep)s is "
+"required"
+msgstr "미안합니다. 자신의 질문을 재개하려면 최소 %(min_rep)s 평판이 필요합니다"
#: models/__init__.py:775
msgid "You have flagged this question before and cannot do it more than once"
-msgstr ""
+msgstr "전에 이 질문을 신고하였으므로 다시 신고하실 수 없습니다"
#: models/__init__.py:783
-msgid "Sorry, since your account is blocked you cannot flag posts as offensive"
-msgstr ""
+msgid ""
+"Sorry, since your account is blocked you cannot flag posts as offensive"
+msgstr "미안합니다. 계정이 차단되어 포스트에 대해 공격적이라고 신고하실 수 없습니다"
#: models/__init__.py:794
#, 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:815
#, python-format
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:827
msgid "cannot remove non-existing flag"
-msgstr ""
+msgstr "존재하지 않는 표시는 제거할수 없습니다"
#: models/__init__.py:833
-#, fuzzy
msgid "Sorry, since your account is blocked you cannot remove flags"
-msgstr ""
-"Sorry, since your account is blocked you cannot flag posts as offensive"
+msgstr "미안합니다. 계정이 차단되었으므로 신고를 취소하실 수 없습니다"
#: models/__init__.py:837
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:843
#, 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:862
msgid "you don't have the permission to remove all flags"
-msgstr ""
+msgstr "모든 표시를 제거할수 있는 권한이 없습니다"
#: models/__init__.py:863
msgid "no flags for this entry"
-msgstr ""
+msgstr "이 항목에 대한 표시가 없습니다"
#: models/__init__.py:887
msgid ""
"Sorry, only question owners, site administrators and moderators can retag "
"deleted questions"
-msgstr ""
+msgstr "미안합니다. 질문의 소유자, 사이트 관리자 및 조정자만이 삭제된 질문에 대하여 태그를 수정할 수 있습니다"
#: models/__init__.py:894
msgid "Sorry, since your account is blocked you cannot retag questions"
-msgstr ""
+msgstr "미안합니다. 계정이 차단되었으므로 질문의 태그를 수정할 수 없습니다"
#: models/__init__.py:898
msgid ""
"Sorry, since your account is suspended you can retag only your own questions"
-msgstr ""
+msgstr "미안합니다. 계정이 정지되었으므로 자신의 질문에 대한 태그만 수정하실 수 있습니다"
#: models/__init__.py:902
#, python-format
msgid ""
"Sorry, to retag questions a minimum reputation of %(min_rep)s is required"
-msgstr ""
+msgstr "미안합니다. 질문에 대한 태그를 수정하려면 최소 %(min_rep)s 평판이 필요합니다"
#: models/__init__.py:921
msgid "Sorry, since your account is blocked you cannot delete comment"
-msgstr ""
+msgstr "미안합니다. 계정이 차단되었으므로 댓글을 삭제할 수 없습니다"
#: models/__init__.py:925
msgid ""
"Sorry, since your account is suspended you can delete only your own comments"
-msgstr ""
+msgstr "미안합니다. 계정이 정지되었으므로 자신의 댓글만 삭제할 수 있습니다"
#: models/__init__.py:929
#, python-format
msgid "Sorry, to delete comments reputation of %(min_rep)s is required"
-msgstr ""
+msgstr "미안합니다. 댓글을 삭제하려면 %(min_rep)s 평판이 필요합니다"
#: models/__init__.py:953
msgid "sorry, but older votes cannot be revoked"
-msgstr ""
+msgstr "미안합니다. 오래된 투표는 취소하실 수 없습니다"
#: models/__init__.py:1469 utils/functions.py:78
#, python-format
msgid "on %(date)s"
-msgstr ""
+msgstr "on %(date)s"
#: models/__init__.py:1471
msgid "in two days"
-msgstr ""
+msgstr "이틀 내로"
#: models/__init__.py:1473
msgid "tomorrow"
-msgstr ""
+msgstr "내일"
#: models/__init__.py:1475
#, python-format
msgid "in %(hr)d hour"
msgid_plural "in %(hr)d hours"
-msgstr[0] ""
+msgstr[0] "%(hr)d 시간 내"
#: models/__init__.py:1477
#, python-format
msgid "in %(min)d min"
msgid_plural "in %(min)d mins"
-msgstr[0] ""
+msgstr[0] "%(min)d 분 내"
#: models/__init__.py:1478
#, python-format
msgid "%(days)d day"
msgid_plural "%(days)d days"
-msgstr[0] ""
+msgstr[0] "%(days)d 일"
#: models/__init__.py:1480
#, python-format
msgid ""
"New users must wait %(days)s before answering their own question. You can "
"post an answer %(left)s"
-msgstr ""
+msgstr "자신의 질문에 답변하기 위해서는 %(days)s 동안 기다려야 합니다. %(left)s 답변을 게시할 수 있습니다"
#: models/__init__.py:1653 skins/default/templates/feedback_email.txt:9
msgid "Anonymous"
-msgstr ""
+msgstr "익명"
#: models/__init__.py:1749
msgid "Site Adminstrator"
-msgstr ""
+msgstr "사이트 관리자"
#: models/__init__.py:1751
msgid "Forum Moderator"
-msgstr ""
+msgstr "포럼 조정자"
#: models/__init__.py:1753
msgid "Suspended User"
-msgstr ""
+msgstr "정지된 사용자"
#: models/__init__.py:1755
msgid "Blocked User"
-msgstr ""
+msgstr "차단된 사용자"
#: models/__init__.py:1757
msgid "Registered User"
-msgstr ""
+msgstr "등록된 사용자"
#: models/__init__.py:1759
msgid "Watched User"
-msgstr ""
+msgstr "Watched 사용자"
#: models/__init__.py:1761
msgid "Approved User"
-msgstr ""
+msgstr "승인된 사용자"
#: models/__init__.py:1870
#, python-format
msgid "%(username)s karma is %(reputation)s"
-msgstr ""
+msgstr "%(username)s 카르마는 %(reputation)s입니다"
#: models/__init__.py:1880
#, python-format
msgid "one gold badge"
msgid_plural "%(count)d gold badges"
-msgstr[0] ""
+msgstr[0] "%(count)d 금 배지"
#: models/__init__.py:1887
#, python-format
msgid "one silver badge"
msgid_plural "%(count)d silver badges"
-msgstr[0] ""
+msgstr[0] "%(count)d 은 배지"
#: models/__init__.py:1894
#, python-format
msgid "one bronze badge"
msgid_plural "%(count)d bronze badges"
-msgstr[0] ""
+msgstr[0] "%(count)d 동 배지"
#: models/__init__.py:1905
#, python-format
msgid "%(item1)s and %(item2)s"
-msgstr ""
+msgstr "%(item1)s과 %(item2)s"
#: models/__init__.py:1909
#, python-format
msgid "%(user)s has %(badges)s"
-msgstr ""
+msgstr "%(user)s는 %(badges)s를 갖고 있습니다"
#: models/__init__.py:2389
#, python-format
msgid "\"%(title)s\""
-msgstr ""
+msgstr "\"%(title)s\""
#: models/__init__.py:2542
#, python-format
msgid ""
"Congratulations, you have received a badge '%(badge_name)s'. Check out <a "
"href=\"%(user_profile)s\">your profile</a>."
-msgstr ""
+msgstr "축하합니다. '%(badge_name)s' 배지를 받으셨습니다. <a href=\"%(user_profile)s\">사용자 프로필</a>을 확인해보세요."
#: models/__init__.py:2745 views/commands.py:460
msgid "Your tag subscription was saved, thanks!"
-msgstr ""
+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"
-msgstr ""
+msgstr "좋은 답변"
#: models/badges.py:328
msgid "Great Answer"
-msgstr ""
+msgstr "최고의 답변"
#: models/badges.py:340
msgid "Nice Question"
-msgstr ""
+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"
-msgstr ""
+msgstr "좋은 질문"
#: models/badges.py:364
msgid "Great Question"
-msgstr ""
+msgstr "최고의 질문"
#: models/badges.py:376
msgid "Student"
-msgstr ""
+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"
-msgstr ""
+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/post.py:1071
msgid "Sorry, this question has been deleted and is no longer accessible"
-msgstr ""
+msgstr "미안합니다. 이 질문은 삭제되었으므로 더 이상 접근할 수 없습니다"
#: models/post.py:1087
msgid ""
"Sorry, the answer you are looking for is no longer available, because the "
"parent question has been removed"
-msgstr ""
+msgstr "미안합니다. 부모 질문이 삭제되었으므로, 찾으시는 답변이 더 이상 유효하지 않습니다"
#: models/post.py:1094
msgid "Sorry, this answer has been removed and is no longer accessible"
-msgstr ""
+msgstr "미안합니다. 이 질문은 삭제되었으므로 더 이상 접근할 수 없습니다"
#: models/post.py:1110
msgid ""
"Sorry, the comment you are looking for is no longer accessible, because the "
"parent question has been removed"
-msgstr ""
+msgstr "미안합니다. 찾으시는 댓글의 부모 질문이 삭제되었으므로 더 이상 접근할 수 없습니다."
#: models/post.py:1117
msgid ""
"Sorry, the comment you are looking for is no longer accessible, because the "
"parent answer has been removed"
-msgstr ""
+msgstr "미안합니다. 찾으시는 댓글의 부모 답변이 삭제되었으므로 더 이상 접근할 수 없습니다."
#: models/question.py:54
#, python-format
msgid "\" and \"%s\""
-msgstr ""
+msgstr "\" 및 \"%s\""
#: models/question.py:57
msgid "\" and more"
-msgstr ""
+msgstr "\" 와 그 이상"
#: models/reply_by_email.py:71
-#, fuzzy
msgid "edited by email"
-msgstr "How to validate email and why?"
+msgstr "이메일에 의하여 편집"
#: models/repute.py:143
#, python-format
msgid "<em>Changed by moderator. Reason:</em> %(reason)s"
-msgstr ""
+msgstr "<em>조정자에 의하여 변경됨. 이유:</em> %(reason)s"
#: models/repute.py:154
#, python-format
msgid ""
"%(points)s points were added for %(username)s's contribution to question "
"%(question_title)s"
-msgstr ""
+msgstr "%(question_title)s 질문에 대한 %(username)s의 공헌에 %(points)s점이 가점되었습니다"
#: models/repute.py:159
#, python-format
msgid ""
"%(points)s points were subtracted for %(username)s's contribution to "
"question %(question_title)s"
-msgstr ""
+msgstr "%(question_title)s 질문에 대한 %(username)s의 공헌에 %(points)s점이 감점되었습니다"
#: models/tag.py:106
msgid "interesting"
-msgstr ""
+msgstr "흥미로운"
#: models/tag.py:106
msgid "ignored"
-msgstr ""
+msgstr "무시된"
#: models/user.py:266
msgid "Entire forum"
-msgstr ""
+msgstr "전체 포럼"
#: models/user.py:267
msgid "Questions that I asked"
-msgstr ""
+msgstr "내가 물어본 질문들"
#: models/user.py:268
msgid "Questions that I answered"
-msgstr ""
+msgstr "내가 답변한 질문들"
#: models/user.py:269
msgid "Individually selected questions"
-msgstr ""
+msgstr "개별적으로 선택한 질문들"
#: models/user.py:270
msgid "Mentions and comment responses"
-msgstr ""
+msgstr "언급 및 댓글 응답"
#: models/user.py:273
msgid "Instantly"
-msgstr ""
+msgstr "즉시"
#: models/user.py:274
msgid "Daily"
-msgstr ""
+msgstr "매일"
#: models/user.py:275
msgid "Weekly"
-msgstr ""
+msgstr "매주"
#: models/user.py:276
msgid "No email"
-msgstr ""
+msgstr "이메일 받지 않음"
#: skins/common/templates/authopenid/authopenid_macros.html:63
msgid "Please enter your <span>user name</span>, then sign in"
-msgstr ""
+msgstr "귀하의 <span>사용자명</span>을 입력한 다음, 로그인하세요"
#: skins/common/templates/authopenid/authopenid_macros.html:64
#: skins/common/templates/authopenid/signin.html:97
msgid "(or select another login method above)"
-msgstr ""
+msgstr "(또는 위의 다른 로그인 방법을 선택)"
#: skins/common/templates/authopenid/authopenid_macros.html:66
#: skins/common/templates/authopenid/signin.html:113
msgid "Sign in"
-msgstr ""
+msgstr "로그인"
#: skins/common/templates/authopenid/changeemail.html:2
#: skins/common/templates/authopenid/changeemail.html:8
#: skins/common/templates/authopenid/changeemail.html:49
-#, fuzzy
msgid "Change Email"
-msgstr "Change Email"
+msgstr "이메일 변경"
#: skins/common/templates/authopenid/changeemail.html:10
-#, fuzzy
msgid "Save your email address"
-msgstr "Your email <i>(never shared)</i>"
+msgstr "이메일 주소를 저장해 주십시오"
#: skins/common/templates/authopenid/changeemail.html:15
#, python-format
msgid ""
-"<span class=\\\"strong big\\\">Enter your new email into the box below</"
-"span> if \n"
+"<span class=\\\"strong big\\\">Enter your new email into the box below</span> if \n"
"you'd like to use another email for <strong>update subscriptions</strong>.\n"
"<br>Currently you are using <strong>%%(email)s</strong>"
-msgstr ""
+msgstr "<strong>새 소식 받아보기</strong>에 다른 이메일을 사용하고 싶으시다면 <span class=\\\"strong big\\\">새로운 이메일을 아래의 박스에 입력하세요</span>.\n<br>현재 사용하시는 이메일은 <strong>%%(email)s</strong>입니다"
#: skins/common/templates/authopenid/changeemail.html:19
#, python-format
msgid ""
-"<span class='strong big'>Please enter your email address in the box below.</"
-"span>\n"
+"<span class='strong big'>Please enter your email address in the box below.</span>\n"
"Valid email address is required on this Q&amp;A forum. If you like, \n"
"you can <strong>receive updates</strong> on interesting questions or entire\n"
"forum via email. Also, your email is used to create a unique \n"
-"<a href='%%(gravatar_faq_url)s'><strong>gravatar</strong></a> image for "
-"your\n"
+"<a href='%%(gravatar_faq_url)s'><strong>gravatar</strong></a> image for your\n"
"account. Email addresses are never shown or otherwise shared with anybody\n"
"else."
-msgstr ""
+msgstr "<span class='strong big'>아래의 박스에 이메일 주소를 입력하세요.</span>\n이 Q&amp;A 포럼에서는 유효한 이메일 주소를 필요로 합니다. 원하신다면, \n관심 있는 질문 또는 전체 포럼에 대하여 이메일을 통하여 <strong>업데이트를 받아보기</strong> 하실 수 있습니다. 또한, 이메일은 유일한 \n<a href='%%(gravatar_faq_url)s'><strong>그라바타</strong></a> 이미지을 생성하는 데에 사용됩니다. 이메일 주소는 노출되지 않으며 다른 사람에게 공유되지 않습니다."
#: skins/common/templates/authopenid/changeemail.html:38
msgid ""
"<strong>Your new Email:</strong> \n"
"(will <strong>not</strong> be shown to anyone, must be valid)"
-msgstr ""
+msgstr "<strong>새로운 이메일:</strong> \n(<strong>다른 사람에게 보이지 않으니</strong>, 유효한 주소를 입력해주세요)"
#: skins/common/templates/authopenid/changeemail.html:49
-#, fuzzy
msgid "Save Email"
-msgstr "Change Email"
+msgstr "이메일 저장"
#: skins/common/templates/authopenid/changeemail.html:51
#: skins/default/templates/answer_edit.html:25
@@ -3731,78 +3661,66 @@ msgstr "Change Email"
#: skins/default/templates/subscribe_for_tags.html:16
#: skins/default/templates/user_profile/user_edit.html:102
msgid "Cancel"
-msgstr ""
+msgstr "취소"
#: skins/common/templates/authopenid/changeemail.html:58
-#, fuzzy
msgid "Validate email"
-msgstr "How to validate email and why?"
+msgstr "이메일 유효성 검사"
#: skins/common/templates/authopenid/changeemail.html:61
#, python-format
msgid ""
-"<span class=\\\"strong big\\\">An email with a validation link has been sent "
-"to \n"
-"%%(email)s.</span> Please <strong>follow the emailed link</strong> with "
-"your \n"
-"web browser. Email validation is necessary to help insure the proper use "
-"of \n"
-"email on <span class=\\\"orange\\\">Q&amp;A</span>. If you would like to "
-"use \n"
+"<span class=\\\"strong big\\\">An email with a validation link has been sent to \n"
+"%%(email)s.</span> Please <strong>follow the emailed link</strong> with your \n"
+"web browser. Email validation is necessary to help insure the proper use of \n"
+"email on <span class=\\\"orange\\\">Q&amp;A</span>. If you would like to use \n"
"<strong>another email</strong>, please <a \n"
"href='%%(change_email_url)s'><strong>change it again</strong></a>."
-msgstr ""
+msgstr "<span class=\\\"strong big\\\">검증 링크가 있는 이메일이 \n%%(email)s으로 발송되었습니다.</span> 웹 브라우저에서 <strong>이메일 링크를 따라가세요</strong>.\n<span class=\\\"orange\\\">Q&amp;A</span>에 대한 이메일을 적합하게 사용함을 확인하기 위하여 이메일 검증이 필요합니다.\n<strong>다른 이메일</strong>을 사용하고 싶으시면, <a href='%%(change_email_url)s'><strong>다시 변경해주세요</strong></a>."
#: skins/common/templates/authopenid/changeemail.html:70
msgid "Email not changed"
-msgstr ""
+msgstr "이메일 변경 안됨"
#: skins/common/templates/authopenid/changeemail.html:73
#, python-format
msgid ""
-"<span class=\\\"strong big\\\">Your email address %%(email)s has not been "
-"changed.\n"
+"<span class=\\\"strong big\\\">Your email address %%(email)s has not been changed.\n"
"</span> If you decide to change it later - you can always do it by editing \n"
"it in your user profile or by using the <a \n"
"href='%%(change_email_url)s'><strong>previous form</strong></a> again."
-msgstr ""
+msgstr "<span class=\\\"strong big\\\">이메일 주소 %%(email)s가 변경되지 않았습니다.</span>\n<a href='%%(change_email_url)s'><strong>이전 양식</strong></a>으로 돌아가거나,\n나중에 사용자 프로필에서 변경하실 수 있습니다."
#: skins/common/templates/authopenid/changeemail.html:80
msgid "Email changed"
-msgstr ""
+msgstr "이메일 변경됨"
#: skins/common/templates/authopenid/changeemail.html:83
#, python-format
msgid ""
"\n"
-"<span class='big strong'>Your email address is now set to %%(email)s.</"
-"span> \n"
+"<span class='big strong'>Your email address is now set to %%(email)s.</span> \n"
"Updates on the questions that you like most will be sent to this address. \n"
-"Email notifications are sent once a day or less frequently - only when "
-"there \n"
+"Email notifications are sent once a day or less frequently - only when there \n"
"are any news."
-msgstr ""
+msgstr "\n<span class='big strong'>귀하의 이메일 주소는 %%(email)s로 설정되었습니다.</span> \n좋아하시는 질문에 대한 업데이트가 이 주소로 발송될 것입니다. \n이메일 알림은 새로운 소식일 있을 경우에만 하루에 한 번 이내로 발송됩니다."
#: skins/common/templates/authopenid/changeemail.html:91
msgid "Email verified"
-msgstr ""
+msgstr "이메일 인증됨"
#: skins/common/templates/authopenid/changeemail.html:94
msgid ""
-"<span class=\\\"big strong\\\">Thank you for verifying your email!</span> "
-"Now \n"
-"you can <strong>ask</strong> and <strong>answer</strong> questions. Also "
-"if \n"
+"<span class=\\\"big strong\\\">Thank you for verifying your email!</span> Now \n"
+"you can <strong>ask</strong> and <strong>answer</strong> questions. Also if \n"
"you find a very interesting question you can <strong>subscribe for the \n"
-"updates</strong> - then will be notified about changes <strong>once a day</"
-"strong>\n"
+"updates</strong> - then will be notified about changes <strong>once a day</strong>\n"
"or less frequently."
-msgstr ""
+msgstr "<span class=\\\"big strong\\\">이메일을 확인해주셔서 고맙습니다!</span> 이제 <strong>질문</strong>과 <strong>답변</strong>을 하실 수 있습니다. 또한 흥미로운 질문을 발견하시면 <strong>업데이트를 구독</strong>하심으로써 변경된 사항을 <strong>하루에 한 번</strong> 이내로 받아보실 수 있습니다."
#: skins/common/templates/authopenid/changeemail.html:102
-#, fuzzy
msgid "Validation email not sent"
-msgstr "How to validate email and why?"
+msgstr "확인 이메일이 발송되지 않음"
#: skins/common/templates/authopenid/changeemail.html:105
#, python-format
@@ -3811,107 +3729,94 @@ msgid ""
"validated before</span> so the new key was not sent. You can <a \n"
"href='%%(change_link)s'>change</a> email used for update subscriptions if \n"
"necessary."
-msgstr ""
+msgstr "<span class='big strong'>귀하의 현재 이메일 주소 %%(email)은 이미 확인되었으므로</span> 새로운 키가 발송되지 않았습니다. 필요하다면 구독 갱신을 위하여 사용되는 이메일을 <a \nhref='%%(change_link)s'>변경</a>하실 수 있습니다"
#: skins/common/templates/authopenid/complete.html:21
-#, fuzzy
msgid "Registration"
-msgstr "karma"
+msgstr "등록"
#: skins/common/templates/authopenid/complete.html:23
-#, fuzzy
msgid "User registration"
-msgstr "karma"
+msgstr "사용자 등록"
#: skins/common/templates/authopenid/complete.html:60
msgid "<strong>Receive forum updates by email</strong>"
-msgstr ""
+msgstr "<strong>포럼의 새 소식들을 이메일로 받음</strong>"
#: skins/common/templates/authopenid/complete.html:64
#: skins/common/templates/authopenid/signup_with_password.html:46
msgid "please select one of the options above"
-msgstr ""
+msgstr "위의 옵션중 하나를 선택해 주십시오"
#: skins/common/templates/authopenid/complete.html:67
#: skins/common/templates/authopenid/signup_with_password.html:4
#: skins/common/templates/authopenid/signup_with_password.html:53
msgid "Signup"
-msgstr ""
+msgstr "가입"
#: skins/common/templates/authopenid/confirm_email.txt:1
msgid "Thank you for registering at our Q&A forum!"
-msgstr ""
+msgstr "저희 Q&A 포럼에 등록해주셔서 고맙습니다!"
#: skins/common/templates/authopenid/confirm_email.txt:3
msgid "Your account details are:"
-msgstr ""
+msgstr "귀하의 계정에 대한 상세 정보:"
#: skins/common/templates/authopenid/confirm_email.txt:5
-#, fuzzy
msgid "Username:"
-msgstr "Choose screen name"
+msgstr "사용자명:"
#: skins/common/templates/authopenid/confirm_email.txt:6
-#, fuzzy
msgid "Password:"
-msgstr "Password"
+msgstr "비밀번호:"
#: skins/common/templates/authopenid/confirm_email.txt:8
-#, fuzzy
msgid "Please sign in here:"
-msgstr ""
-"<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."
+msgstr "여기서 로그인하세요:"
#: skins/common/templates/authopenid/confirm_email.txt:11
#: skins/common/templates/authopenid/email_validation.txt:13
-#, fuzzy
msgid ""
"Sincerely,\n"
"Q&A Forum Administrator"
-msgstr ""
-"Sincerely,\n"
-"Q&A Forum Administrator"
+msgstr "Q&A 포럼 관리자로부터"
#: skins/common/templates/authopenid/email_validation.txt:1
msgid "Greetings from the Q&A forum"
-msgstr ""
+msgstr "Q&A 포럼으로부터 인사"
#: skins/common/templates/authopenid/email_validation.txt:3
msgid "To make use of the Forum, please follow the link below:"
-msgstr ""
+msgstr "포럼을 사용하려면, 아래의 링크를 따라가세요:"
#: skins/common/templates/authopenid/email_validation.txt:7
msgid "Following the link above will help us verify your email address."
-msgstr ""
+msgstr "위의 링크를 따라서 이메일 주소를 검증하실 수 있습니다."
#: skins/common/templates/authopenid/email_validation.txt:9
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 "만일 이 메세지가 실수로 발송되었다고 생각된다면\n별도의 조치를 취할 필요가 없습니다. 그냥 이 이메일을 무시하시면 되며,\n불편을 끼친것에 대하여 사과드립니다."
#: skins/common/templates/authopenid/logout.html:3
msgid "Logout"
-msgstr "Sign out"
+msgstr "로그아웃"
#: skins/common/templates/authopenid/logout.html:5
msgid "You have successfully logged out"
-msgstr ""
+msgstr "성공적으로 로그아웃 하셨습니다"
#: skins/common/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 제공자에 계속 로그인되어 있을 수 있습니다. 원하신다면 사용하시는 OpenID에서 로그아웃하시기 바랍니다."
#: skins/common/templates/authopenid/signin.html:4
msgid "User login"
-msgstr "User login"
+msgstr "사용자 로그인"
#: skins/common/templates/authopenid/signin.html:14
#, python-format
@@ -3919,11 +3824,7 @@ msgid ""
"\n"
" Your answer to %(title)s %(summary)s will be posted once you log in\n"
" "
-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>"
+msgstr "\n<i>\"<strong>%(title)s</strong> %(summary)s...\"</i>에 대한 <span class=\"strong big\">귀하의 답변</span> <span class=\"strong big\">는 저장되었으며 로그인 후에 게시됩니다.</span>"
#: skins/common/templates/authopenid/signin.html:21
#, python-format
@@ -3931,154 +3832,139 @@ msgid ""
"Your question \n"
" %(title)s %(summary)s will be posted once you log in\n"
" "
-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>"
+msgstr "<span class=\"strong big\">귀하의 질문</span> <i>\"<strong>%(title)s</strong> %(summary)s...\"</i> <span class=\"strong big\">은 저장되었으며 로그인 후에 게시됩니다.</span>"
#: skins/common/templates/authopenid/signin.html:28
msgid ""
-"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."
-msgstr ""
+"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."
+msgstr "안전한 OpenID 또는 그와 유사한 기술 중에서 선호하는 서비스를 아래에서 선택하십시오. 외부 서비스의 비밀번호는 항상 비밀로 유지되며 그것을 기억하거나 새로운 것을 생성할 필요가 없습니다."
#: skins/common/templates/authopenid/signin.html:31
msgid ""
"It's a good idea to make sure that your existing login methods still work, "
-"or add a new one. Please click any of the icons below to check/change or add "
-"new login methods."
-msgstr ""
+"or add a new one. Please click any of the icons below to check/change or add"
+" new login methods."
+msgstr "기존의 로그인 방법이 여전히 동작하는지 확인하거나 새로운 방법을 추가하시는 것은 좋은 생각입니다. 아래의 점검/변경 또는 새 로그인 방법 추가 버튼 중에 하나를 클릭해 주시기 바랍니다."
#: skins/common/templates/authopenid/signin.html:33
msgid ""
-"Please add a more permanent login method by clicking one of the icons below, "
-"to avoid logging in via email each time."
-msgstr ""
+"Please add a more permanent login method by clicking one of the icons below,"
+" to avoid logging in via email each time."
+msgstr "매번 이메일을 통한 로깅을 피하시려면 아래의 아이콘중에 하나를 클릭해서 영구적인 로그인 방법을 추가해 주시기 바랍니다."
#: skins/common/templates/authopenid/signin.html:37
msgid ""
"Click on one of the icons below to add a new login method or re-validate an "
"existing one."
-msgstr ""
+msgstr "아래의 아이콘중 하나를 클릭해서 새로운 로그인 방식을 추가하거나 기존의 로그인 방법에 대한 재확인을 하시기 바랍니다."
#: skins/common/templates/authopenid/signin.html:39
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 "지금 바로 사용할수 있는 로그인 방법이 없습니다. 아래의 아이콘중 하나를 눌러서 추가해주시기 바랍니다."
#: skins/common/templates/authopenid/signin.html:42
msgid ""
"Please check your email and visit the enclosed link to re-connect to your "
"account"
-msgstr ""
+msgstr "이메일을 확인하시고 이메일에 동봉된 링크를 방문하여 계정을 재접속하시기 바랍니다."
#: skins/common/templates/authopenid/signin.html:89
msgid "or enter your <span>user name and password</span>, then sign in"
-msgstr ""
+msgstr "또는 <span>사용자명과 비밀번호</span>를 입력한 다음, 가입해주세요"
#: skins/common/templates/authopenid/signin.html:93
-#, fuzzy
msgid "Please, sign in"
-msgstr ""
-"<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."
+msgstr "로그인해주세요"
#: skins/common/templates/authopenid/signin.html:100
msgid "Login failed, please try again"
-msgstr ""
+msgstr "로그인에 실패하였습니다, 다시 시도해 주시기 바랍니다."
#: skins/common/templates/authopenid/signin.html:104
msgid "Login or email"
-msgstr ""
+msgstr "아이디 또는 이메일"
#: skins/common/templates/authopenid/signin.html:108 utils/forms.py:169
-#, fuzzy
msgid "Password"
-msgstr "Password"
+msgstr "비밀번호"
#: skins/common/templates/authopenid/signin.html:120
msgid "To change your password - please enter the new one twice, then submit"
-msgstr ""
+msgstr "비밀번호 변경 - 새로운 비밀번호를 두번 입력한 다음, 제출해주세요"
#: skins/common/templates/authopenid/signin.html:124
-#, fuzzy
msgid "New password"
-msgstr "Password"
+msgstr "새로운 비밀번호"
#: skins/common/templates/authopenid/signin.html:133
msgid "Please, retype"
-msgstr ""
+msgstr "다시 입력해 주십시오"
#: skins/common/templates/authopenid/signin.html:157
msgid "Here are your current login methods"
-msgstr ""
+msgstr "현재 사용중인 로그인 방법"
#: skins/common/templates/authopenid/signin.html:161
msgid "provider"
-msgstr ""
+msgstr "제공자"
#: skins/common/templates/authopenid/signin.html:162
-#, fuzzy
msgid "last used"
-msgstr "Last updated"
+msgstr "최근 사용"
#: skins/common/templates/authopenid/signin.html:163
msgid "delete, if you like"
-msgstr ""
+msgstr "원하실 경우 삭제"
#: skins/common/templates/authopenid/signin.html:177
#: skins/common/templates/question/answer_controls.html:13
#: skins/common/templates/question/question_controls.html:4
-#, fuzzy
msgid "delete"
-msgstr "How to change my picture (gravatar) and what is gravatar?"
+msgstr "삭제"
#: skins/common/templates/authopenid/signin.html:179
-#, fuzzy
msgid "cannot be deleted"
-msgstr "sorry, but older votes cannot be revoked"
+msgstr "삭제될수 없음"
#: skins/common/templates/authopenid/signin.html:192
-#, fuzzy
msgid "Still have trouble signing in?"
-msgstr "Post Your Answer"
+msgstr "아직도 로그인에 문제가 있습니까?"
#: skins/common/templates/authopenid/signin.html:197
msgid "Please, enter your email address below and obtain a new key"
-msgstr ""
+msgstr "아래에 이메일 주소를 입력하시고 새 키를 받으시기 바랍니다"
#: skins/common/templates/authopenid/signin.html:199
msgid "Please, enter your email address below to recover your account"
-msgstr ""
+msgstr "아래에 이메일 주소를 입력하시고 계정을 복원하시기 바랍니다"
#: skins/common/templates/authopenid/signin.html:202
msgid "recover your account via email"
-msgstr ""
+msgstr "이메일을 통해서 계정을 복원"
#: skins/common/templates/authopenid/signin.html:213
msgid "Send a new recovery key"
-msgstr ""
+msgstr "새 복원 키를 보냄"
#: skins/common/templates/authopenid/signin.html:215
msgid "Recover your account via email"
-msgstr ""
+msgstr "이메일을 통해서 계정을 복원"
#: skins/common/templates/authopenid/signup_with_password.html:10
msgid "Please register by clicking on any of the icons below"
-msgstr ""
+msgstr "아래의 아이콘중 하나를 클릭해서 등록하시기 바랍니다다"
#: skins/common/templates/authopenid/signup_with_password.html:23
msgid "or create a new user name and password here"
-msgstr ""
+msgstr "또는 아래에서 새 사용자명과 비밀번호를 생성"
#: skins/common/templates/authopenid/signup_with_password.html:25
msgid "Create login name and password"
-msgstr ""
+msgstr "로그인 이름과 비밀번호를 생성"
#: skins/common/templates/authopenid/signup_with_password.html:26
msgid ""
@@ -4087,114 +3973,106 @@ msgid ""
"<strong>OpenID</strong> login method. With <strong>OpenID</strong> you can \n"
"simply reuse your external login (e.g. Gmail or AOL) without ever sharing \n"
"your login details with anyone and having to remember yet another password."
-msgstr ""
+msgstr "<span class='strong big'>원하신다면, 포럼 로그인 이름과 비밀번호를 이곳에서 생성하실 수 있습니다. 하지만</span>, <strong>OpenID</strong> 로그인 방법 또한 지원한다는 점을 염두에 두시기 바랍니다. <strong>OpenID</strong>를 사용하면 외부의 로그인(Gmail 또는 AOL 등)을 재사용하실 수 있으며, 다른 사람에게 자세한 정보를 노출하거나 새로운 비밀번호를 기억하지 않아도 됩니다."
#: skins/common/templates/authopenid/signup_with_password.html:41
msgid "<strong>Receive periodic updates by email</strong>"
-msgstr ""
+msgstr "<strong>새 소식을 주기적으로 이메일로 받아보기</strong>"
#: skins/common/templates/authopenid/signup_with_password.html:50
msgid ""
"Please read and type in the two words below to help us prevent automated "
"account creation."
-msgstr ""
+msgstr "아래의 두개 단어를 읽고 입력해서 저희가 자동 계정생성을 막는걸 도와주시기 바랍니다."
#: skins/common/templates/authopenid/signup_with_password.html:55
msgid "or"
-msgstr ""
+msgstr "또는"
#: skins/common/templates/authopenid/signup_with_password.html:56
msgid "return to OpenID login"
-msgstr ""
+msgstr "OpenID 로그인으로 돌아가기"
#: skins/common/templates/avatar/add.html:3
-#, fuzzy
msgid "add avatar"
-msgstr "How to change my picture (gravatar) and what is gravatar?"
+msgstr "아바타 추가"
#: skins/common/templates/avatar/add.html:5
-#, fuzzy
msgid "Change avatar"
-msgstr "Retag question"
+msgstr "아바타 변경"
#: skins/common/templates/avatar/add.html:6
#: skins/common/templates/avatar/change.html:7
msgid "Your current avatar: "
-msgstr ""
+msgstr "현재 사용중인 아바타"
#: skins/common/templates/avatar/add.html:9
#: skins/common/templates/avatar/change.html:11
msgid "You haven't uploaded an avatar yet. Please upload one now."
-msgstr ""
+msgstr "아직 아바타를 업로드하지 않으셨습니다. 지금 하나를 업로드 해주시기 바랍니다."
#: skins/common/templates/avatar/add.html:13
msgid "Upload New Image"
-msgstr ""
+msgstr "새 이미지 업로드"
#: skins/common/templates/avatar/change.html:4
-#, fuzzy
msgid "change avatar"
-msgstr "Retag question"
+msgstr "아바타 변경"
#: skins/common/templates/avatar/change.html:17
msgid "Choose new Default"
-msgstr ""
+msgstr "새 기본값 선택"
#: skins/common/templates/avatar/change.html:22
msgid "Upload"
-msgstr ""
+msgstr "업로드"
#: skins/common/templates/avatar/confirm_delete.html:2
-#, fuzzy
msgid "delete avatar"
-msgstr "How to change my picture (gravatar) and what is gravatar?"
+msgstr "아바타 삭제"
#: skins/common/templates/avatar/confirm_delete.html:4
msgid "Please select the avatars that you would like to delete."
-msgstr ""
+msgstr "삭제하기 원하는 아바타를 선택해 주십시오"
#: skins/common/templates/avatar/confirm_delete.html:6
#, python-format
msgid ""
-"You have no avatars to delete. Please <a href=\"%(avatar_change_url)s"
-"\">upload one</a> now."
-msgstr ""
+"You have no avatars to delete. Please <a "
+"href=\"%(avatar_change_url)s\">upload one</a> now."
+msgstr "삭제할 아바타가 없습니다. 아바타를 하나 <a href=\"%(avatar_change_url)s\">업로드</a> 해주시기 바랍니다."
#: skins/common/templates/avatar/confirm_delete.html:12
msgid "Delete These"
-msgstr ""
+msgstr "이것들을 삭제"
#: skins/common/templates/question/answer_controls.html:2
-#, fuzzy
msgid "swap with question"
-msgstr "Post Your Answer"
+msgstr "질문으로 바꿔치기"
#: skins/common/templates/question/answer_controls.html:7
msgid "permanent link"
-msgstr "link"
+msgstr "고유 링크"
#: skins/common/templates/question/answer_controls.html:8
#: skins/default/templates/widgets/answer_edit_tips.html:45
#: skins/default/templates/widgets/question_edit_tips.html:40
msgid "link"
-msgstr ""
+msgstr "링크"
#: skins/common/templates/question/answer_controls.html:13
#: skins/common/templates/question/question_controls.html:4
-#, fuzzy
msgid "undelete"
-msgstr "How to change my picture (gravatar) and what is gravatar?"
+msgstr "삭제 취소"
#: skins/common/templates/question/answer_controls.html:19
-#, fuzzy
msgid "remove offensive flag"
-msgstr "Tags"
+msgstr "공격적인 게시물에 대한 신고를 취소"
#: skins/common/templates/question/answer_controls.html:21
#: skins/common/templates/question/question_controls.html:16
-#, fuzzy
msgid "remove flag"
-msgstr "Tags"
+msgstr "신고 취소"
#: skins/common/templates/question/answer_controls.html:26
#: skins/common/templates/question/answer_controls.html:35
@@ -4203,76 +4081,73 @@ msgstr "Tags"
#: skins/common/templates/question/question_controls.html:27
msgid ""
"report as offensive (i.e containing spam, advertising, malicious text, etc.)"
-msgstr ""
+msgstr "공격적인 게시물(예: 스팸, 광고, 나쁜 문구 등) 신고하기"
#: skins/common/templates/question/answer_controls.html:28
#: skins/common/templates/question/answer_controls.html:37
#: skins/common/templates/question/question_controls.html:22
#: skins/common/templates/question/question_controls.html:29
msgid "flag offensive"
-msgstr ""
+msgstr "게시물 신고"
#: skins/common/templates/question/answer_controls.html:41
#: skins/common/templates/question/question_controls.html:36
#: skins/default/templates/macros.html:311
#: skins/default/templates/revisions.html:38
#: skins/default/templates/revisions.html:41
-#, fuzzy
msgid "edit"
-msgstr "Change Email"
+msgstr "편집"
#: skins/common/templates/question/answer_vote_buttons.html:6
#: skins/default/templates/user_profile/user_stats.html:24
msgid "this answer has been selected as correct"
-msgstr ""
+msgstr "답변이 정답으로 선택되었습니다"
#: skins/common/templates/question/answer_vote_buttons.html:8
msgid "mark this answer as correct (click again to undo)"
-msgstr ""
+msgstr "이 답변이 옳다고 표시 (다시 클릭하면 취소)"
#: skins/common/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 ""
+"The question has been closed for the following reason "
+"<b>\"%(close_reason)s\"</b> <i>by"
+msgstr "이 질문은 다음의 이유로 종료되었습니다. <b>\"%(close_reason)s\"</b> <i>by"
#: skins/common/templates/question/closed_question_info.html:4
#, python-format
msgid "close date %(closed_at)s"
-msgstr ""
+msgstr "종료일 %(closed_at)s"
#: skins/common/templates/question/question_controls.html:6
-#, fuzzy
msgid "reopen"
-msgstr "You can safely re-use the same login for all OpenID-enabled websites."
+msgstr "재개"
#: skins/common/templates/question/question_controls.html:8
#: skins/default/templates/user_profile/user_inbox.html:67
msgid "close"
-msgstr ""
+msgstr "종료"
#: skins/common/templates/question/question_controls.html:35
msgid "retag"
-msgstr ""
+msgstr "태그 수정"
#: skins/common/templates/widgets/edit_post.html:22
msgid ", one of these is required"
-msgstr ""
+msgstr ", 이들 중 하나가 요구됩니다"
#: skins/common/templates/widgets/edit_post.html:31
#: skins/common/templates/widgets/edit_post.html:36
-#, fuzzy
msgid "tags:"
-msgstr "Tags"
+msgstr "태그들:"
#: skins/common/templates/widgets/edit_post.html:32
msgid "(required)"
-msgstr ""
+msgstr "(필수)"
#: skins/common/templates/widgets/edit_post.html:58
msgid "Toggle the real time Markdown editor preview"
-msgstr ""
+msgstr "실시간 마크다운 편집기 미리보기 토글"
#: skins/common/templates/widgets/edit_post.html:60
#: skins/default/templates/answer_edit.html:61
@@ -4283,302 +4158,274 @@ msgstr ""
#: skins/default/templates/question/javascript.html:85
#: skins/default/templates/question/javascript.html:88
msgid "hide preview"
-msgstr ""
+msgstr "미리보기 숨김"
#: skins/common/templates/widgets/related_tags.html:3
#: skins/default/templates/tags.html:4
msgid "Tags"
-msgstr ""
+msgstr "태그들"
#: skins/common/templates/widgets/tag_selector.html:4
-#, fuzzy
msgid "Interesting tags"
-msgstr "Tags"
+msgstr "흥미로운 태그"
#: skins/common/templates/widgets/tag_selector.html:19
#: skins/common/templates/widgets/tag_selector.html:36
msgid "add"
-msgstr ""
+msgstr "추가"
#: skins/common/templates/widgets/tag_selector.html:21
-#, fuzzy
msgid "Ignored tags"
-msgstr "Retag question"
+msgstr "무시할 태그"
#: skins/common/templates/widgets/tag_selector.html:38
msgid "Display tag filter"
-msgstr ""
+msgstr "태그 필터 보기"
#: skins/default/templates/404.jinja.html:3
#: skins/default/templates/404.jinja.html:10
msgid "Page not found"
-msgstr ""
+msgstr "페이지를 찾을 수 없음"
#: skins/default/templates/404.jinja.html:13
msgid "Sorry, could not find the page you requested."
-msgstr ""
+msgstr "미안합니다. 요청하신 페이지를 찾을 수 없습니다."
#: skins/default/templates/404.jinja.html:15
msgid "This might have happened for the following reasons:"
-msgstr ""
+msgstr "이것은 다음과 같은 이유로 인하여 일어날 수 있습니다:"
#: skins/default/templates/404.jinja.html:17
msgid "this question or answer has been deleted;"
-msgstr ""
+msgstr "이 질문 또는 답변은 삭제되었습니다;"
#: skins/default/templates/404.jinja.html:18
msgid "url has error - please check it;"
-msgstr ""
+msgstr "url에 오류가 있습니다. 확인해주세요;"
#: skins/default/templates/404.jinja.html:19
msgid ""
"the page you tried to visit is protected or you don't have sufficient "
"points, see"
-msgstr ""
+msgstr "방문하려는 페이지는 보호되었거나 회원님의 포인트가 부족합니다."
#: skins/default/templates/404.jinja.html:19
#: skins/default/templates/widgets/footer.html:39
msgid "faq"
-msgstr ""
+msgstr "faq"
#: skins/default/templates/404.jinja.html:20
msgid "if you believe this error 404 should not have occured, please"
-msgstr ""
+msgstr "이 404 오류가 발생할 리가 없다고 확신하신다면, "
#: skins/default/templates/404.jinja.html:21
msgid "report this problem"
-msgstr ""
+msgstr "이 문제를 보고"
#: skins/default/templates/404.jinja.html:30
#: skins/default/templates/500.jinja.html:11
msgid "back to previous page"
-msgstr ""
+msgstr "이전 페이지로 돌아가기"
#: skins/default/templates/404.jinja.html:31
#: skins/default/templates/widgets/scope_nav.html:6
-#, fuzzy
msgid "see all questions"
-msgstr "Ask Your Question"
+msgstr "모든 질문을 보기"
#: skins/default/templates/404.jinja.html:32
-#, fuzzy
msgid "see all tags"
-msgstr "Tags"
+msgstr "모든 태그를 보기"
#: skins/default/templates/500.jinja.html:3
#: skins/default/templates/500.jinja.html:5
msgid "Internal server error"
-msgstr ""
+msgstr "내부 서버 오류"
#: skins/default/templates/500.jinja.html:8
msgid "system error log is recorded, error will be fixed as soon as possible"
-msgstr ""
+msgstr "시스템 오류가 기록되었으며, 가능한 빠른 시일 내에 수정될 것입니다"
#: skins/default/templates/500.jinja.html:9
msgid "please report the error to the site administrators if you wish"
-msgstr ""
+msgstr "사이트 관리자에게 오류를 보고해주시기 바랍니다"
#: skins/default/templates/500.jinja.html:12
-#, fuzzy
msgid "see latest questions"
-msgstr "Post Your Answer"
+msgstr "최근의 질문 보기"
#: skins/default/templates/500.jinja.html:13
-#, fuzzy
msgid "see tags"
-msgstr "Tags"
+msgstr "태그 보기"
#: skins/default/templates/answer_edit.html:4
#: skins/default/templates/answer_edit.html:10
-#, fuzzy
msgid "Edit answer"
-msgstr "oldest"
+msgstr "답변을 편집"
#: skins/default/templates/answer_edit.html:10
#: skins/default/templates/question_edit.html:9
#: skins/default/templates/question_retag.html:5
#: skins/default/templates/revisions.html:7
msgid "back"
-msgstr ""
+msgstr "뒤로"
#: skins/default/templates/answer_edit.html:14
msgid "revision"
-msgstr ""
+msgstr "리비전"
#: skins/default/templates/answer_edit.html:17
#: skins/default/templates/question_edit.html:16
msgid "select revision"
-msgstr ""
+msgstr "리비전 선택"
#: skins/default/templates/answer_edit.html:24
#: skins/default/templates/question_edit.html:35
-#, fuzzy
msgid "Save edit"
-msgstr "Change Email"
+msgstr "수정내용 저장하기"
#: skins/default/templates/answer_edit.html:64
#: skins/default/templates/ask.html:52
#: skins/default/templates/question_edit.html:76
#: skins/default/templates/question/javascript.html:88
msgid "show preview"
-msgstr ""
+msgstr "미리보기"
#: skins/default/templates/ask.html:4
#: skins/default/templates/widgets/ask_button.html:5
#: skins/default/templates/widgets/ask_form.html:43
-#, fuzzy
msgid "Ask Your Question"
-msgstr "Ask Your Question"
+msgstr "질문하기"
#: skins/default/templates/badge.html:5 skins/default/templates/badge.html:9
#: skins/default/templates/user_profile/user_recent.html:19
#: skins/default/templates/user_profile/user_stats.html:108
#, python-format
msgid "%(name)s"
-msgstr ""
+msgstr "%(name)s"
#: skins/default/templates/badge.html:5
-#, fuzzy
msgid "Badge"
-msgstr "Badges"
+msgstr "배지"
#: skins/default/templates/badge.html:7
#, python-format
msgid "Badge \"%(name)s\""
-msgstr ""
+msgstr "\"%(name)s\" 배지"
#: skins/default/templates/badge.html:9
#: skins/default/templates/user_profile/user_recent.html:17
#: skins/default/templates/user_profile/user_stats.html:106
-#, fuzzy, python-format
+#, python-format
msgid "%(description)s"
-msgstr ""
-"<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."
+msgstr "%(description)s"
#: skins/default/templates/badge.html:14
msgid "user received this badge:"
msgid_plural "users received this badge:"
-msgstr[0] ""
+msgstr[0] "사용자가 다음의 배지를 받았습니다:"
#: skins/default/templates/badges.html:3 skins/default/templates/badges.html:5
-#, fuzzy
msgid "Badges"
-msgstr "Badges"
+msgstr "배지"
#: skins/default/templates/badges.html:7
msgid "Community gives you awards for your questions, answers and votes."
-msgstr ""
+msgstr "커뮤니티로부터 질문, 답변 및 투표에 대한 상을 받았습니다"
#: skins/default/templates/badges.html:8
-#, fuzzy, python-format
+#, python-format
msgid ""
"Below is the list of available badges and number \n"
" of times each type of badge has been awarded. Have ideas about fun \n"
"badges? Please, give us your <a href='%%(feedback_faq_url)s'>feedback</a>\n"
-msgstr ""
-"Below is the list of available badges and number \n"
-" of times each type of badge has been awarded. Have ideas about fun "
-"badges? Please, give us your <a href='%(feedback_faq_url)s'>feedback</a>"
+msgstr "다음은 사용 가능한 배지와 각 종류별로 배지를 \n 수여할 수 있는 숫자에 대한 목록입니다. 재미있는 배지에 대한 \n아이디어가 있으신가요? 저희에게 <a href='%%(feedback_faq_url)s'>피드백</a>을 주세요\n"
#: skins/default/templates/badges.html:36
msgid "Community badges"
-msgstr "Badge levels"
+msgstr "배지 레벨"
#: skins/default/templates/badges.html:38
msgid "gold badge: the highest honor and is very rare"
-msgstr ""
+msgstr "금 배지: 최고의 영예로서 매우 드뭄"
#: skins/default/templates/badges.html:41
msgid ""
-"Gold badge is the highest award in this community. To obtain it have to "
-"show \n"
+"Gold badge is the highest award in this community. To obtain it have to show \n"
"profound knowledge and ability in addition to your active participation."
-msgstr ""
+msgstr "금 배지는 커뮤니티내에서 가장 높은 상입니다. 그것을 취득하려면 활발한 참여와 더불어 깊은 지식과 능력을 보여주셔야 합니다."
#: skins/default/templates/badges.html:47
msgid ""
"silver badge: occasionally awarded for the very high quality contributions"
-msgstr ""
+msgstr "은 배지: 높은 수준의 공헌에 대하여 가끔 포상"
#: skins/default/templates/badges.html:51
msgid ""
"msgid \"silver badge: occasionally awarded for the very high quality "
"contributions"
-msgstr ""
+msgstr "msgid \"은 배지: 높은 품질의 공헌에 대하여 종종 수여됨"
#: skins/default/templates/badges.html:54
#: skins/default/templates/badges.html:58
msgid "bronze badge: often given as a special honor"
-msgstr ""
+msgstr "동 배지: 특별한 영예로서 종종 주어짐"
#: skins/default/templates/close.html:3 skins/default/templates/close.html:5
-#, fuzzy
msgid "Close question"
-msgstr "Post Your Answer"
+msgstr "질문을 종료"
#: skins/default/templates/close.html:6
-#, fuzzy
msgid "Close the question"
-msgstr "Post Your Answer"
+msgstr "질문을 종료"
#: skins/default/templates/close.html:11
msgid "Reasons"
-msgstr ""
+msgstr "이유"
#: skins/default/templates/close.html:15
msgid "OK to close"
-msgstr ""
+msgstr "닫으려면 OK"
#: skins/default/templates/faq_static.html:3
#: skins/default/templates/faq_static.html:5
#: skins/default/templates/widgets/answer_edit_tips.html:20
#: skins/default/templates/widgets/question_edit_tips.html:16 views/meta.py:61
msgid "FAQ"
-msgstr ""
+msgstr "FAQ"
#: skins/default/templates/faq_static.html:5
-#, fuzzy
msgid "Frequently Asked Questions "
-msgstr "ask a question interesting to this community"
+msgstr "자주 나오는 질문들"
#: skins/default/templates/faq_static.html:6
msgid "What kinds of questions can I ask here?"
-msgstr ""
+msgstr "이곳에서는 어떤 질문을 할 수 있나요?"
#: skins/default/templates/faq_static.html:7
msgid ""
"Most importanly - questions should be <strong>relevant</strong> to this "
"community."
-msgstr ""
+msgstr "가장 중요한 점은, 질문은 이 커뮤니티에 <strong>적합</strong>해야한다는 것입니다."
#: skins/default/templates/faq_static.html:8
-#, fuzzy
msgid ""
"Before you ask - please make sure to search for a similar question. You can "
"search questions by their title or tags."
-msgstr ""
-"Before you ask - please make sure to search for a similar question. You can "
-"search questions by their title or tags."
+msgstr "질문하시기 전에 비슷한 질문이 있는지 확인해 주세요. 제목이나 태그를 이용하여 찾으실 수 있습니다."
#: skins/default/templates/faq_static.html:10
-#, fuzzy
msgid "What kinds of questions should be avoided?"
-msgstr "What kinds of questions should be avoided?"
+msgstr "어떤 종류의 질문을 피해야 하나요?"
#: skins/default/templates/faq_static.html:11
msgid ""
"Please avoid asking questions that are not relevant to this community, too "
"subjective and argumentative."
-msgstr ""
+msgstr "이 커뮤니티에 어울리지 않는 질문, 지나치게 주관적이거나 논쟁적인 질문은 삼가시기 바랍니다."
#: skins/default/templates/faq_static.html:13
-#, fuzzy
msgid "What should I avoid in my answers?"
-msgstr "What kinds of questions should be avoided?"
+msgstr "답변할 때 주의할 점에는 어떤 것이 있나요?"
#: skins/default/templates/faq_static.html:14
msgid ""
@@ -4586,34 +4433,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 "는 <strong>질문 답변</strong> 사이트입니다 - <strong>이곳은 토론 그룹</strong>이 아닙니다. 질문과 답변의 핵심을 흐리는 토론을 하는 것은 피해주시기 바랍니다. 간단한 토론을 위해서는 댓글 기능을 활용하시기 바랍니다."
#: skins/default/templates/faq_static.html:15
-#, fuzzy
msgid "Who moderates this community?"
-msgstr "post a comment"
+msgstr "이 커뮤니티는 누가 관리하나요?"
#: skins/default/templates/faq_static.html:16
msgid "The short answer is: <strong>you</strong>."
-msgstr ""
+msgstr "간단히 말하자면, <strong>여러분</strong>입니다."
#: skins/default/templates/faq_static.html:17
msgid "This website is moderated by the users."
-msgstr ""
+msgstr "이 웹사이트는 사용자에 의해 운영됩니다."
#: skins/default/templates/faq_static.html:18
-#, fuzzy
msgid ""
"Karma system allows users to earn rights to perform a variety of moderation "
"tasks"
-msgstr ""
-"Karma system allows users to earn rights to perform a variety of moderation "
-"tasks"
+msgstr "카르마 시스템은 사용자로 하여금 다양한 조정 업무를 할 수 있는 권한을 부여합니다"
#: skins/default/templates/faq_static.html:20
-#, fuzzy
msgid "How does karma system work?"
-msgstr "How does karma system work?"
+msgstr "카르마 시스템은 어떻게 동작 합니까?"
#: skins/default/templates/faq_static.html:21
msgid ""
@@ -4621,266 +4463,245 @@ 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 "질문이나 답변이 찬성표를 얻으면, 게시한 사용자는 점수를 얻으며, 이를 \\\"카르마 점수\\\"라고 부릅니다. 이러한 점수는 그 회원에 대한 커뮤니티의 신뢰를 대략적으로 나타냅니다. 이러한 점수에 따라서 회원에게 다양한 조정 작업이 할당됩니다."
#: skins/default/templates/faq_static.html:22
#, python-format
msgid ""
"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."
-msgstr ""
+"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."
+msgstr "예를 들어, 흥미로운 질문이나 유익한 답변을 하면, 여러분의 입력은 찬성표를 얻습니다. 반면 답변이 부실하다면 감점이 됩니다. 찬성표에는 <strong>%(REP_GAIN_FOR_RECEIVING_UPVOTE)s</strong> 점이 부여되며, 반대표에 대해서는 <strong>%(REP_LOSS_FOR_RECEIVING_DOWNVOTE)s</strong> 점이 감점됩니다. 질문 및 답변에 대하여 하루동안 얻을 수 있는 점수는 <strong>%(MAX_REP_GAIN_PER_USER_PER_DAY)s</strong> 점으로 제한됩니다. 아래의 표에 조정 활동의 유형에 따른 평판 점수가 설명되어 있습니다."
#: skins/default/templates/faq_static.html:32
#: skins/default/templates/user_profile/user_votes.html:13
-#, fuzzy
msgid "upvote"
-msgstr "votes"
+msgstr "찬성표"
#: skins/default/templates/faq_static.html:36
-#, fuzzy
msgid "add comments"
-msgstr "post a comment"
+msgstr "댓글 달기"
#: skins/default/templates/faq_static.html:40
#: skins/default/templates/user_profile/user_votes.html:15
-#, fuzzy
msgid "downvote"
-msgstr "votes"
+msgstr "비추천"
#: skins/default/templates/faq_static.html:43
-#, fuzzy
msgid " accept own answer to own questions"
-msgstr ""
-"<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!"
+msgstr "자신의 질문에 자신의 답변을 채택"
#: skins/default/templates/faq_static.html:47
-#, fuzzy
msgid "open and close own questions"
-msgstr "Post Your Answer"
+msgstr "자신의 질문을 시작 및 종료"
#: skins/default/templates/faq_static.html:51
-#, fuzzy
msgid "retag other's questions"
-msgstr "Post Your Answer"
+msgstr "다른 사람의 질문의 태그를 수정"
#: skins/default/templates/faq_static.html:56
-#, fuzzy
msgid "edit community wiki questions"
-msgstr "ask a question interesting to this community"
+msgstr "커뮤니티 위키 질문 편집"
#: skins/default/templates/faq_static.html:61
-#, fuzzy
msgid "edit any answer"
-msgstr "oldest"
+msgstr "답변을 편집"
#: skins/default/templates/faq_static.html:65
-#, fuzzy
msgid "delete any comment"
-msgstr "post a comment"
+msgstr "어떤 댓글이든 지움"
#: skins/default/templates/faq_static.html:69
msgid "How to change my picture (gravatar) and what is gravatar?"
-msgstr ""
+msgstr "어떻게 제 사진(그라바타)를 변경하며 그라바타는 무엇입니까?"
#: skins/default/templates/faq_static.html:70
msgid ""
"<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). "
+"<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>"
-msgstr ""
+msgstr "<p>사용자 프로필에 보이는 그림은 <strong>그라바타</strong>(<strong>g</strong>lobally <strong>r</strong>ecognized <strong>avatar</strong>라는 뜻)입니다.</p><p>원리는 이렇습니다. 이메일 주소로부터 <strong>암호화 키</strong>(깰 수 없는 코드)를 계산해냅니다. 여러분의 사진(또는 여러분을 나타내는 좋아하는 이미지)을 웹사이트<a href='http://gravatar.com'><strong>gravatar.com</strong></a>에 업로드하시면 우리가 키를 이용하여 그 이미지를 얻어오게 됩니다.</p><p>이러한 방법으로 여러분이 신뢰하는 웹사이트에서는 여러분의 이메일 주소를 공개하지 않으면서도 게시글 옆에 이미지를 보여줄 수 있습니다.</p><p>이미지로 <strong>여러분의 계정을 개인화하세요.</strong><a href='http://gravatar.com'><strong>gravatar.com</strong></a>에서 등록만 하시면 됩니다(등록할 때 사용한 이메일과 동일한 주소를 사용하세요). 부엌 타일처럼 생긴 기본 이미지는 자동으로 생성된 것입니다.</p>"
#: skins/default/templates/faq_static.html:71
msgid "To register, do I need to create new password?"
-msgstr ""
+msgstr "등록하려면 새로운 비밀번호를 생성해야 하나요?"
#: skins/default/templates/faq_static.html:72
msgid ""
"No, you don't have to. You can login through any service that supports "
"OpenID, e.g. Google, Yahoo, AOL, etc.\""
-msgstr ""
+msgstr "꼭 그럴 필요는 없습니다. 구글, 야후, AOL 등과 같이 OpenID를 지원하는 서비스를 통하여 로그인하실 수 있습니다."
#: skins/default/templates/faq_static.html:73
-#, fuzzy
msgid "\"Login now!\""
-msgstr "Logout Now"
+msgstr "\"지금 로그인!\""
#: skins/default/templates/faq_static.html:75
msgid "Why other people can edit my questions/answers?"
-msgstr ""
+msgstr "어째서 다른 사람들이 내 질문/답변을 수정할 수 있는 건가요?"
#: skins/default/templates/faq_static.html:76
msgid "Goal of this site is..."
-msgstr ""
+msgstr "이 사이트의 목표는, "
#: skins/default/templates/faq_static.html:76
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 "위키 페이지처럼 사용자들이 질문과 답변을 수정할 수 있도록 함으로써 지식 기반의 전체적인 품질을 향상시키는 것입니다."
#: skins/default/templates/faq_static.html:77
msgid "If this approach is not for you, we respect your choice."
-msgstr ""
+msgstr "이러한 방식이 마음에 들지 않는다면, 다른 선택을 하시는 것은 존중합니다."
#: skins/default/templates/faq_static.html:79
-#, fuzzy
msgid "Still have questions?"
-msgstr "Post Your Answer"
+msgstr "다른 질문이 있으신가요?"
#: skins/default/templates/faq_static.html:80
-#, fuzzy, python-format
+#, python-format
msgid ""
"Please <a href='%%(ask_question_url)s'>ask</a> your question, help make our "
"community better!"
-msgstr ""
-"Please <a href='%(ask_question_url)s'>ask</a> your question, help make our "
-"community better!"
+msgstr "<a href='%%(ask_question_url)s'>질문</a>을 통하여 이 커뮤니티를 더 발전시켜 주세요!"
#: skins/default/templates/feedback.html:3
msgid "Feedback"
-msgstr ""
+msgstr "피드백"
#: skins/default/templates/feedback.html:5
msgid "Give us your feedback!"
-msgstr ""
+msgstr "피드백을 주세요!"
#: skins/default/templates/feedback.html:14
#, python-format
msgid ""
"\n"
-" <span class='big strong'>Dear %(user_name)s</span>, we look forward "
-"to hearing your feedback. \n"
+" <span class='big strong'>Dear %(user_name)s</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'>%(user_name)s</span>님, 피드백을 들려주세요. \n 아래에 메시지를 입력해서 보내주세요.\n "
#: skins/default/templates/feedback.html:21
msgid ""
"\n"
-" <span class='big strong'>Dear visitor</span>, we look forward to "
-"hearing your feedback.\n"
+" <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 "
#: skins/default/templates/feedback.html:30
msgid "(to hear from us please enter a valid email or check the box below)"
-msgstr ""
+msgstr "(소식을 받아보시려면 유효한 이메일을 입력하시거나 아래의 박스를 체크하세요)"
#: skins/default/templates/feedback.html:37
#: skins/default/templates/feedback.html:46
msgid "(this field is required)"
-msgstr ""
+msgstr "(필수)"
#: skins/default/templates/feedback.html:55
msgid "(Please solve the captcha)"
-msgstr ""
+msgstr "(캡차를 풀어주세요)"
#: skins/default/templates/feedback.html:63
msgid "Send Feedback"
-msgstr ""
+msgstr "피드백을 보내기"
#: skins/default/templates/feedback_email.txt:2
#, python-format
msgid ""
"\n"
"Hello, this is a %(site_title)s forum feedback message.\n"
-msgstr ""
+msgstr "\n안녕하세요, 이것은 %(site_title)s 포럼 피드백 메시지입니다.\n"
#: skins/default/templates/help.html:2 skins/default/templates/help.html:4
msgid "Help"
-msgstr ""
+msgstr "도움말"
#: skins/default/templates/help.html:7
-#, fuzzy, python-format
+#, python-format
msgid "Welcome %(username)s,"
-msgstr "Choose screen name"
+msgstr "%(username)s님 환영합니다,"
#: skins/default/templates/help.html:9
msgid "Welcome,"
-msgstr ""
+msgstr "환영합니다,"
#: skins/default/templates/help.html:13
#, python-format
msgid "Thank you for using %(app_name)s, here is how it works."
-msgstr ""
+msgstr "%(app_name)s에 방문해주셔서 고맙습니다. 이곳은 다음과 같이 운영됩니다."
#: skins/default/templates/help.html:16
msgid ""
"This site is for asking and answering questions, not for open-ended "
"discussions."
-msgstr ""
+msgstr "이 사이트는 꼬리에 꼬리를 무는 토론보다는, 질문과 답변을 하기 위한 곳입니다."
#: skins/default/templates/help.html:17
msgid ""
"We encourage everyone to use “question” space for asking and “answer” for "
"answering."
-msgstr ""
+msgstr "우리는 모든 이가 \"질문\" 란에 질문하고 \"답변\" 란에 답변하기를 권장합니다."
#: skins/default/templates/help.html:20
msgid ""
"Despite that, each question and answer can be commented – \n"
" the comments are good for the limited discussions."
-msgstr ""
+msgstr "그렇지만 각각의 질문과 답변에 댓글을 다실 수는 있으며, 제한적인 토론에는 댓글이 유용합니다."
#: skins/default/templates/help.html:24
#, python-format
msgid ""
"Voting in %(app_name)s helps to select best answers and thank most helpful "
"users."
-msgstr ""
+msgstr " %(app_name)s 에서 투표는 으뜸가는 답변과 가장 도움을 준 사용자에게 감사를 표하는데 도움이 됩니다."
#: skins/default/templates/help.html:26
#, python-format
msgid ""
"Please vote when you find helpful information,\n"
" it really helps the %(app_name)s community."
-msgstr ""
+msgstr "도움이 되는 정보를 찾았을 때 투표해주시기 바랍니다, 이는 %(app_name)s 커뮤니티에 큰 도움이 됩니다."
#: skins/default/templates/help.html:29
msgid ""
-"Besides, 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 ""
+"Besides, 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 "게다가 텍스트의 어느 부분에서든 사용자를 @언급하여 그들의 주의를 끌 수 있으며, 사용자를 팔로우한다거나 부적절한 내용에 대하여 표시를 함으로서 신고할 수 있습니다."
#: skins/default/templates/help.html:32
msgid "Enjoy."
-msgstr ""
+msgstr "즐기세요."
#: skins/default/templates/import_data.html:2
#: skins/default/templates/import_data.html:4
msgid "Import StackExchange data"
-msgstr ""
+msgstr "StackExchange의 데이타를 가져오기"
#: skins/default/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>경고:</em> 만약 데이터베이스가 비어있지 않다면 이 기능을\n사용하기 전에 백업을 꼭 하시기 바랍니다."
#: skins/default/templates/import_data.html:16
msgid ""
@@ -4888,39 +4709,36 @@ 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 "stackexchange 덤프 .zip 파일을 업로드한 다음, 데이터\n 가져오기가 완료될 때까지 기다리세요. 이 과정에 몇 분이 걸립니다.\n 피드백이 일반 텍스트로 출력됨에 유의하세요.\n "
#: skins/default/templates/import_data.html:25
msgid "Import data"
-msgstr ""
+msgstr "데이타 가져오기"
#: skins/default/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 ""
+" please try importing your data via command line: <code>python manage.py load_stackexchange path/to/your-data.zip</code>"
+msgstr "이 임포트 도구를 사용하는 데에 어려움을 겪으신다면,\n 명령행을 통해 데이터를 임포트해보시기 바랍니다: <code>python manage.py load_stackexchange path/to/your-data.zip</code>"
#: skins/default/templates/instant_notification.html:1
#, python-format
msgid "<p>Dear %(receiving_user_name)s,</p>"
-msgstr ""
+msgstr "<p>%(receiving_user_name)s님,</p>"
#: skins/default/templates/instant_notification.html:3
#, python-format
msgid ""
"\n"
-"<p>%(update_author_name)s left a <a href=\"%(post_url)s\">new comment</a>:</"
-"p>\n"
-msgstr ""
+"<p>%(update_author_name)s left a <a href=\"%(post_url)s\">new comment</a>:</p>\n"
+msgstr "\n<p>%(update_author_name)s 님이 <a href=\"%(post_url)s\">새로운 댓글</a>을 남겼습니다:</p>\n"
#: skins/default/templates/instant_notification.html:8
#, python-format
msgid ""
"\n"
-"<p>%(update_author_name)s left a <a href=\"%(post_url)s\">new comment</a></"
-"p>\n"
-msgstr ""
+"<p>%(update_author_name)s left a <a href=\"%(post_url)s\">new comment</a></p>\n"
+msgstr "\n<p>%(update_author_name)s 님이 <a href=\"%(post_url)s\">새로운 댓글</a>을 남겼습니다</p>\n"
#: skins/default/templates/instant_notification.html:13
#, python-format
@@ -4928,7 +4746,7 @@ msgid ""
"\n"
"<p>%(update_author_name)s answered a question \n"
"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
-msgstr ""
+msgstr "\n<p>%(update_author_name)s 님이 질문\n<a href=\"%(post_url)s\">%(origin_post_title)s</a>에 답변했습니다</p>\n"
#: skins/default/templates/instant_notification.html:19
#, python-format
@@ -4936,7 +4754,7 @@ msgid ""
"\n"
"<p>%(update_author_name)s posted a new question \n"
"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
-msgstr ""
+msgstr "\n<p>%(update_author_name)s 님이 새로운 질문 \n<a href=\"%(post_url)s\">%(origin_post_title)s</a>을 게시했습니다</p>\n"
#: skins/default/templates/instant_notification.html:25
#, python-format
@@ -4944,7 +4762,7 @@ msgid ""
"\n"
"<p>%(update_author_name)s updated an answer to the question\n"
"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
-msgstr ""
+msgstr "\n<p>%(update_author_name)s 님이 질문\n<a href=\"%(post_url)s\">%(origin_post_title)s</a>에 대한 답변을 수정했습니다</p>\n"
#: skins/default/templates/instant_notification.html:31
#, python-format
@@ -4952,332 +4770,300 @@ msgid ""
"\n"
"<p>%(update_author_name)s updated a question \n"
"<a href=\"%(post_url)s\">%(origin_post_title)s</a></p>\n"
-msgstr ""
+msgstr "\n<p>%(update_author_name)s 님이 질문\n<a href=\"%(post_url)s\">%(origin_post_title)s</a>을 수정했습니다</p>\n"
#: skins/default/templates/instant_notification.html:37
#, python-format
msgid ""
"\n"
"<div>%(content_preview)s</div>\n"
-"<p>Please note - you can easily <a href=\"%(user_subscriptions_url)s"
-"\">change</a>\n"
-"how often you receive these notifications or unsubscribe. Thank you for your "
-"interest in our forum!</p>\n"
-msgstr ""
+"<p>Please note - you can easily <a href=\"%(user_subscriptions_url)s\">change</a>\n"
+"how often you receive these notifications or unsubscribe. Thank you for your interest in our forum!</p>\n"
+msgstr "\n<div>%(content_preview)s</div>\n<p>알림 수신 여부와 얼마나 자주 받을 지를 쉽게 <a href=\"%(user_subscriptions_url)s\">변경</a>할 수 있음에 유의하시기 바랍니다.\n포럼에 관심을 가져주셔서 고맙습니다!</p>\n"
#: skins/default/templates/instant_notification.html:42
-#, fuzzy
msgid "<p>Sincerely,<br/>Forum Administrator</p>"
-msgstr ""
-"Sincerely,\n"
-"Q&A Forum Administrator"
+msgstr "<p><br>포럼 관리자</br>로부터</p>"
#: skins/default/templates/instant_notification_reply_by_email.html:3
msgid ""
"\n"
"\n"
"======= Reply above this line. ====-=-=\n"
-msgstr ""
+msgstr "\n\n======= 이 선 위로 답변. ====-=-=\n"
#: skins/default/templates/instant_notification_reply_by_email.html:8
#, python-format
msgid ""
"\n"
-"You can post an answer or a comment by replying to email notifications. To "
-"do that\n"
-"you need %(reply_by_email_karma_threshold)s karma, you have "
-"%(receiving_user_karma)s karma. \n"
-msgstr ""
+"You can post an answer or a comment by replying to email notifications. To do that\n"
+"you need %(reply_by_email_karma_threshold)s karma, you have %(receiving_user_karma)s karma. \n"
+msgstr "\n이메일 알림에 답장을 보냄으로써 답변 및 댓글을 게시할 수 있습니다. 그렇게 하기 위해서는 %(reply_by_email_karma_threshold)s 카르마가 필요하며, %(receiving_user_karma)s 카르마를 가집니다. \n"
#: skins/default/templates/macros.html:5
#, python-format
msgid "Share this question on %(site)s"
-msgstr ""
+msgstr "이 질문을 %(site)s에서 공유하기"
#: skins/default/templates/macros.html:16
#: skins/default/templates/macros.html:436
#, python-format
msgid "follow %(alias)s"
-msgstr ""
+msgstr "%(alias)s 를 팔로우"
#: skins/default/templates/macros.html:19
#: skins/default/templates/macros.html:439
#, python-format
msgid "unfollow %(alias)s"
-msgstr ""
+msgstr "%(alias)s 를 언팔로우"
#: skins/default/templates/macros.html:20
#: skins/default/templates/macros.html:440
#, python-format
msgid "following %(alias)s"
-msgstr ""
+msgstr "%(alias)s 를 팔로우중"
#: skins/default/templates/macros.html:33
msgid "current number of votes"
-msgstr ""
+msgstr "현재 총 투표수"
#: skins/default/templates/macros.html:46
-#, fuzzy
msgid "anonymous user"
-msgstr "Sorry, anonymous users cannot vote"
+msgstr "익명의 사용자"
#: skins/default/templates/macros.html:79
msgid "this post is marked as community wiki"
-msgstr ""
+msgstr "이 게시물은 커뮤니티 위키로 표시되었습니다"
#: skins/default/templates/macros.html:82
#, python-format
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 이상이면 가능)"
#: skins/default/templates/macros.html:88
msgid "asked"
-msgstr ""
+msgstr "질문"
#: skins/default/templates/macros.html:90
-#, fuzzy
msgid "answered"
-msgstr "oldest"
+msgstr "답변"
#: skins/default/templates/macros.html:92
msgid "posted"
-msgstr ""
+msgstr "게시"
#: skins/default/templates/macros.html:122
-#, fuzzy
msgid "updated"
-msgstr "Last updated"
+msgstr "수정"
#: skins/default/templates/macros.html:202
-#, fuzzy, python-format
+#, python-format
msgid "see questions tagged '%(tag)s'"
-msgstr "Asked"
+msgstr "'%(tag)s 로 태그된 질문들 보기"
#: skins/default/templates/macros.html:304
-#, fuzzy
msgid "delete this comment"
-msgstr "post a comment"
+msgstr "이 댓글을 삭제"
#: skins/default/templates/macros.html:507 templatetags/extra_tags.py:43
#, python-format
msgid "%(username)s gravatar image"
-msgstr ""
+msgstr "%(username)s의 그라바타 이미지"
#: skins/default/templates/macros.html:516
-#, fuzzy, python-format
+#, python-format
msgid "%(username)s's website is %(url)s"
-msgstr "User login"
+msgstr "%(username)s의 웹사이트는 %(url)s입니다"
#: skins/default/templates/macros.html:531
#: skins/default/templates/macros.html:532
#: skins/default/templates/macros.html:570
#: skins/default/templates/macros.html:571
msgid "previous"
-msgstr ""
+msgstr "이전"
#: skins/default/templates/macros.html:543
#: skins/default/templates/macros.html:582
msgid "current page"
-msgstr ""
+msgstr "현재 페이지"
#: skins/default/templates/macros.html:545
#: skins/default/templates/macros.html:552
#: skins/default/templates/macros.html:584
#: skins/default/templates/macros.html:591
-#, fuzzy, python-format
+#, python-format
msgid "page %(num)s"
-msgstr "page %(num)s"
+msgstr "%(num)s 페이지"
#: skins/default/templates/macros.html:556
#: skins/default/templates/macros.html:595
msgid "next page"
-msgstr ""
+msgstr "다음 페이지"
#: skins/default/templates/macros.html:607
-#, fuzzy, python-format
+#, python-format
msgid "responses for %(username)s"
-msgstr "Choose screen name"
+msgstr "%(username)s의 응답"
#: skins/default/templates/macros.html:610
#, python-format
msgid "you have %(response_count)s new response"
msgid_plural "you have %(response_count)s new responses"
-msgstr[0] ""
+msgstr[0] "%(response_count)s 개의 새로운 응답이 있습니다"
#: skins/default/templates/macros.html:613
msgid "no new responses yet"
-msgstr ""
+msgstr "아직 새로운 반응들이 없습니다"
#: skins/default/templates/macros.html:628
#: skins/default/templates/macros.html:629
#, python-format
msgid "%(new)s new flagged posts and %(seen)s previous"
-msgstr ""
+msgstr "%(new)s 새로 신고된 게시물 및 %(seen)s 이전"
#: skins/default/templates/macros.html:631
#: skins/default/templates/macros.html:632
#, python-format
msgid "%(new)s new flagged posts"
-msgstr ""
+msgstr "%(new)s 새로 신고된 게시물"
#: skins/default/templates/macros.html:637
#: skins/default/templates/macros.html:638
#, python-format
msgid "%(seen)s flagged posts"
-msgstr ""
+msgstr "%(seen)s 신고된 게시물"
#: skins/default/templates/main_page.html:11
-#, fuzzy
msgid "Questions"
-msgstr "Tags"
+msgstr "질문들"
#: skins/default/templates/question.html:110
msgid "post a comment / <strong>some</strong> more"
-msgstr ""
+msgstr "댓글 달기 / <strong>조금</strong> 더"
#: skins/default/templates/question.html:113
msgid "see <strong>some</strong> more"
-msgstr ""
+msgstr "<strong>더 보기</strong>"
#: skins/default/templates/question.html:117
#: skins/default/templates/question/javascript.html:20
-#, fuzzy
msgid "post a comment"
-msgstr "post a comment"
+msgstr "댓글 달기"
#: skins/default/templates/question.html:135
#: skins/default/templates/question/content.html:40
-#, fuzzy
msgid "Answer Your Own Question"
-msgstr "Post Your Answer"
+msgstr "자신의 질문에 답변"
#: skins/default/templates/question.html:140
-#, fuzzy
msgid "Post Your Answer"
-msgstr "most voted"
+msgstr "답변하기"
#: skins/default/templates/question.html:146
#: skins/default/templates/widgets/ask_form.html:41
-#, fuzzy
msgid "Login/Signup to Post"
-msgstr "Login/Signup to Post"
+msgstr "글 작성을 위해 로그인/가입"
#: skins/default/templates/question_edit.html:4
#: skins/default/templates/question_edit.html:9
-#, fuzzy
msgid "Edit question"
-msgstr "Post Your Answer"
+msgstr "질문을 편집"
#: skins/default/templates/question_retag.html:3
#: skins/default/templates/question_retag.html:5
-#, fuzzy
msgid "Retag question"
-msgstr "ask a question interesting to this community"
+msgstr "질문의 태그 수정"
#: skins/default/templates/question_retag.html:21
msgid "Retag"
-msgstr ""
+msgstr "태그 수정"
#: skins/default/templates/question_retag.html:28
msgid "Why use and modify tags?"
-msgstr ""
+msgstr "왜 태그를 사용하거나 수정하나요?"
#: skins/default/templates/question_retag.html:30
msgid "Tags help to keep the content better organized and searchable"
-msgstr ""
+msgstr "태그를 사용하여 컨텐츠를 보다 잘 관리하고 찾기 쉽도록 할 수 있습니다"
#: skins/default/templates/question_retag.html:32
msgid "tag editors receive special awards from the community"
-msgstr ""
+msgstr "태그 편집자들은 커뮤니티로부터 특별한 포상을 받습니다"
#: skins/default/templates/question_retag.html:59
msgid "up to 5 tags, less than 20 characters each"
-msgstr ""
+msgstr "5 태그까지, 각각 20 자까지"
#: skins/default/templates/reopen.html:3 skins/default/templates/reopen.html:5
-#, fuzzy
msgid "Reopen question"
-msgstr "Post Your Answer"
+msgstr "다시 열린 질문"
#: skins/default/templates/reopen.html:6
msgid "Title"
-msgstr ""
+msgstr "제목"
#: skins/default/templates/reopen.html:11
#, python-format
msgid ""
"This question has been closed by \n"
" <a href=\"%(closed_by_profile_url)s\">%(closed_by_username)s</a>\n"
-msgstr ""
+msgstr "이 질문은 <a href=\"%(closed_by_profile_url)s\">%(closed_by_username)s</a>에 의하여 종료되었습니다\n"
#: skins/default/templates/reopen.html:16
-#, fuzzy
msgid "Close reason:"
-msgstr "Post Your Answer"
+msgstr "종료 이유:"
#: skins/default/templates/reopen.html:19
msgid "When:"
-msgstr ""
+msgstr "언제:"
#: skins/default/templates/reopen.html:22
-#, fuzzy
msgid "Reopen this question?"
-msgstr "Post Your Answer"
+msgstr "이 질문을 재개할까요?"
#: skins/default/templates/reopen.html:26
-#, fuzzy
msgid "Reopen this question"
-msgstr "Post Your Answer"
+msgstr "이 질문을 재개"
#: skins/default/templates/reply_by_email_error.html:1
msgid ""
"\n"
-"<p>The system was unable to process your message successfully, the reason "
-"being:<p>\n"
-msgstr ""
+"<p>The system was unable to process your message successfully, the reason being:<p>\n"
+msgstr "\n<p>이 시스템은 당신의 메시지를 올바로 처리할 수 없습니다. 이유:<p>\n"
#: skins/default/templates/revisions.html:4
#: skins/default/templates/revisions.html:7
-#, fuzzy
msgid "Revision history"
-msgstr "karma history"
+msgstr "리비전 이력"
#: skins/default/templates/revisions.html:23
-#, fuzzy
msgid "click to hide/show revision"
-msgstr ""
-"<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."
+msgstr "클릭하여 리비전 숨기기/보기"
#: skins/default/templates/revisions.html:29
#, python-format
msgid "revision %(number)s"
-msgstr ""
+msgstr "리비전 %(number)s"
#: skins/default/templates/subscribe_for_tags.html:3
#: skins/default/templates/subscribe_for_tags.html:5
-#, fuzzy
msgid "Subscribe for tags"
-msgstr "Tags"
+msgstr "태그 구독하기"
#: skins/default/templates/subscribe_for_tags.html:6
msgid "Please, subscribe for the following tags:"
-msgstr ""
+msgstr "다음의 태그를 구독해주세요:"
#: skins/default/templates/subscribe_for_tags.html:15
-#, fuzzy
msgid "Subscribe"
-msgstr "Tags"
+msgstr "구독"
#: skins/default/templates/tags.html:8
#, python-format
msgid "Tags, matching \"%(stag)s\""
-msgstr ""
+msgstr "태그들, \"%(stag)s\" 일치"
#: skins/default/templates/tags.html:10
msgid "Tag list"
@@ -5286,221 +5072,197 @@ msgstr "Tags"
#: skins/default/templates/tags.html:14 skins/default/templates/users.html:9
#: skins/default/templates/main_page/tab_bar.html:15
msgid "Sort by &raquo;"
-msgstr ""
+msgstr "정렬 기준 &raquo;"
#: skins/default/templates/tags.html:19
msgid "sorted alphabetically"
-msgstr ""
+msgstr "알파벳순 정렬"
#: skins/default/templates/tags.html:20
msgid "by name"
-msgstr ""
+msgstr "이름으로"
#: skins/default/templates/tags.html:25
msgid "sorted by frequency of tag use"
-msgstr ""
+msgstr "태그 사용빈도에 따라 정렬"
#: skins/default/templates/tags.html:26
msgid "by popularity"
-msgstr ""
+msgstr "인기순"
#: skins/default/templates/tags.html:31 skins/default/templates/tags.html:56
msgid "Nothing found"
-msgstr ""
+msgstr "아무 것도 찾을 수 없음"
#: skins/default/templates/users.html:4 skins/default/templates/users.html:6
msgid "Users"
-msgstr "People"
+msgstr "사람들"
#: skins/default/templates/users.html:14
msgid "see people with the highest reputation"
-msgstr ""
+msgstr "가장 높은 평판을 얻은 사람들"
#: skins/default/templates/users.html:15
#: skins/default/templates/user_profile/user_info.html:25
#: skins/default/templates/user_profile/user_reputation.html:4
#: skins/default/templates/user_profile/user_tabs.html:23
msgid "karma"
-msgstr ""
+msgstr "카르마"
#: skins/default/templates/users.html:20
msgid "see people who joined most recently"
-msgstr ""
+msgstr "최근에 가입한 사람들 보기"
#: skins/default/templates/users.html:21
msgid "recent"
-msgstr ""
+msgstr "최근"
#: skins/default/templates/users.html:26
msgid "see people who joined the site first"
-msgstr ""
+msgstr "사이트에 처음 가입한 사람들 보기"
#: skins/default/templates/users.html:32
msgid "see people sorted by name"
-msgstr ""
+msgstr "사람들을 이름 순으로 보기"
#: skins/default/templates/users.html:33
-#, fuzzy
msgid "by username"
-msgstr "Choose screen name"
+msgstr "사용자명"
#: skins/default/templates/users.html:39
#, python-format
msgid "users matching query %(suser)s:"
-msgstr ""
+msgstr "%(suser)s 질의에 일치하는 사용자:"
#: skins/default/templates/users.html:42
msgid "Nothing found."
-msgstr ""
+msgstr "아무 것도 찾지 못함."
#: skins/default/templates/main_page/headline.html:4 views/readers.py:135
#, python-format
msgid "%(q_num)s question"
msgid_plural "%(q_num)s questions"
-msgstr[0] ""
+msgstr[0] "%(q_num)s 개의 질문"
#: skins/default/templates/main_page/headline.html:6
#, python-format
msgid "with %(author_name)s's contributions"
-msgstr ""
+msgstr "%(author_name)s 님의 공헌"
#: skins/default/templates/main_page/headline.html:12
msgid "Tagged"
-msgstr ""
+msgstr "태그 달림"
#: skins/default/templates/main_page/headline.html:24
-#, fuzzy
msgid "Search tips:"
-msgstr "Tips"
+msgstr "검색 도움말:"
#: skins/default/templates/main_page/headline.html:27
-#, fuzzy
msgid "reset author"
-msgstr "Tags"
+msgstr "작성자 리셋"
#: skins/default/templates/main_page/headline.html:29
#: skins/default/templates/main_page/headline.html:32
#: skins/default/templates/main_page/nothing_found.html:18
#: skins/default/templates/main_page/nothing_found.html:21
msgid " or "
-msgstr ""
+msgstr " 또는 "
#: skins/default/templates/main_page/headline.html:30
-#, fuzzy
msgid "reset tags"
-msgstr "Tags"
+msgstr "태그 리셋"
#: skins/default/templates/main_page/headline.html:33
#: skins/default/templates/main_page/headline.html:36
msgid "start over"
-msgstr ""
+msgstr "새로 찾기"
#: skins/default/templates/main_page/headline.html:38
msgid " - to expand, or dig in by adding more tags and revising the query."
-msgstr ""
+msgstr " - 태그를 추가하거나 질의를 개정함으로써 확장하거나 파헤치기 위하여 "
#: skins/default/templates/main_page/headline.html:41
-#, fuzzy
msgid "Search tip:"
-msgstr "Tips"
+msgstr "검색 도움말:"
#: skins/default/templates/main_page/headline.html:41
msgid "add tags and a query to focus your search"
-msgstr ""
+msgstr "질문에 태그를 붙이고 검색하세요"
#: skins/default/templates/main_page/nothing_found.html:4
-#, fuzzy
msgid "There are no unanswered questions here"
-msgstr ""
-"<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!"
+msgstr "답변되지 않은 질문이 없습니다"
#: skins/default/templates/main_page/nothing_found.html:7
-#, fuzzy
msgid "No questions here. "
-msgstr "answered question"
+msgstr "즐겨찾는 질문이 없습니다."
#: skins/default/templates/main_page/nothing_found.html:8
msgid "Please follow some questions or follow some users."
-msgstr ""
+msgstr "질문 또는 사용자를 팔로우해주세요"
#: skins/default/templates/main_page/nothing_found.html:13
msgid "You can expand your search by "
-msgstr ""
+msgstr "검색 범위를 확장하시려면"
#: skins/default/templates/main_page/nothing_found.html:16
-#, fuzzy
msgid "resetting author"
-msgstr "Tags"
+msgstr "작성자 리셋"
#: skins/default/templates/main_page/nothing_found.html:19
-#, fuzzy
msgid "resetting tags"
-msgstr "Tags"
+msgstr "태그 리셋"
#: skins/default/templates/main_page/nothing_found.html:22
#: skins/default/templates/main_page/nothing_found.html:25
-#, fuzzy
msgid "starting over"
-msgstr "Tags"
+msgstr "처음부터 시작"
#: skins/default/templates/main_page/nothing_found.html:30
-#, fuzzy
msgid "Please always feel free to ask your question!"
-msgstr ""
-"<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."
+msgstr "항상 편안하게 질문하세요!"
#: skins/default/templates/main_page/questions_loop.html:11
msgid "Did not find what you were looking for?"
-msgstr ""
+msgstr "원하는 것을 찾지 못하셨나요?"
#: skins/default/templates/main_page/questions_loop.html:12
-#, fuzzy
msgid "Please, post your question!"
-msgstr "Ask Your Question"
+msgstr "질문을 올려주세요!"
#: skins/default/templates/main_page/tab_bar.html:10
-#, fuzzy
msgid "subscribe to the questions feed"
-msgstr "Post Your Answer"
+msgstr "질문 피드 구독"
#: skins/default/templates/main_page/tab_bar.html:11
msgid "RSS"
-msgstr ""
+msgstr "RSS"
#: skins/default/templates/meta/bottom_scripts.html:7
#, python-format
msgid ""
"Please note: %(app_name)s requires javascript to work properly, please "
-"enable javascript in your browser, <a href=\"%(noscript_url)s\">here is how</"
-"a>"
-msgstr ""
+"enable javascript in your browser, <a href=\"%(noscript_url)s\">here is "
+"how</a>"
+msgstr "주의: %(app_name)s은 올바로 동작하기 위해 자바스크립트를 필요로 하므로, 사용하시는 브라우저에서 자바스크립트를 사용하도록 설정해주세요. <a href=\"%(noscript_url)s\">방법</a>"
#: skins/default/templates/meta/editor_data.html:7
#, 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] ""
+msgstr[0] "각각의 태그는 %(max_chars)s 자 미만이어야 합니다"
#: skins/default/templates/meta/editor_data.html:9
#, python-format
msgid "please use %(tag_count)s tag"
msgid_plural "please use %(tag_count)s tags or less"
-msgstr[0] ""
+msgstr[0] "%(tag_count)s 개 이하의 태그를 사용해주세요"
#: skins/default/templates/meta/editor_data.html:10
#, 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 자 미만으로 사용해주세요"
#: skins/default/templates/question/answer_tab_bar.html:3
#, python-format
@@ -5512,998 +5274,884 @@ msgid_plural ""
"\n"
" %(counter)s Answers\n"
" "
-msgstr[0] ""
+msgstr[0] "\n %(counter)s 답변\n "
#: skins/default/templates/question/answer_tab_bar.html:11
msgid "Sort by »"
-msgstr ""
+msgstr "정렬 기준 »"
#: skins/default/templates/question/answer_tab_bar.html:14
msgid "oldest answers will be shown first"
-msgstr ""
+msgstr "가장 오래된 답변이 처음 보여짐"
#: skins/default/templates/question/answer_tab_bar.html:17
msgid "newest answers will be shown first"
-msgstr ""
+msgstr "새로운 질문이 처음 보여짐"
#: skins/default/templates/question/answer_tab_bar.html:20
msgid "most voted answers will be shown first"
-msgstr ""
+msgstr "투표가 많은 질문이 처음 보여짐"
#: skins/default/templates/question/new_answer_form.html:16
-#, fuzzy
msgid "Login/Signup to Answer"
-msgstr "Login/Signup to Post"
+msgstr "로그인/답변을 위해 새로 참여."
#: skins/default/templates/question/new_answer_form.html:24
-#, fuzzy
msgid "Your answer"
-msgstr "most voted"
+msgstr "여러분의 답변"
#: skins/default/templates/question/new_answer_form.html:26
-#, fuzzy
msgid "Be the first one to answer this question!"
-msgstr ""
-"<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!"
+msgstr "이 질문에 첫 답변자가 되세요!"
#: skins/default/templates/question/new_answer_form.html:32
msgid ""
-"<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 "
+"<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)!"
-msgstr ""
+msgstr "<span class='strong big'>익명으로 답변을 시작하시기 바랍니다</span> - 작성하신 답변은 현재 세션 내에 저장되며 로그인 하거나 새 계정을 만들고 나서 발행됩니다. <strong>실질적인 답변</strong>을 줄수 있도록 해주시고 토론을 위해서는 <strong>댓글을 사용</strong>하시기 바랍니다. 그리고 <strong>투표하는것 잊지 마세요</strong>(로그인 한 다음에!)"
#: skins/default/templates/question/new_answer_form.html:36
msgid ""
-"<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 "
+"<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)!"
-msgstr ""
+msgstr "<span class='big strong'>자신의 질문에 답변하는 것을 환영합니다만</span>, <strong>답변</strong>을 하셔야 합니다. <strong>항상 원래의 질문을 개정</strong>할 수 있음을 기억하시기 바랍니다. <strong>토론을 위해서는 댓글을 사용</strong>하시고 좋아하는 질문에 대해서는(싫어하는 질문에 대해서도) <strong>투표를 잊지 마세요! :)</strong>"
#: skins/default/templates/question/new_answer_form.html:38
msgid ""
"<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!"
-msgstr ""
+"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!"
+msgstr "<span class='big strong'>실질적인 답변을 하도록 노력하시기 바랍니다</span>. 질문이나 답변에 첨언하고자 한다면 <strong>댓글 도구를 사용하세요</strong>. 항상 <strong>답변을 개정</strong>할 수 있음을 유념하세요 - 동일한 질문에 두번 답할 필요가 없습니다. 또한, <strong>투표를 잊지 마세요!</strong> - 으뜸가는 질문과 답변을 선택하는 데에 정말 도움이 됩니다!"
#: skins/default/templates/question/sharing_prompt_phrase.html:2
#, python-format
msgid ""
"Know someone who can answer? Share a <a href=\"%(question_url)s\">link</a> "
"to this question via"
-msgstr ""
+msgstr "답해줄 수 있는 사람을 아시나요? <a href=\"%(question_url)s\">이 질문</a>을 공유해주세요."
#: skins/default/templates/question/sharing_prompt_phrase.html:8
msgid " or"
-msgstr ""
+msgstr "또는"
#: skins/default/templates/question/sharing_prompt_phrase.html:10
-#, fuzzy
msgid "email"
-msgstr ""
-"<strong>Your Email</strong> (<i>must be valid, never shown to others</i>)"
+msgstr "이메일"
#: skins/default/templates/question/sidebar.html:6
-#, fuzzy
msgid "Question tools"
-msgstr "Tags"
+msgstr "질문 도구들"
#: skins/default/templates/question/sidebar.html:9
-#, fuzzy
msgid "click to unfollow this question"
-msgstr ""
-"<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."
+msgstr "이 질문을 언팔로우하기 위해 클릭하세요"
#: skins/default/templates/question/sidebar.html:10
msgid "Following"
-msgstr ""
+msgstr "팔로잉"
#: skins/default/templates/question/sidebar.html:11
msgid "Unfollow"
-msgstr ""
+msgstr "언팔로우"
#: skins/default/templates/question/sidebar.html:15
-#, fuzzy
msgid "click to follow this question"
-msgstr ""
-"<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."
+msgstr "이 질문을 팔로우하기 위해 클릭하세요."
#: skins/default/templates/question/sidebar.html:16
msgid "Follow"
-msgstr ""
+msgstr "팔로우"
#: skins/default/templates/question/sidebar.html:23
#, python-format
msgid "%(count)s follower"
msgid_plural "%(count)s followers"
-msgstr[0] ""
+msgstr[0] "%(count)s 팔로워"
#: skins/default/templates/question/sidebar.html:29
-#, fuzzy
msgid "email the updates"
-msgstr "Last updated"
+msgstr "업데이트를 이메일로 구독"
#: skins/default/templates/question/sidebar.html:32
msgid ""
"<strong>Here</strong> (once you log in) you will be able to sign up for the "
"periodic email updates about this question."
-msgstr ""
+msgstr "<strong>여기에서</strong> (로그인 후에) 이 질문에 대한 소식을 이메일을 통해 주기적으로 받아보실 수 있습니다."
#: skins/default/templates/question/sidebar.html:37
-#, fuzzy
msgid "subscribe to this question rss feed"
-msgstr "Post Your Answer"
+msgstr "이 질문에 대한 rss 피드를 등록합니다"
#: skins/default/templates/question/sidebar.html:38
-#, fuzzy
msgid "subscribe to rss feed"
-msgstr "Post Your Answer"
+msgstr "rss 피드 등록"
#: skins/default/templates/question/sidebar.html:46
msgid "Stats"
-msgstr ""
+msgstr "통계"
#: skins/default/templates/question/sidebar.html:48
msgid "Asked"
-msgstr ""
+msgstr "질문"
#: skins/default/templates/question/sidebar.html:51
msgid "Seen"
-msgstr ""
+msgstr "읽음"
#: skins/default/templates/question/sidebar.html:51
msgid "times"
-msgstr ""
+msgstr "시간"
#: skins/default/templates/question/sidebar.html:54
-#, fuzzy
msgid "Last updated"
-msgstr "Last updated"
+msgstr "마지막 업데이트"
#: skins/default/templates/question/sidebar.html:62
-#, fuzzy
msgid "Related questions"
-msgstr "ask a question interesting to this community"
+msgstr "연관된 질문들"
#: skins/default/templates/question/subscribe_by_email_prompt.html:5
-#, fuzzy
msgid "Email me when there are any new answers"
-msgstr ""
-"<strong>Notify me</strong> weekly when there are any new answers or updates"
+msgstr "새로운 질문이 있을 때 이메일을 보내주세요"
#: skins/default/templates/question/subscribe_by_email_prompt.html:11
msgid "once you sign in you will be able to subscribe for any updates here"
-msgstr ""
-"<span class='strong'>Here</span> (once you log in) you will be able to sign "
-"up for the periodic email updates about this question."
+msgstr "<span class='strong'>Here</span> (once you log in) you will be able to sign up for the periodic email updates about this question."
#: skins/default/templates/question/subscribe_by_email_prompt.html:12
msgid ""
"<span class='strong'>Here</span> (once you log in) you will be able to sign "
"up for the periodic email updates about this question."
-msgstr ""
+msgstr "<span class='strong'>이 곳에서</span> (로그인 후에) 이 질문에 대하여 주기적으로 이메일을 받아보도록 등록하실 수 있습니다."
#: skins/default/templates/user_profile/user.html:12
-#, fuzzy, python-format
+#, python-format
msgid "%(username)s's profile"
-msgstr "User login"
+msgstr "%(username)s의 프로필"
#: skins/default/templates/user_profile/user_edit.html:4
-#, fuzzy
msgid "Edit user profile"
-msgstr "User login"
+msgstr "사용자 프로필을 수정합니다."
#: skins/default/templates/user_profile/user_edit.html:7
-#, fuzzy
msgid "edit profile"
-msgstr "User login"
+msgstr "프로필을 수정합니다."
#: skins/default/templates/user_profile/user_edit.html:21
#: skins/default/templates/user_profile/user_info.html:15
-#, fuzzy
msgid "change picture"
-msgstr "Retag question"
+msgstr "사진을 바꿉니다."
#: skins/default/templates/user_profile/user_edit.html:25
#: skins/default/templates/user_profile/user_info.html:19
msgid "remove"
-msgstr ""
+msgstr "지우기"
#: skins/default/templates/user_profile/user_edit.html:32
msgid "Registered user"
-msgstr ""
+msgstr "등록된 사용자"
#: skins/default/templates/user_profile/user_edit.html:39
-#, fuzzy
msgid "Screen Name"
-msgstr "<strong>Screen Name</strong> (<i>will be shown to others</i>)"
+msgstr "닉네임"
#: skins/default/templates/user_profile/user_edit.html:59
-#, fuzzy
msgid "(cannot be changed)"
-msgstr "sorry, but older votes cannot be revoked"
+msgstr "(변경될 수 없다)"
#: skins/default/templates/user_profile/user_edit.html:101
#: skins/default/templates/user_profile/user_email_subscriptions.html:22
-#, fuzzy
msgid "Update"
-msgstr "Last updated"
+msgstr "업데이트"
#: skins/default/templates/user_profile/user_email_subscriptions.html:4
#: skins/default/templates/user_profile/user_tabs.html:42
-#, fuzzy
msgid "subscriptions"
-msgstr ""
-"<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."
+msgstr "구독"
#: skins/default/templates/user_profile/user_email_subscriptions.html:7
-#, fuzzy
msgid "Email subscription settings"
-msgstr ""
-"<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."
+msgstr "이메일 구독 설정"
#: skins/default/templates/user_profile/user_email_subscriptions.html:9
msgid ""
"<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."
-msgstr ""
+"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."
+msgstr "<span class='big strong'>이메일 발송 주기 조정.</span> 관심 있는 질문에 대한 소식을 이메일로 받아보시고, 동료의 질문에 답변함으로써 <strong><br/>커뮤니티를 도와주세요</strong>. 이메일을 받기를 원치 않으시면 - 아래의 항목 중 'no email'을 선택하세요.<br/>선택된 항목에 대하여 새로운 활동이 있을 경우에만 새 소식이 발송됩니다."
#: skins/default/templates/user_profile/user_email_subscriptions.html:23
-#, fuzzy
msgid "Stop Email"
-msgstr ""
-"<strong>Your Email</strong> (<i>must be valid, never shown to others</i>)"
+msgstr "이메일 중지"
#: skins/default/templates/user_profile/user_favorites.html:4
#: skins/default/templates/user_profile/user_tabs.html:27
-#, fuzzy
msgid "followed questions"
-msgstr "Ask Your Question"
+msgstr "관심 질문"
#: skins/default/templates/user_profile/user_inbox.html:18
#: skins/default/templates/user_profile/user_tabs.html:12
msgid "inbox"
-msgstr ""
+msgstr "편지함"
#: skins/default/templates/user_profile/user_inbox.html:34
-#, fuzzy
msgid "Sections:"
-msgstr "Tags"
+msgstr "섹션:"
#: skins/default/templates/user_profile/user_inbox.html:38
#, python-format
msgid "forum responses (%(re_count)s)"
-msgstr ""
+msgstr "포럼 응답 (%(re_count)s)"
#: skins/default/templates/user_profile/user_inbox.html:43
#, python-format
msgid "flagged items (%(flag_count)s)"
-msgstr ""
+msgstr "신고된 항목 (%(flag_count)s)"
#: skins/default/templates/user_profile/user_inbox.html:49
#: skins/default/templates/user_profile/user_inbox.html:61
msgid "select:"
-msgstr ""
+msgstr "선택:"
#: skins/default/templates/user_profile/user_inbox.html:51
#: skins/default/templates/user_profile/user_inbox.html:63
-#, fuzzy
msgid "seen"
-msgstr "Last updated"
+msgstr "읽음"
#: skins/default/templates/user_profile/user_inbox.html:52
#: skins/default/templates/user_profile/user_inbox.html:64
msgid "new"
-msgstr ""
+msgstr "새 메시지"
#: skins/default/templates/user_profile/user_inbox.html:53
#: skins/default/templates/user_profile/user_inbox.html:65
msgid "none"
-msgstr ""
+msgstr "기타"
#: skins/default/templates/user_profile/user_inbox.html:54
-#, fuzzy
msgid "mark as seen"
-msgstr "Last updated"
+msgstr "읽음으로 표시"
#: skins/default/templates/user_profile/user_inbox.html:55
msgid "mark as new"
-msgstr ""
+msgstr "새 메시지로 표시"
#: skins/default/templates/user_profile/user_inbox.html:56
msgid "dismiss"
-msgstr ""
+msgstr "무시하기"
#: skins/default/templates/user_profile/user_inbox.html:66
-#, fuzzy
msgid "remove flags"
-msgstr "Tags"
+msgstr "신고 취소"
#: skins/default/templates/user_profile/user_inbox.html:68
-#, fuzzy
msgid "delete post"
-msgstr "How to change my picture (gravatar) and what is gravatar?"
+msgstr "포스트 삭제"
#: skins/default/templates/user_profile/user_info.html:36
-#, fuzzy
msgid "update profile"
-msgstr "User login"
+msgstr "프로필 편집"
#: skins/default/templates/user_profile/user_info.html:40
msgid "manage login methods"
-msgstr ""
+msgstr "로그인 방법 관리"
#: skins/default/templates/user_profile/user_info.html:53
msgid "real name"
-msgstr ""
+msgstr "본명"
#: skins/default/templates/user_profile/user_info.html:58
-#, fuzzy
msgid "member since"
-msgstr "member since"
+msgstr "가입:"
#: skins/default/templates/user_profile/user_info.html:63
-#, fuzzy
msgid "last seen"
-msgstr "Last updated"
+msgstr "최종 방문일"
#: skins/default/templates/user_profile/user_info.html:69
-#, fuzzy
msgid "website"
-msgstr "website"
+msgstr "웹사이트"
#: skins/default/templates/user_profile/user_info.html:75
-#, fuzzy
msgid "location"
-msgstr "karma"
+msgstr "위치"
#: skins/default/templates/user_profile/user_info.html:82
-#, fuzzy
msgid "age"
-msgstr "Badges"
+msgstr "나이"
#: skins/default/templates/user_profile/user_info.html:83
msgid "age unit"
msgstr "years old"
#: skins/default/templates/user_profile/user_info.html:88
-#, fuzzy
msgid "todays unused votes"
-msgstr "votes"
+msgstr "사용하지 않은 일일 투표"
#: skins/default/templates/user_profile/user_info.html:89
-#, fuzzy
msgid "votes left"
-msgstr "votes"
+msgstr "표 남음"
#: skins/default/templates/user_profile/user_moderate.html:4
#: skins/default/templates/user_profile/user_tabs.html:48
-#, fuzzy
msgid "moderation"
-msgstr "karma"
+msgstr "조정"
#: skins/default/templates/user_profile/user_moderate.html:8
#, python-format
msgid "%(username)s's current status is \"%(status)s\""
-msgstr ""
+msgstr "%(username)s'님의 현재 상태는 \"%(status)s\"입니다"
#: skins/default/templates/user_profile/user_moderate.html:11
-#, fuzzy
msgid "User status changed"
-msgstr "User login"
+msgstr "사용자의 상태가 변경되었습니다."
#: skins/default/templates/user_profile/user_moderate.html:20
-#, fuzzy
msgid "Save"
-msgstr "Change Email"
+msgstr "저장"
#: skins/default/templates/user_profile/user_moderate.html:25
#, python-format
msgid "Your current reputation is %(reputation)s points"
-msgstr ""
+msgstr "현재 명성은 %(reputation)s점입니다"
#: skins/default/templates/user_profile/user_moderate.html:27
#, python-format
msgid "User's current reputation is %(reputation)s points"
-msgstr ""
+msgstr "이 사용자의 명성은 %(reputation)s 점입니다."
#: skins/default/templates/user_profile/user_moderate.html:31
-#, fuzzy
msgid "User reputation changed"
-msgstr "user karma"
+msgstr "사용자의 명성이 변경되었습니다."
#: skins/default/templates/user_profile/user_moderate.html:38
msgid "Subtract"
-msgstr ""
+msgstr "감점"
#: skins/default/templates/user_profile/user_moderate.html:39
msgid "Add"
-msgstr ""
+msgstr "가점"
#: skins/default/templates/user_profile/user_moderate.html:43
-#, fuzzy, python-format
+#, python-format
msgid "Send message to %(username)s"
-msgstr "Choose screen name"
+msgstr "%(username)s 님에게 메시지 보내기"
#: skins/default/templates/user_profile/user_moderate.html:44
msgid ""
"An email will be sent to the user with 'reply-to' field set to your email "
"address. Please make sure that your address is entered correctly."
-msgstr ""
+msgstr "'reply-to' 필드에 입력한 이메일 주소로 사용자에게 이메일이 발송됩니다. 주소를 올바로 입력하였는지 확인해주세요."
#: skins/default/templates/user_profile/user_moderate.html:46
-#, fuzzy
msgid "Message sent"
-msgstr "years old"
+msgstr "메시지가 발송됨"
#: skins/default/templates/user_profile/user_moderate.html:64
-#, fuzzy
msgid "Send message"
-msgstr "Choose screen name"
+msgstr "메시지 보내기"
#: skins/default/templates/user_profile/user_moderate.html:74
msgid ""
"Administrators have privileges of normal users, but in addition they can "
"assign/revoke any status to any user, and are exempt from the reputation "
"limits."
-msgstr ""
+msgstr "관리자는 일반 사용자의 권한을 갖지만, 어떠한 사용자에 대하여 어떠한 상태를 부여/회수할 수 있으며, 명성 제한이 면제됩니다."
#: skins/default/templates/user_profile/user_moderate.html:77
msgid ""
"Moderators have the same privileges as administrators, but cannot add or "
"remove user status of 'moderator' or 'administrator'."
-msgstr ""
+msgstr " 조정자는 관리자와 동일한 권한을 갖지만, 사용자에게 '조정자'나 '관리자' 상태를 추가하거나 제거할 수 없습니다."
#: skins/default/templates/user_profile/user_moderate.html:80
msgid "'Approved' status means the same as regular user."
-msgstr ""
+msgstr "'승인됨' 상태는 보통의 사용자와 동일함을 의미합니다."
#: skins/default/templates/user_profile/user_moderate.html:83
-#, fuzzy
msgid "Suspended users can only edit or delete their own posts."
-msgstr ""
-"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 "정지된 사용자는 자신의 게시물에 대해서만 편집 및 삭제를 할 수 있습니다."
#: skins/default/templates/user_profile/user_moderate.html:86
msgid ""
"Blocked users can only login and send feedback to the site administrators."
-msgstr ""
+msgstr "차단된 사용자는 로그인과 사이트 관리자에게 피드백 보내기만을 할 수 있습니다."
#: skins/default/templates/user_profile/user_network.html:5
#: skins/default/templates/user_profile/user_tabs.html:18
msgid "network"
-msgstr ""
+msgstr "인맥"
#: skins/default/templates/user_profile/user_network.html:10
#, python-format
msgid "Followed by %(count)s person"
msgid_plural "Followed by %(count)s people"
-msgstr[0] ""
+msgstr[0] "%(count)s 명에게 팔로우됨"
#: skins/default/templates/user_profile/user_network.html:14
#, python-format
msgid "Following %(count)s person"
msgid_plural "Following %(count)s people"
-msgstr[0] ""
+msgstr[0] "%(count)s 명을 팔로잉"
#: skins/default/templates/user_profile/user_network.html:19
msgid ""
"Your network is empty. Would you like to follow someone? - Just visit their "
"profiles and click \"follow\""
-msgstr ""
+msgstr "인맥이 형성되지 않았습니다. 누군가를 팔로우하시겠습니까? - 프로필을 방문하고 \"팔로우\"를 클릭하시면 됩니다."
#: skins/default/templates/user_profile/user_network.html:21
-#, fuzzy, python-format
+#, python-format
msgid "%(username)s's network is empty"
-msgstr "User login"
+msgstr "%(username)s 님의 인맥이 형성되지 않았습니다"
#: skins/default/templates/user_profile/user_recent.html:4
#: skins/default/templates/user_profile/user_tabs.html:29
#: skins/default/templates/user_profile/user_tabs.html:31
msgid "activity"
-msgstr ""
+msgstr "활동"
#: skins/default/templates/user_profile/user_recent.html:24
#: skins/default/templates/user_profile/user_recent.html:28
msgid "source"
-msgstr ""
+msgstr "원천"
#: skins/default/templates/user_profile/user_reputation.html:11
msgid "Your karma change log."
-msgstr ""
+msgstr "카르마 변경 로그."
#: skins/default/templates/user_profile/user_reputation.html:13
-#, fuzzy, python-format
+#, python-format
msgid "%(user_name)s's karma change log"
-msgstr "User login"
+msgstr "%(user_name)s의 카르마 변경 로그"
#: skins/default/templates/user_profile/user_stats.html:5
#: skins/default/templates/user_profile/user_tabs.html:7
msgid "overview"
-msgstr ""
+msgstr "프로필"
#: skins/default/templates/user_profile/user_stats.html:11
#, python-format
msgid "<span class=\"count\">%(counter)s</span> Question"
msgid_plural "<span class=\"count\">%(counter)s</span> Questions"
-msgstr[0] ""
+msgstr[0] "<span class=\"count\">%(counter)s</span> 질문"
#: skins/default/templates/user_profile/user_stats.html:16
-#, fuzzy
msgid "Answer"
msgid_plural "Answers"
-msgstr[0] "oldest"
+msgstr[0] "답변"
#: skins/default/templates/user_profile/user_stats.html:24
#, python-format
msgid "the answer has been voted for %(answer_score)s times"
-msgstr ""
+msgstr "답변이 %(answer_score)s 번 추천되었습니다"
#: skins/default/templates/user_profile/user_stats.html:34
#, python-format
msgid "(%(comment_count)s comment)"
msgid_plural "the answer has been commented %(comment_count)s times"
-msgstr[0] ""
+msgstr[0] "답변에 %(comment_count)s 개의 댓글이 달렸습니다"
#: skins/default/templates/user_profile/user_stats.html:44
#, python-format
msgid "<span class=\"count\">%(cnt)s</span> Vote"
msgid_plural "<span class=\"count\">%(cnt)s</span> Votes "
-msgstr[0] ""
+msgstr[0] "<span class=\"count\">%(cnt)s</span> 투표"
#: skins/default/templates/user_profile/user_stats.html:50
msgid "thumb up"
-msgstr ""
+msgstr "좋아요"
#: skins/default/templates/user_profile/user_stats.html:51
msgid "user has voted up this many times"
-msgstr ""
+msgstr "사용자가 여러 번 추천했습니다"
#: skins/default/templates/user_profile/user_stats.html:54
msgid "thumb down"
-msgstr ""
+msgstr "별로예요"
#: skins/default/templates/user_profile/user_stats.html:55
msgid "user voted down this many times"
-msgstr ""
+msgstr "사용자가 여러 번 비난했습니다"
#: skins/default/templates/user_profile/user_stats.html:63
#, python-format
msgid "<span class=\"count\">%(counter)s</span> Tag"
msgid_plural "<span class=\"count\">%(counter)s</span> Tags"
-msgstr[0] ""
+msgstr[0] "<span class=\"count\">%(counter)s</span> 태그"
#: skins/default/templates/user_profile/user_stats.html:97
#, python-format
msgid "<span class=\"count\">%(counter)s</span> Badge"
msgid_plural "<span class=\"count\">%(counter)s</span> Badges"
-msgstr[0] ""
+msgstr[0] "<span class=\"count\">%(counter)s</span> 배지"
#: skins/default/templates/user_profile/user_stats.html:120
-#, fuzzy
msgid "Answer to:"
-msgstr "Tips"
+msgstr "답변 대상:"
#: skins/default/templates/user_profile/user_tabs.html:5
-#, fuzzy
msgid "User profile"
-msgstr "User login"
+msgstr "사용자 프로필"
#: skins/default/templates/user_profile/user_tabs.html:10 views/users.py:638
msgid "comments and answers to others questions"
-msgstr ""
+msgstr "다른 사람들의 질문에 대한 댓글과 답변"
#: skins/default/templates/user_profile/user_tabs.html:16
msgid "followers and followed users"
-msgstr ""
+msgstr "팔로워 및 팔로우하는 사용자"
#: skins/default/templates/user_profile/user_tabs.html:21
-#, fuzzy
msgid "Graph of user karma"
-msgstr "Graph of user karma"
+msgstr "사용자 카르마 그래프"
#: skins/default/templates/user_profile/user_tabs.html:25
msgid "questions that user is following"
-msgstr ""
+msgstr "사용자가 팔로잉한 질문들"
#: skins/default/templates/user_profile/user_tabs.html:34 views/users.py:679
msgid "user vote record"
-msgstr ""
+msgstr "사용자 투표 기록"
#: skins/default/templates/user_profile/user_tabs.html:36
#: skins/default/templates/user_profile/user_votes.html:4
-#, fuzzy
msgid "votes"
-msgstr "votes"
+msgstr "투표"
#: skins/default/templates/user_profile/user_tabs.html:40 views/users.py:769
msgid "email subscription settings"
-msgstr ""
+msgstr "이메일 구독 설정"
#: skins/default/templates/user_profile/user_tabs.html:46 views/users.py:205
msgid "moderate this user"
-msgstr ""
+msgstr "이 사용자에 대한 조정"
#: skins/default/templates/widgets/answer_edit_tips.html:3
#: skins/default/templates/widgets/question_edit_tips.html:3
msgid "Tips"
-msgstr ""
+msgstr "팁"
#: skins/default/templates/widgets/answer_edit_tips.html:6
-#, fuzzy
msgid "give an answer interesting to this community"
-msgstr "ask a question interesting to this community"
+msgstr "이 커뮤니티에서 흥미를 가질 만한 답변을 해주세요"
#: skins/default/templates/widgets/answer_edit_tips.html:9
-#, fuzzy
msgid "try to give an answer, rather than engage into a discussion"
-msgstr ""
-"<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!"
+msgstr "논의에 참여하기 보다는 답변을 하기 위해 노력하라."
#: skins/default/templates/widgets/answer_edit_tips.html:12
#: skins/default/templates/widgets/question_edit_tips.html:8
-#, fuzzy
msgid "provide enough details"
-msgstr "provide enough details"
+msgstr "자세히 작성해주세요"
#: skins/default/templates/widgets/answer_edit_tips.html:15
#: skins/default/templates/widgets/question_edit_tips.html:11
msgid "be clear and concise"
-msgstr ""
+msgstr "깔끔하고 명료하게 작성해주세요"
#: skins/default/templates/widgets/answer_edit_tips.html:20
#: skins/default/templates/widgets/question_edit_tips.html:16
-#, fuzzy
msgid "see frequently asked questions"
-msgstr "ask a question interesting to this community"
+msgstr "자주 묻는 질문을 참조하세요."
#: skins/default/templates/widgets/answer_edit_tips.html:27
#: skins/default/templates/widgets/question_edit_tips.html:22
-#, fuzzy
msgid "Markdown basics"
-msgstr "Markdown basics"
+msgstr "마크다운 기초"
#: skins/default/templates/widgets/answer_edit_tips.html:31
#: skins/default/templates/widgets/question_edit_tips.html:26
msgid "*italic*"
-msgstr ""
+msgstr "*italic*"
#: skins/default/templates/widgets/answer_edit_tips.html:34
#: skins/default/templates/widgets/question_edit_tips.html:29
msgid "**bold**"
-msgstr ""
+msgstr "**bold**"
#: skins/default/templates/widgets/answer_edit_tips.html:38
#: skins/default/templates/widgets/question_edit_tips.html:33
msgid "*italic* or _italic_"
-msgstr ""
+msgstr "*italic* or _italic_"
#: skins/default/templates/widgets/answer_edit_tips.html:41
#: skins/default/templates/widgets/question_edit_tips.html:36
msgid "**bold** or __bold__"
-msgstr ""
+msgstr "**bold** or __bold__"
#: skins/default/templates/widgets/answer_edit_tips.html:45
#: skins/default/templates/widgets/answer_edit_tips.html:49
#: skins/default/templates/widgets/question_edit_tips.html:40
#: skins/default/templates/widgets/question_edit_tips.html:45
msgid "text"
-msgstr ""
+msgstr "텍스트"
#: skins/default/templates/widgets/answer_edit_tips.html:49
#: skins/default/templates/widgets/question_edit_tips.html:45
msgid "image"
-msgstr ""
+msgstr "이미지"
#: skins/default/templates/widgets/answer_edit_tips.html:53
#: skins/default/templates/widgets/question_edit_tips.html:49
msgid "numbered list:"
-msgstr ""
+msgstr "번호가 매겨진 목록:"
#: skins/default/templates/widgets/answer_edit_tips.html:58
#: skins/default/templates/widgets/question_edit_tips.html:54
msgid "basic HTML tags are also supported"
-msgstr ""
+msgstr "기본 HTML 태그들 역시 지원됩니다."
#: skins/default/templates/widgets/answer_edit_tips.html:63
#: skins/default/templates/widgets/question_edit_tips.html:59
msgid "learn more about Markdown"
-msgstr ""
+msgstr "Markdown에 관하여 더 많이 배우기"
#: skins/default/templates/widgets/ask_form.html:6
msgid "login to post question info"
-msgstr ""
-"<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."
+msgstr "<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."
#: skins/default/templates/widgets/ask_form.html:7
msgid ""
"<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."
-msgstr ""
+"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."
+msgstr "<span class=\\\"strong big\\\">익명으로 질문을 올리시는 것을 환영합니다</span>. 게시물을 제출하면, 로그인/가입 페이지로 이동할 것입니다. 귀하의 게시물은 이 세션 내에 저장되며 로그인 후에 발행됩니다. 로그인/가입 절차는 매우 간단합니다. 로그인에는 30 초, 처음 가입하는 데에는 몇 분 밖에 걸리지 않습니다."
#: skins/default/templates/widgets/ask_form.html:11
#, python-format
msgid ""
"<span class='strong big'>Looks like your email address, %%(email)s has not "
"yet been validated.</span> To post messages you must verify your email, "
-"please see <a href='%%(email_validation_faq_url)s'>more details here</a>."
-"<br>You can submit your question now and validate email after that. Your "
-"question will saved as pending meanwhile."
-msgstr ""
+"please see <a href='%%(email_validation_faq_url)s'>more details "
+"here</a>.<br>You can submit your question now and validate email after that."
+" Your question will saved as pending meanwhile."
+msgstr "%%(email)s은 <span class='strong big'>귀하의 이메일 주소처럼 보이지만, 아직 확인되지 않았습니다.</span> 메시지를 게시하기 위해서는 이메일을 반드시 검증하셔야 하며, <a href='%%(email_validation_faq_url)s'>자세한 내용은 이곳</a>을 참조하시기 바랍니다.<br>그런 다음 이메일을 통하여 질문을 제출하실 수 있습니다. 그때까지는 귀하의 질문은 대기상태로 저장됩니다."
#: skins/default/templates/widgets/contributors.html:3
msgid "Contributors"
-msgstr ""
+msgstr "공헌자"
#: skins/default/templates/widgets/footer.html:33
#, python-format
msgid "Content on this site is licensed under a %(license)s"
-msgstr ""
+msgstr "이 사이트의 컨텐츠는 %(license)s 라이선스를 따릅니다"
#: skins/default/templates/widgets/footer.html:38
msgid "about"
-msgstr ""
+msgstr "소개"
#: skins/default/templates/widgets/footer.html:40
#: skins/default/templates/widgets/user_navigation.html:17
msgid "help"
-msgstr ""
+msgstr "도움말"
#: skins/default/templates/widgets/footer.html:42
msgid "privacy policy"
-msgstr ""
+msgstr "개인정보 정책"
#: skins/default/templates/widgets/footer.html:51
msgid "give feedback"
-msgstr ""
+msgstr "피드백 주기"
#: skins/default/templates/widgets/logo.html:3
msgid "back to home page"
-msgstr ""
+msgstr "홈 페이지로 돌아가기"
#: skins/default/templates/widgets/logo.html:4
#, python-format
msgid "%(site)s logo"
-msgstr ""
+msgstr "%(site)s 로고"
#: skins/default/templates/widgets/meta_nav.html:10
msgid "users"
msgstr "people"
#: skins/default/templates/widgets/meta_nav.html:15
-#, fuzzy
msgid "badges"
-msgstr "Badges"
+msgstr "배지"
#: skins/default/templates/widgets/question_edit_tips.html:5
-#, fuzzy
msgid "ask a question interesting to this community"
-msgstr "ask a question interesting to this community"
+msgstr "이 커뮤니티에서 흥미를 가질 만한 질문을 해주세요"
#: skins/default/templates/widgets/question_summary.html:12
msgid "view"
msgid_plural "views"
-msgstr[0] ""
+msgstr[0] "읽음"
#: skins/default/templates/widgets/question_summary.html:29
-#, fuzzy
msgid "answer"
msgid_plural "answers"
-msgstr[0] "oldest"
+msgstr[0] "답변"
#: skins/default/templates/widgets/question_summary.html:40
-#, fuzzy
msgid "vote"
msgid_plural "votes"
-msgstr[0] "votes"
+msgstr[0] "투표"
#: skins/default/templates/widgets/scope_nav.html:6
msgid "ALL"
-msgstr ""
+msgstr "모두"
#: skins/default/templates/widgets/scope_nav.html:8
-#, fuzzy
msgid "see unanswered questions"
-msgstr "Ask Your Question"
+msgstr "답변되지 않은 질문 보기"
#: skins/default/templates/widgets/scope_nav.html:8
msgid "UNANSWERED"
-msgstr ""
+msgstr "미답변"
#: skins/default/templates/widgets/scope_nav.html:11
-#, fuzzy
msgid "see your followed questions"
-msgstr "Ask Your Question"
+msgstr "팔로우하는 질문 보기"
#: skins/default/templates/widgets/scope_nav.html:11
msgid "FOLLOWED"
-msgstr ""
+msgstr "관심사"
#: skins/default/templates/widgets/scope_nav.html:14
-#, fuzzy
msgid "Please ask your question here"
-msgstr "Ask Your Question"
+msgstr "이곳에서 질문하세요"
#: skins/default/templates/widgets/user_long_score_and_badge_summary.html:3
msgid "karma:"
-msgstr ""
+msgstr "카르마:"
#: skins/default/templates/widgets/user_long_score_and_badge_summary.html:7
-#, fuzzy
msgid "badges:"
-msgstr "Badges"
+msgstr "배지:"
#: skins/default/templates/widgets/user_navigation.html:9
msgid "sign out"
-msgstr ""
+msgstr "로그아웃"
#: skins/default/templates/widgets/user_navigation.html:12
-#, fuzzy
msgid "Hi, there! Please sign in"
-msgstr ""
-"<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."
+msgstr "안녕하세요! 로그인해주세요"
#: skins/default/templates/widgets/user_navigation.html:15
-#, fuzzy
msgid "settings"
-msgstr "User login"
+msgstr "설정"
#: templatetags/extra_filters_jinja.py:279
msgid "no"
-msgstr ""
+msgstr "0"
#: utils/decorators.py:90 views/commands.py:73 views/commands.py:93
msgid "Oops, apologies - there was some error"
-msgstr ""
+msgstr "앗, 죄송합니다. 오류가 있네요"
#: utils/decorators.py:109
msgid "Please login to post"
-msgstr ""
+msgstr "게시하려면 로그인해주세요"
#: utils/decorators.py:205
msgid "Spam was detected on your post, sorry for if this is a mistake"
-msgstr ""
+msgstr "게시물에서 스팸이 탐지되었습니다. 잘못 탐지되었다면 죄송합니다"
#: utils/forms.py:33
msgid "this field is required"
-msgstr ""
+msgstr "이 항목을 입력해주세요"
#: utils/forms.py:60
-#, fuzzy
msgid "Choose a screen name"
-msgstr "Choose screen name"
+msgstr "닉네임을 선택해주세요"
#: utils/forms.py:69
msgid "user name is required"
-msgstr ""
+msgstr "사용자명이 필요합니다"
#: utils/forms.py:70
msgid "sorry, this name is taken, please choose another"
-msgstr ""
+msgstr "미안합니다. 이 이름은 이미 사용 중입니다. 다른 이름을 골라주세요"
#: utils/forms.py:71
msgid "sorry, this name is not allowed, please choose another"
-msgstr ""
+msgstr "미안합니다. 이 이름은 사용하실 수 없습니다. 다른 이름을 골라주세요"
#: utils/forms.py:72
msgid "sorry, there is no user with this name"
-msgstr ""
+msgstr "미안합니다. 이 이름을 가진 사용자가 존재하지 않습니다"
#: utils/forms.py:73
msgid "sorry, we have a serious error - user name is taken by several users"
-msgstr ""
+msgstr "미안합니다. 사용자명을 여러 사람이 쓰는 심각한 오류가 있습니다."
#: utils/forms.py:74
msgid "user name can only consist of letters, empty space and underscore"
-msgstr ""
+msgstr "사용자명에는 문자, 공백, 밑줄만 사용할 수 있습니다."
#: utils/forms.py:75
msgid "please use at least some alphabetic characters in the user name"
-msgstr ""
+msgstr "사용자명에는 영문자 몇 개만이라도 필요합니다"
#: utils/forms.py:138
msgid "Your email <i>(never shared)</i>"
-msgstr ""
+msgstr "이메일 <i>(비공개)</i>"
#: utils/forms.py:139
msgid "email address is required"
-msgstr ""
+msgstr "이메일 주소가 필요합니다"
#: utils/forms.py:140
msgid "please enter a valid email address"
-msgstr ""
+msgstr "유효한 이메일 주소를 입력해주세요"
#: utils/forms.py:141
msgid "this email is already used by someone else, please choose another"
-msgstr ""
+msgstr "이 이메일은 이미 다른 사람이 사용하고 있습니다. 다른 것을 선택해주세요"
#: utils/forms.py:170
msgid "password is required"
-msgstr ""
+msgstr "비밀번호가 필요합니다"
#: utils/forms.py:173
msgid "Password <i>(please retype)</i>"
-msgstr ""
+msgstr "비밀번호 <i>(한 번 더 입력해주세요)</i>"
#: utils/forms.py:174
msgid "please, retype your password"
-msgstr ""
+msgstr "비밀번호를 한 번 더 입력해주세요"
#: utils/forms.py:175
msgid "sorry, entered passwords did not match, please try again"
-msgstr ""
+msgstr "미안합니다. 입력하신 비밀번호가 일치하지 않습니다. 다시 입력해주세요"
#: utils/functions.py:82
msgid "2 days ago"
-msgstr ""
+msgstr "이틀 전"
#: utils/functions.py:84
msgid "yesterday"
-msgstr ""
+msgstr "어제"
#: utils/functions.py:87
#, python-format
msgid "%(hr)d hour ago"
msgid_plural "%(hr)d hours ago"
-msgstr[0] ""
+msgstr[0] "%(hr)d 시간 전"
#: utils/functions.py:93
#, python-format
msgid "%(min)d min ago"
msgid_plural "%(min)d mins ago"
-msgstr[0] ""
+msgstr[0] "%(min)d 분 전"
#: utils/mail.py:147
msgid ""
@@ -6514,747 +6162,264 @@ msgid ""
"</ul>\n"
"<p>Note that tags may consist of more than one word, and tags\n"
"may be separated by a semicolon or a comma</p>\n"
-msgstr ""
+msgstr "<p>이메일로 질문하려면</p>\n<ul>\n <li>제목 형식: [태그1; 태그2] 질문 제목</li>\n <li>이메일 본문: 질문 내용을 작성합니다</li>\n</ul>\n<p>태그는 한 단어 이상으로 이루어질 수도 있으며, 각 태그는 세미콜론이나 쉼표로 구분함에 유의하시기 바랍니다</p>\n"
#: utils/mail.py:167
#, python-format
msgid ""
"<p>Sorry, there was an error posting your question please contact the "
"%(site)s administrator</p>"
-msgstr ""
+msgstr "<p>죄송합니다. 질문을 올리는 도중에 오류가 발생하였습니다. %(site)s 관리자에게 연락해주세요</p>"
#: utils/mail.py:173
#, python-format
msgid ""
-"<p>Sorry, in order to post questions on %(site)s by email, please <a href="
-"\"%(url)s\">register first</a></p>"
-msgstr ""
+"<p>Sorry, in order to post questions on %(site)s by email, please <a "
+"href=\"%(url)s\">register first</a></p>"
+msgstr "<p>죄송합니다. %(site)s에 이메일로 질문을 등록하시려면, <a href=\"%(url)s\">등록</a>을 먼저 해주세요</p>"
#: utils/mail.py:181
msgid ""
"<p>Sorry, your question could not be posted due to insufficient privileges "
"of your user account</p>"
-msgstr ""
+msgstr "<p>죄송합니다. 귀하의 계정으로는 질문을 등록하실 수 없습니다</p>"
#: views/avatar_views.py:99
msgid "Successfully uploaded a new avatar."
-msgstr ""
+msgstr "새 아바타를 성공적으로 업로드하였습니다."
#: views/avatar_views.py:140
msgid "Successfully updated your avatar."
-msgstr ""
+msgstr "아바타를 성공적으로 갱신했습니다."
#: views/avatar_views.py:180
msgid "Successfully deleted the requested avatars."
-msgstr ""
+msgstr "요청하신 아바타를 성공적으로 삭제했습니다."
#: views/commands.py:83
msgid "Sorry, but anonymous users cannot access the inbox"
-msgstr ""
+msgstr "미안합니다. 익명의 사용자는 편지함에 접근할 수 없습니다"
#: views/commands.py:112
-#, fuzzy
msgid "Sorry, anonymous users cannot vote"
-msgstr "Sorry, anonymous users cannot vote"
+msgstr "미안합니다. 익명으로 투표하실 수 없습니다."
#: views/commands.py:129
msgid "Sorry you ran out of votes for today"
-msgstr ""
+msgstr "오늘의 투표를 모두 행사하셨습니다"
#: views/commands.py:135
#, python-format
msgid "You have %(votes_left)s votes left for today"
-msgstr ""
+msgstr "오늘은 %(votes_left)s 표가 남아 있습니다"
#: views/commands.py:210
msgid "Sorry, something is not right here..."
-msgstr ""
+msgstr "미안합니다. 뭔가가 올바르지 않습니다..."
#: views/commands.py:229
msgid "Sorry, but anonymous users cannot accept answers"
-msgstr ""
+msgstr "미안합니다. 익명의 사용자는 질문을 채택할 수 없습니다"
#: views/commands.py:339
-#, fuzzy, python-format
+#, python-format
msgid ""
"Your subscription is saved, but email address %(email)s needs to be "
"validated, please see <a href=\"%(details_url)s\">more details here</a>"
-msgstr ""
-"Your subscription is saved, but email address %(email)s needs to be "
-"validated, please see <a href='%(details_url)s'>more details here</a>"
+msgstr "구독이 저장되었지만, 이메일 주소 %(email)s에 대한 확인이 필요합니다. <a href=\"%(details_url)s\">자세한 사항은 이곳</a>을 참고하시기 바랍니다"
#: views/commands.py:348
msgid "email update frequency has been set to daily"
-msgstr ""
+msgstr "이메일 업데이트 주기가 매일로 설정되었습니다"
#: views/commands.py:464
#, python-format
msgid "Tag subscription was canceled (<a href=\"%(url)s\">undo</a>)."
-msgstr ""
+msgstr "태그 구독이 취소되었습니다(<a href=\"%(url)s\">되돌리기</a>)."
#: views/commands.py:473
#, python-format
msgid "Please sign in to subscribe for: %(tags)s"
-msgstr ""
+msgstr "%(tags)s를 구독하려면 로그인해주세요"
#: views/commands.py:600
msgid "Please sign in to vote"
-msgstr ""
+msgstr "투표하려면 로그인해주세요"
#: views/commands.py:620
-#, fuzzy
msgid "Please sign in to delete/restore posts"
-msgstr ""
-"<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."
+msgstr "게시물을 삭제/복구하려면 로그인해주세요"
#: views/meta.py:37
#, python-format
msgid "About %(site)s"
-msgstr ""
+msgstr "%(site)s에 대하여"
#: views/meta.py:92
msgid "Q&A forum feedback"
-msgstr ""
+msgstr "Q&A 포럼 피드백"
#: views/meta.py:93
msgid "Thanks for the feedback!"
-msgstr ""
+msgstr "피드백에 감사드립니다!"
#: views/meta.py:102
msgid "We look forward to hearing your feedback! Please, give it next time :)"
-msgstr ""
+msgstr "피드백을 들려주세요! 다음 번에는요 :)"
#: views/meta.py:106
msgid "Privacy policy"
-msgstr ""
+msgstr "개인정보 정책"
#: views/readers.py:133
-#, fuzzy, python-format
+#, python-format
msgid "%(q_num)s question, tagged"
msgid_plural "%(q_num)s questions, tagged"
-msgstr[0] "Asked"
+msgstr[0] "%(q_num)s 개의 질문, 태그됨"
#: views/readers.py:388
msgid ""
"Sorry, the comment you are looking for has been deleted and is no longer "
"accessible"
-msgstr ""
+msgstr "미안합니다. 찾으시는 댓글은 삭제되었거나 더 이상 접근할 수 없습니다"
#: views/users.py:206
msgid "moderate user"
-msgstr ""
+msgstr "사용자 조정"
#: views/users.py:381
msgid "user profile"
-msgstr ""
+msgstr "사용자 프로필"
#: views/users.py:382
msgid "user profile overview"
-msgstr ""
+msgstr "사용자 프로필 둘러보기"
#: views/users.py:551
msgid "recent user activity"
-msgstr ""
+msgstr "사용자의 최근 활동"
#: views/users.py:552
msgid "profile - recent activity"
-msgstr ""
+msgstr "프로필 - 최근 활동"
#: views/users.py:639
msgid "profile - responses"
-msgstr ""
+msgstr "프로필 - 응답"
#: views/users.py:680
msgid "profile - votes"
-msgstr ""
+msgstr "프로필 - 투표"
#: views/users.py:701
msgid "user karma"
-msgstr ""
+msgstr "사용자 카르마"
#: views/users.py:702
-#, fuzzy
msgid "Profile - User's Karma"
-msgstr "Profile - User's Karma"
+msgstr "프로필 - 사용자의 카르마"
#: views/users.py:720
msgid "users favorite questions"
-msgstr ""
+msgstr "사용자가 좋아하는 질문"
#: views/users.py:721
msgid "profile - favorite questions"
-msgstr ""
+msgstr "프로필 - 좋아하는 질문"
#: views/users.py:741 views/users.py:745
msgid "changes saved"
-msgstr ""
+msgstr "변경사항이 저장됨"
#: views/users.py:751
msgid "email updates canceled"
-msgstr ""
+msgstr "이메일 변경이 취소됨"
#: views/users.py:770
msgid "profile - email subscriptions"
-msgstr ""
+msgstr "프로필 - 이메일 구독"
#: views/writers.py:60
msgid "Sorry, anonymous users cannot upload files"
-msgstr ""
+msgstr "미안합니다. 익명으로 파일을 업로드할 수 없습니다"
#: views/writers.py:73
#, python-format
msgid "allowed file types are '%(file_types)s'"
-msgstr ""
+msgstr "허용되는 파일 형식은 '%(file_types)s'"
#: views/writers.py:84
#, python-format
msgid "maximum upload file size is %(file_size)sK"
-msgstr ""
+msgstr "최대 업로드 파일 크기는 %(file_size)sK입니다"
#: views/writers.py:92
-msgid "Error uploading file. Please contact the site administrator. Thank you."
-msgstr ""
+msgid ""
+"Error uploading file. Please contact the site administrator. Thank you."
+msgstr "파일 업로드 오류. 사이트 관리자에게 문의해주세요. 고맙습니다."
#: views/writers.py:189
msgid ""
-"<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 "
+"<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."
-msgstr ""
+msgstr "<span class=\"strong big\">익명으로 질문을 올리시는 것을 환영합니다</span>. 게시물을 제출하면, 로그인/가입 페이지로 이동합니다. 귀하의 질문은 현재 세션 내에 저장되며 로그인 후에 발행됩니다. 로그인/가입 절차는 매우 간단합니다. 로그인에는 30 초, 처음 가입에는 몇 분 밖에 걸리지 않습니다."
#: views/writers.py:466
-#, fuzzy
msgid "Please log in to answer questions"
-msgstr ""
-"<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!"
+msgstr "질문에 답하려면 로그인해주세요"
#: views/writers.py:572
#, python-format
msgid ""
-"Sorry, you appear to be logged out and cannot post comments. Please <a href="
-"\"%(sign_in_url)s\">sign in</a>."
-msgstr ""
+"Sorry, you appear to be logged out and cannot post comments. Please <a "
+"href=\"%(sign_in_url)s\">sign in</a>."
+msgstr "미안합니다. 로그아웃하신 것으로 보여서 댓글을 달 수 없습니다. <a href=\"%(sign_in_url)s\">로그인</a>해주세요."
#: views/writers.py:589
msgid "Sorry, anonymous users cannot edit comments"
-msgstr ""
+msgstr "미안합니다. 익명의 사용자는 댓글을 편집할 수 없습니다"
#: views/writers.py:619
#, python-format
msgid ""
"Sorry, you appear to be logged out and cannot delete comments. Please <a "
"href=\"%(sign_in_url)s\">sign in</a>."
-msgstr ""
+msgstr "미안합니다. 로그아웃하신 것으로 보여서 댓글을 삭제할 수 없습니다. <a href=\"%(sign_in_url)s\">로그인</a>해주세요."
#: views/writers.py:640
msgid "sorry, we seem to have some technical difficulties"
-msgstr ""
-
-#~ msgid "question_answered"
-#~ msgstr "answered question"
-
-#~ msgid "question_commented"
-#~ msgstr "commented question"
-
-#~ msgid "Incorrect username."
-#~ msgstr "sorry, there is no such user name"
-
-#~ msgid "%(name)s, this is an update message header for %(num)d question"
-#~ msgid_plural ""
-#~ "%(name)s, this is an update message header for %(num)d questions"
-#~ msgstr[0] ""
-#~ "<p>Dear %(name)s,</p></p>The following %(num)d question has been updated "
-#~ "on the Q&A forum:</p>"
-
-#~ msgid ""
-#~ "go to %(email_settings_link)s to change frequency of email updates or "
-#~ "%(admin_email)s administrator"
-#~ msgstr ""
-#~ "<p>Please remember that you can always <a "
-#~ "href='%(email_settings_link)s'>adjust</a> frequency of the email updates "
-#~ "or turn them off entirely.<br/>If you believe that this message was sent "
-#~ "in an error, please email about it the forum administrator at "
-#~ "%(admin_email)s.</p><p>Sincerely,</p><p>Your friendly Q&A forum server.</"
-#~ "p>"
-
-#~ msgid ""
-#~ "uploading images is limited to users with >%(min_rep)s reputation points"
-#~ msgstr "sorry, file uploading requires karma >%(min_rep)s"
-
-#~ msgid "blocked users cannot post"
-#~ msgstr ""
-#~ "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."
-
-#~ msgid "suspended users cannot post"
-#~ msgstr ""
-#~ "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."
-
-#~ msgid "cannot flag message as offensive twice"
-#~ msgstr ""
-#~ "You have flagged this question before and cannot do it more than once"
-
-#~ msgid "blocked users cannot flag posts"
-#~ msgstr ""
-#~ "Sorry, since your account is blocked you cannot flag posts as offensive"
-
-#~ msgid "suspended users cannot flag posts"
-#~ msgstr ""
-#~ "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."
-
-#~ msgid "need > %(min_rep)s points to flag spam"
-#~ msgstr ""
-#~ "Sorry, to flag posts as offensive a minimum reputation of %(min_rep)s is "
-#~ "required"
-
-#~ msgid "%(max_flags_per_day)s exceeded"
-#~ msgstr ""
-#~ "Sorry, you have exhausted the maximum number of %(max_flags_per_day)s "
-#~ "offensive flags per day."
-
-#, fuzzy
-#~ msgid "suspended users cannot remove flags"
-#~ msgstr ""
-#~ "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."
-
-#, fuzzy
-#~ msgid "need > %(min_rep)d point to remove flag"
-#~ msgid_plural "need > %(min_rep)d points to remove flag"
-#~ msgstr[0] ""
-#~ "Sorry, to flag posts as offensive a minimum reputation of %(min_rep)s is "
-#~ "required"
-
-#~ msgid "cannot revoke old vote"
-#~ msgstr "sorry, but older votes cannot be revoked"
-
-#~ msgid "change %(email)s info"
-#~ msgstr ""
-#~ "<span class=\"strong big\">Enter your new email into the box below</span> "
-#~ "if you'd like to use another email for <strong>update subscriptions</"
-#~ "strong>.<br>Currently you are using <strong>%(email)s</strong>"
-
-#~ msgid "here is why email is required, see %(gravatar_faq_url)s"
-#~ msgstr ""
-#~ "<span class='strong big'>Please enter your email address in the box below."
-#~ "</span> Valid email address is required on this Q&amp;A forum. If you "
-#~ "like, you can <strong>receive updates</strong> on interesting questions "
-#~ "or entire forum via email. Also, your email is used to create a unique <a "
-#~ "href='%(gravatar_faq_url)s'><strong>gravatar</strong></a> image for your "
-#~ "account. Email addresses are never shown or otherwise shared with anybody "
-#~ "else."
-
-#~ msgid "Your new Email"
-#~ msgstr ""
-#~ "<strong>Your new Email:</strong> (will <strong>not</strong> be shown to "
-#~ "anyone, must be valid)"
-
-#~ msgid "validate %(email)s info or go to %(change_email_url)s"
-#~ msgstr ""
-#~ "<span class=\"strong big\">An email with a validation link has been sent "
-#~ "to %(email)s.</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)s'><strong>change it again</strong></a>."
-
-#~ msgid "old %(email)s kept, if you like go to %(change_email_url)s"
-#~ msgstr ""
-#~ "<span class=\"strong big\">Your email address %(email)s has not been "
-#~ "changed.</span> If you decide to change it later - you can always do it "
-#~ "by editing it in your user profile or by using the <a "
-#~ "href='%(change_email_url)s'><strong>previous form</strong></a> again."
-
-#~ msgid "your current %(email)s can be used for this"
-#~ msgstr ""
-#~ "<span class='big strong'>Your email address is now set to %(email)s.</"
-#~ "span> Updates on the questions that you like most will be sent to this "
-#~ "address. Email notifications are sent once a day or less frequently - "
-#~ "only when there are any news."
-
-#~ msgid "thanks for verifying email"
-#~ msgstr ""
-#~ "<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."
-
-#~ msgid "email key not sent"
-#~ msgstr "Validation email not sent"
-
-#~ msgid "email key not sent %(email)s change email here %(change_link)s"
-#~ msgstr ""
-#~ "<span class='big strong'>Your current email address %(email)s has been "
-#~ "validated before</span> so the new key was not sent. You can <a "
-#~ "href='%(change_link)s'>change</a> email used for update subscriptions if "
-#~ "necessary."
-
-#~ msgid "register new %(provider)s account info, see %(gravatar_faq_url)s"
-#~ msgstr ""
-#~ "<p><span class=\"big strong\">You are here for the first time with your "
-#~ "%(provider)s login.</span> Please create your <strong>screen name</"
-#~ "strong> and save your <strong>email</strong> address. Saved email address "
-#~ "will let you <strong>subscribe for the updates</strong> on the most "
-#~ "interesting questions and will be used to create and retrieve your unique "
-#~ "avatar image - <a href='%(gravatar_faq_url)s'><strong>gravatar</strong></"
-#~ "a>.</p>"
-
-#~ msgid ""
-#~ "%(username)s already exists, choose another name for \n"
-#~ " %(provider)s. Email is required too, see "
-#~ "%(gravatar_faq_url)s\n"
-#~ " "
-#~ msgstr ""
-#~ "<p><span class='strong big'>Oops... looks like screen name %(username)s "
-#~ "is already used in another account.</span></p><p>Please choose another "
-#~ "screen name to use with your %(provider)s login. Also, a valid email "
-#~ "address is required on the <span class='orange'>Q&amp;A</span> forum. "
-#~ "Your email is used to create a unique <a "
-#~ "href='%(gravatar_faq_url)s'><strong>gravatar</strong></a> image for your "
-#~ "account. If you like, you can <strong>receive updates</strong> on the "
-#~ "interesting questions or entire forum by email. Email addresses are never "
-#~ "shown or otherwise shared with anybody else.</p>"
-
-#~ msgid ""
-#~ "register new external %(provider)s account info, see %(gravatar_faq_url)s"
-#~ msgstr ""
-#~ "<p><span class=\"big strong\">You are here for the first time with your "
-#~ "%(provider)s login.</span></p><p>You can either keep your <strong>screen "
-#~ "name</strong> the same as your %(provider)s login name or choose some "
-#~ "other nickname.</p><p>Also, please save a valid <strong>email</strong> "
-#~ "address. With the email you can <strong>subscribe for the updates</"
-#~ "strong> on the most interesting questions. Email address is also used to "
-#~ "create and retrieve your unique avatar image - <a "
-#~ "href='%(gravatar_faq_url)s'><strong>gravatar</strong></a>.</p>"
-
-#~ msgid "register new Facebook connect account info, see %(gravatar_faq_url)s"
-#~ msgstr ""
-#~ "<p><span class=\"big strong\">You are here for the first time with your "
-#~ "Facebook login.</span> Please create your <strong>screen name</strong> "
-#~ "and save your <strong>email</strong> address. Saved email address will "
-#~ "let you <strong>subscribe for the updates</strong> on the most "
-#~ "interesting questions and will be used to create and retrieve your unique "
-#~ "avatar image - <a href='%(gravatar_faq_url)s'><strong>gravatar</strong></"
-#~ "a>.</p>"
-
-#~ msgid "Screen name label"
-#~ msgstr "<strong>Screen Name</strong> (<i>will be shown to others</i>)"
-
-#~ msgid "Email address label"
-#~ msgstr ""
-#~ "<strong>Email Address</strong> (<i>will <strong>not</strong> be shared "
-#~ "with anyone, must be valid</i>)"
-
-#~ msgid "receive updates motivational blurb"
-#~ msgstr ""
-#~ "<strong>Receive forum updates by email</strong> - this will help our "
-#~ "community grow and become more useful.<br/>By default <span "
-#~ "class='orange'>Q&amp;A</span> forum sends up to <strong>one email digest "
-#~ "per week</strong> - only when there is anything new.<br/>If you like, "
-#~ "please adjust this now or any time later from your user account."
-
-#~ msgid "create account"
-#~ msgstr "Signup"
-
-#~ msgid "Login"
-#~ msgstr "Sign in"
-
-#~ msgid "with openid it is easier"
-#~ msgstr "With the OpenID you don't need to create new username and password."
-
-#~ msgid "reuse openid"
-#~ msgstr ""
-#~ "You can safely re-use the same login for all OpenID-enabled websites."
-
-#~ msgid "openid is widely adopted"
-#~ msgstr ""
-#~ "There are > 160,000,000 OpenID account in use. Over 10,000 sites are "
-#~ "OpenID-enabled."
-
-#~ msgid "openid is supported open standard"
-#~ msgstr ""
-#~ "OpenID is based on an open standard, supported by many organizations."
-
-#~ msgid "Traditional signup info"
-#~ msgstr ""
-#~ "<span class='strong big'>If you prefer, create your forum login name and "
-#~ "password here. However</span>, please keep in mind that we also support "
-#~ "<strong>OpenID</strong> login method. With <strong>OpenID</strong> you "
-#~ "can simply reuse your external login (e.g. Gmail or AOL) without ever "
-#~ "sharing your login details with anyone and having to remember yet another "
-#~ "password."
-
-#, fuzzy
-#~ msgid "Create Account"
-#~ msgstr "Signup"
-
-#~ msgid "answer permanent link"
-#~ msgstr "permanent link"
-
-#, fuzzy
-#~ msgid "remove all flags"
-#~ msgstr "Tags"
-
-#~ msgid "Related tags"
-#~ msgstr "Tags"
-
-#, fuzzy
-#~ msgid "Ask a question"
-#~ msgstr "Ask Your Question"
-
-#~ msgid "Badges summary"
-#~ msgstr "Badges"
-
-#~ msgid "gold badge description"
-#~ msgstr ""
-#~ "Gold badge is the highest award in this community. To obtain it have to "
-#~ "show profound knowledge and ability in addition to your active "
-#~ "participation."
-
-#~ msgid "silver badge description"
-#~ msgstr ""
-#~ "silver badge: occasionally awarded for the very high quality contributions"
-
-#~ msgid "bronze badge description"
-#~ msgstr "bronze badge: often given as a special honor"
-
-#~ msgid ""
-#~ "is a Q&A site, not a discussion group. Therefore - please avoid having "
-#~ "discussions in your answers, comment facility allows some space for brief "
-#~ "discussions."
-#~ 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."
-
-#~ msgid "Rep system summary"
-#~ 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."
-
-#, fuzzy
-#~ msgid "use tags"
-#~ msgstr "Tags"
-
-#~ msgid "what is gravatar"
-#~ msgstr "How to change my picture (gravatar) and what is gravatar?"
-
-#~ msgid "gravatar faq info"
-#~ 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>"
-
-#~ msgid "Change tags"
-#~ msgstr "Retag question"
-
-#~ msgid "reputation"
-#~ msgstr "karma"
-
-#~ msgid "newest answers"
-#~ msgstr "newest"
-
-#~ msgid "popular answers"
-#~ msgstr "most voted"
-
-#~ msgid "you can answer anonymously and then login"
-#~ msgstr ""
-#~ "<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)!"
-
-#~ msgid "answer your own question only to give an answer"
-#~ msgstr ""
-#~ "<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)! "
-
-#~ msgid "please only give an answer, no discussions"
-#~ msgstr ""
-#~ "<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!"
-
-#~ msgid "Login/Signup to Post Your Answer"
-#~ msgstr "Login/Signup to Post"
-
-#~ msgid "question asked"
-#~ msgstr "Asked"
-
-#~ msgid "question was seen"
-#~ msgstr "Seen"
-
-#~ msgid "Notify me once a day when there are any new answers"
-#~ msgstr ""
-#~ "<strong>Notify me</strong> once a day by email when there are any new "
-#~ "answers or updates"
-
-#, fuzzy
-#~ msgid "Notify me immediately when there are any new answers"
-#~ msgstr ""
-#~ "<strong>Notify me</strong> weekly when there are any new answers or "
-#~ "updates"
-
-#~ msgid ""
-#~ "You can always adjust frequency of email updates from your %(profile_url)s"
-#~ msgstr ""
-#~ "(note: you can always <strong><a href='%(profile_url)s?"
-#~ "sort=email_subscriptions'>change</a></strong> how often you receive "
-#~ "updates)"
-
-#~ msgid "email subscription settings info"
-#~ msgstr ""
-#~ "<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."
-
-#~ msgid "Stop sending email"
-#~ msgstr "Stop Email"
-
-#~ msgid "reputation history"
-#~ msgstr "karma history"
-
-#~ msgid "casted votes"
-#~ msgstr "votes"
-
-#~ msgid "answer tips"
-#~ msgstr "Tips"
-
-#~ msgid "please try to provide details"
-#~ msgstr "provide enough details"
-
-#, fuzzy
-#~ msgid "ask a question"
-#~ msgstr "Ask Your Question"
-
-#, fuzzy
-#~ msgid ""
-#~ "must have valid %(email)s to post, \n"
-#~ " see %(email_validation_faq_url)s\n"
-#~ " "
-#~ msgstr ""
-#~ "<span class='strong big'>Looks like your email address, %(email)s has not "
-#~ "yet been validated.</span> To post messages you must verify your email, "
-#~ "please see <a href='%(email_validation_faq_url)s'>more details here</a>."
-#~ "<br>You can submit your question now and validate email after that. Your "
-#~ "question will saved as pending meanwhile. "
-
-#~ msgid "Login/signup to post your question"
-#~ msgstr "Login/Signup to Post"
-
-#~ msgid "question tips"
-#~ msgstr "Tips"
-
-#~ msgid "please ask a relevant question"
-#~ msgstr "ask a question interesting to this community"
+msgstr "미안합니다. 기술적인 어려움이 있는 것 같습니다."
#~ msgid "logout"
#~ msgstr "sign out"
-#~ msgid "login"
-#~ msgstr "Hi, there! Please sign in"
-
-#~ msgid "no items in counter"
-#~ msgstr "no"
-
-#~ msgid "choose password"
-#~ msgstr "Password"
-
-#~ msgid "retype password"
-#~ msgstr "Password <i>(please retype)</i>"
-
-#~ msgid "user reputation in the community"
-#~ msgstr "user karma"
-
-#, fuzzy
-#~ msgid "Please log in to ask questions"
+#~ msgid ""
+#~ "As a registered user you can login with your OpenID, log out of the site or "
+#~ "permanently remove your account."
#~ msgstr ""
-#~ "<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."
-
-#, fuzzy
-#~ msgid "(please enter a valid email)"
-#~ msgstr "provide enough details"
-
-#~ msgid "Question tags"
-#~ msgstr "Tags"
+#~ "Clicking <strong>Logout</strong> will log you out from the forum but will "
+#~ "not sign you off from your OpenID provider.</p><p>If you wish to sign off "
+#~ "completely - please make sure to log out from your OpenID provider as well."
#~ msgid "Email verification subject line"
#~ 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 "
-#~ "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 "
-#~ "- create a unique <a href='%(gravatar_faq_url)s'><strong>gravatar</"
-#~ "strong></a> personal image.</p>"
-
-#~ msgid ""
-#~ "As a registered user you can login with your OpenID, log out of the site "
-#~ "or permanently remove your account."
-#~ msgstr ""
-#~ "Clicking <strong>Logout</strong> will log you out from the forumbut will "
-#~ "not sign you off from your OpenID provider.</p><p>If you wish to sign off "
-#~ "completely - please make sure to log out from your OpenID provider as "
-#~ "well."
-
-#~ msgid "reputation points"
-#~ msgstr "karma"
+#~ "<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 - create a unique <a "
+#~ "href='%(gravatar_faq_url)s'><strong>gravatar</strong></a> personal "
+#~ "image.</p>"
diff --git a/askbot/locale/ko/LC_MESSAGES/djangojs.mo b/askbot/locale/ko/LC_MESSAGES/djangojs.mo
index 2845bf19..5d2b2865 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 3e40eaa0..3bfa7b6c 100644
--- a/askbot/locale/ko/LC_MESSAGES/djangojs.po
+++ b/askbot/locale/ko/LC_MESSAGES/djangojs.po
@@ -1,268 +1,292 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+# Translators:
+# <16thetower@gmail.com>, 2012.
+# Yong Choi <sk8er.choi@gmail.com>, 2012.
msgid ""
msgstr ""
-"Project-Id-Version: 0.7\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-04-18 18:51-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"
-"Language: ko\n"
+"Project-Id-Version: askbot\n"
+"Report-Msgid-Bugs-To: http://askbot.org/\n"
+"POT-Creation-Date: 2012-04-18 18:58-0500\n"
+"PO-Revision-Date: 2012-12-25 13:51+0000\n"
+"Last-Translator: Yong Choi <sk8er.choi@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"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=1; plural=0\n"
-"X-Generator: Translate Toolkit 1.9.0\n"
+"Language: ko\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
#: skins/common/media/jquery-openid/jquery.openid.js:73
#, perl-format
msgid "Are you sure you want to remove your %s login?"
-msgstr ""
+msgstr "%s 로그인을 정말로 제거하시겠습니까?"
#: skins/common/media/jquery-openid/jquery.openid.js:90
msgid "Please add one or more login methods."
-msgstr ""
+msgstr "한 가지 또는 그 이상의 로그인 방법을 추가해주세요."
#: skins/common/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 "아래의 아이콘 중 하나를 클릭하여 로그인 방법을 지정하신 후 로그인해주세요."
#: skins/common/media/jquery-openid/jquery.openid.js:135
msgid "passwords do not match"
-msgstr ""
+msgstr "패스워드가 일치하지 않습니다"
#: skins/common/media/jquery-openid/jquery.openid.js:161
msgid "Show/change current login methods"
-msgstr ""
+msgstr "현재의 로그인 방법을 표시/변경"
#: skins/common/media/jquery-openid/jquery.openid.js:226
#, perl-format
msgid "Please enter your %s, then proceed"
-msgstr ""
+msgstr "%s를 입력 후 진행"
#: skins/common/media/jquery-openid/jquery.openid.js:228
msgid "Connect your %(provider_name)s account to %(site)s"
-msgstr ""
+msgstr "%(provider_name)s 계정을 %(site)s에 연결"
#: skins/common/media/jquery-openid/jquery.openid.js:322
#, perl-format
msgid "Change your %s password"
-msgstr ""
+msgstr "%s 패스워드를 변경"
#: skins/common/media/jquery-openid/jquery.openid.js:323
msgid "Change password"
-msgstr ""
+msgstr "패스워드 변경"
#: skins/common/media/jquery-openid/jquery.openid.js:326
#, perl-format
msgid "Create a password for %s"
-msgstr ""
+msgstr "%s 패스워드를 생성"
#: skins/common/media/jquery-openid/jquery.openid.js:327
msgid "Create password"
-msgstr ""
+msgstr "패스워드 생성"
#: skins/common/media/jquery-openid/jquery.openid.js:343
msgid "Create a password-protected account"
-msgstr ""
+msgstr "일반 계정을 생성"
#: skins/common/media/js/post.js:28
msgid "loading..."
-msgstr ""
+msgstr "로딩중.."
#: skins/common/media/js/post.js:318
msgid "insufficient privilege"
-msgstr ""
+msgstr "해당 권한이 없습니다"
#: skins/common/media/js/post.js:319
msgid "cannot pick own answer as best"
-msgstr ""
+msgstr "자신의 대답을 채택할 수 없습니다"
#: skins/common/media/js/post.js:324
msgid "please login"
-msgstr ""
+msgstr "로그인을 해주세요"
#: skins/common/media/js/post.js:326
msgid "anonymous users cannot follow questions"
-msgstr ""
+msgstr "익명의 사용자는 질문을 팔로우할 수 없습니다"
#: skins/common/media/js/post.js:327
msgid "anonymous users cannot subscribe to questions"
-msgstr ""
+msgstr "익명의 사용자는 질문을 구독하실 수 없습니다"
#: skins/common/media/js/post.js:328
msgid "anonymous users cannot vote"
-msgstr ""
+msgstr "익명의 사용자는 투표하실 수 없습니다"
#: skins/common/media/js/post.js:330
msgid "please confirm offensive"
-msgstr ""
+msgstr "이 글은 욕설, 광고, 스팸, 악의적인 내용이 포함되어 있습니까?"
#: skins/common/media/js/post.js:331
msgid "please confirm removal of offensive flag"
-msgstr ""
+msgstr "이 글에 욕설, 광고, 스팸, 악의적인 내용이 포함되어 있는 것이 확실합니까?"
#: skins/common/media/js/post.js:332
msgid "anonymous users cannot flag offensive posts"
-msgstr ""
+msgstr "익명의 사용자는 부적합한 게시물을 신고할 수 없습니다"
#: skins/common/media/js/post.js:333
msgid "confirm delete"
-msgstr ""
+msgstr "이 글을 삭제 하시겠습니까?"
#: skins/common/media/js/post.js:334
msgid "anonymous users cannot delete/undelete"
-msgstr ""
+msgstr "익명의 사용자는 글을 삭제 또는 삭제 취소할 수 없습니다"
#: skins/common/media/js/post.js:335
msgid "post recovered"
-msgstr ""
+msgstr "글이 복원되었습니다!"
#: skins/common/media/js/post.js:336
msgid "post deleted"
-msgstr ""
+msgstr "글이 삭제되었습니다"
#: skins/common/media/js/post.js:1206
msgid "add comment"
-msgstr ""
+msgstr "댓글 추가"
#: skins/common/media/js/post.js:1209
msgid "save comment"
-msgstr ""
+msgstr "댓글 저장"
#: skins/common/media/js/post.js:1874
msgid "Please enter question title (>10 characters)"
-msgstr ""
+msgstr "질문을 입력해 주세요 (10자 이상)"
#: skins/common/media/js/tag_selector.js:15
msgid "Tag \"<span></span>\" matches:"
-msgstr ""
+msgstr "\"<span></span>\" 태그 맞춤:"
#: skins/common/media/js/tag_selector.js:84
#, perl-format
msgid "and %s more, not shown..."
-msgstr ""
+msgstr "그리고 %s 이상은 보여주지 않습니다..."
#: skins/common/media/js/user.js:14
msgid "Please select at least one item"
-msgstr ""
+msgstr "적어도 하나의 아이템을 선택 해야 합니다."
#: skins/common/media/js/user.js:58
msgid "Delete this notification?"
msgid_plural "Delete these notifications?"
-msgstr[0] ""
+msgstr[0] "알림을 삭제 하시겠습니까?\n\n알림들을 삭제 하시겠습니까?"
#: skins/common/media/js/user.js:65
msgid "Close this entry?"
msgid_plural "Close these entries?"
-msgstr[0] ""
+msgstr[0] "해당 항목을 닫으시겠습니까?"
#: skins/common/media/js/user.js:72
msgid "Remove all flags on this entry?"
msgid_plural "Remove all flags on these entries?"
-msgstr[0] ""
+msgstr[0] "해당 항목의 모든 플래그를 삭제하시겠습니까?"
#: skins/common/media/js/user.js:79
msgid "Delete this entry?"
msgid_plural "Delete these entries?"
-msgstr[0] ""
+msgstr[0] "해당 항목을 삭제하시겠습니까?"
#: skins/common/media/js/user.js:159
msgid "Please <a href=\"%(signin_url)s\">signin</a> to follow %(username)s"
-msgstr ""
+msgstr "%(username)s님을 팔로우하시려면 <a href=\"%(signin_url)s\">로그인</a>을 해주세요"
#: skins/common/media/js/user.js:191
#, perl-format
msgid "unfollow %s"
-msgstr ""
+msgstr "%s님을 언팔로우"
#: skins/common/media/js/user.js:194
#, perl-format
msgid "following %s"
-msgstr ""
+msgstr "%s님을 팔로잉"
#: skins/common/media/js/user.js:200
#, perl-format
msgid "follow %s"
-msgstr ""
+msgstr "%s 팔로우"
#: skins/common/media/js/utils.js:44
msgid "click to close"
-msgstr ""
+msgstr "close를 선택"
#: skins/common/media/js/wmd/wmd.js:26
msgid "bold"
-msgstr ""
+msgstr "굵게"
#: skins/common/media/js/wmd/wmd.js:27
msgid "italic"
-msgstr ""
+msgstr "기울임꼴"
#: skins/common/media/js/wmd/wmd.js:28
msgid "link"
-msgstr ""
+msgstr "링크"
#: skins/common/media/js/wmd/wmd.js:29
msgid "quote"
-msgstr ""
+msgstr "인용"
#: skins/common/media/js/wmd/wmd.js:30
msgid "preformatted text"
-msgstr ""
+msgstr "텍스트 서식이 설정되어 있습니다."
#: skins/common/media/js/wmd/wmd.js:31
msgid "image"
-msgstr ""
+msgstr "이미지"
#: skins/common/media/js/wmd/wmd.js:32
msgid "attachment"
-msgstr ""
+msgstr "첨부파일"
#: skins/common/media/js/wmd/wmd.js:33
msgid "numbered list"
-msgstr ""
+msgstr "번호 목록"
#: skins/common/media/js/wmd/wmd.js:34
msgid "bulleted list"
-msgstr ""
+msgstr "불릿 목록"
#: skins/common/media/js/wmd/wmd.js:35
msgid "heading"
-msgstr ""
+msgstr "머리글"
#: skins/common/media/js/wmd/wmd.js:36
msgid "horizontal bar"
-msgstr ""
+msgstr "수평 막대"
#: skins/common/media/js/wmd/wmd.js:37
msgid "undo"
-msgstr ""
+msgstr "실행 취소"
#: skins/common/media/js/wmd/wmd.js:38 skins/common/media/js/wmd/wmd.js:1053
msgid "redo"
-msgstr ""
+msgstr "다시 실행"
#: skins/common/media/js/wmd/wmd.js:47
msgid "enter image url"
-msgstr ""
+msgstr "URL이나 이미지를 입력해주세요.\n예: http://www.example.com/image.jpg 입력 또는 이미지 파일 업로드"
#: skins/common/media/js/wmd/wmd.js:48
msgid "enter url"
-msgstr ""
+msgstr "웹사이트 주소를 입력해주세요.\n예: http://www.example.com \"웹 페이지 명\""
#: skins/common/media/js/wmd/wmd.js:49
msgid "upload file attachment"
-msgstr ""
+msgstr "업로드할 파일을 선택해주세요"
+
+#~ msgid "tags cannot be empty"
+#~ msgstr "please enter at least one tag"
+
+#~ msgid "%s content minchars"
+#~ msgstr "please enter more than %s characters"
+
+#~ msgid "%s title minchars"
+#~ msgstr "please enter at least %s characters"
+
+#~ msgid "Follow"
+#~ msgstr "Follow"
+
+#~ msgid "<div>Following</div><div class=\"unfollow\">Unfollow</div>"
+#~ msgstr "<div>Following</div><div class=\"unfollow\">Unfollow</div>"
+
+#~ msgid "enter %s more characters"
+#~ msgstr "please enter at least %s more characters"
+
+#~ msgid "confirm abandon comment"
+#~ msgstr "Are you sure you do not want to post this comment?"
+
+#~ msgid "confirm delete comment"
+#~ msgstr "do you really want to delete this comment?"
+
+#~ msgid "click to edit this comment"
+#~ msgstr "click to edit this comment"
-#, fuzzy
-#~ msgid "%s follower"
-#~ msgid_plural "%s followers"
-#~ msgstr[0] ""
-#~ "#-#-#-#-# djangojs.po (0.7) #-#-#-#-#\n"
-#~ "#-#-#-#-# djangojs.po (0.7) #-#-#-#-#\n"
-#~ msgstr[1] "#-#-#-#-# djangojs.po (0.7) #-#-#-#-#\n"
+#~ msgid "edit"
+#~ msgstr "edit"
diff --git a/askbot/mail/__init__.py b/askbot/mail/__init__.py
index c9c84f33..60deec68 100644
--- a/askbot/mail/__init__.py
+++ b/askbot/mail/__init__.py
@@ -1,25 +1,29 @@
"""functions that send email in askbot
these automatically catch email-related exceptions
"""
+import logging
import os
+import re
import smtplib
-import logging
+import sys
+from askbot import exceptions
+from askbot import const
+from askbot.conf import settings as askbot_settings
+from askbot.mail import parsing
+from askbot.utils import url_utils
+from askbot.utils.file_utils import store_file
+from askbot.utils.html import absolutize_urls
+from bs4 import BeautifulSoup
from django.core import mail
from django.conf import settings as django_settings
from django.core.exceptions import PermissionDenied
from django.forms import ValidationError
-from django.utils.translation import ugettext_lazy as _
+from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy
from django.utils.translation import string_concat
from django.template import Context
from django.utils.html import strip_tags
-from askbot import exceptions
-from askbot import const
-from askbot.conf import settings as askbot_settings
-from askbot.utils import url_utils
-from askbot.utils.file_utils import store_file
-from askbot.utils.html import absolutize_urls
-from bs4 import BeautifulSoup
#todo: maybe send_mail functions belong to models
#or the future API
def prefix_the_subject_line(subject):
@@ -82,14 +86,16 @@ def thread_headers(post, orig_post, update):
return headers
def clean_html_email(email_body):
- """needs more clenup might not work for other email templates
+ """returns the content part from an HTML email.
+ todo: needs more clenup might not work for other email templates
that do not use table layout
"""
soup = BeautifulSoup(email_body)
body_element = soup.find('body')
+ filter_func = lambda s: bool(s.strip())
phrases = map(
lambda s: s.strip(),
- filter(bool, body_element.get_text().split('\n'))
+ filter(filter_func, body_element.get_text().split('\n'))
)
return '\n\n'.join(phrases)
@@ -129,10 +135,11 @@ def send_mail(
)
msg.attach_alternative(body_text, "text/html")
msg.send()
+ logging.debug('sent update to %s' % ','.join(recipient_list))
if related_object is not None:
assert(activity_type is not None)
except Exception, error:
- logging.critical(unicode(error))
+ sys.stderr.write('\n' + unicode(error).encode('utf-8') + '\n')
if raise_on_failure == True:
raise exceptions.EmailNotSent(unicode(error))
@@ -169,26 +176,26 @@ def mail_moderators(
msg.content_subtype = 'html'
msg.send()
except smtplib.SMTPException, error:
- logging.critical(unicode(error))
+ sys.stderr.write('\n' + error.encode('utf-8') + '\n')
if raise_on_failure == True:
raise exceptions.EmailNotSent(unicode(error))
-INSTRUCTIONS_PREAMBLE = _('<p>To ask by email, please:</p>')
-QUESTION_TITLE_INSTRUCTION = _(
+INSTRUCTIONS_PREAMBLE = ugettext_lazy('<p>To ask by email, please:</p>')
+QUESTION_TITLE_INSTRUCTION = ugettext_lazy(
'<li>Type title in the subject line</li>'
)
-QUESTION_DETAILS_INSTRUCTION = _(
+QUESTION_DETAILS_INSTRUCTION = ugettext_lazy(
'<li>Type details of your question into the email body</li>'
)
-OPTIONAL_TAGS_INSTRUCTION = _(
+OPTIONAL_TAGS_INSTRUCTION = ugettext_lazy(
"""<li>The beginning of the subject line can contain tags,
<em>enclosed in the square brackets</em> like so: [Tag1; Tag2]</li>"""
)
-REQUIRED_TAGS_INSTRUCTION = _(
+REQUIRED_TAGS_INSTRUCTION = ugettext_lazy(
"""<li>In the beginning of the subject add at least one tag
<em>enclosed in the brackets</em> like so: [Tag1; Tag2].</li>"""
)
-TAGS_INSTRUCTION_FOOTNOTE = _(
+TAGS_INSTRUCTION_FOOTNOTE = ugettext_lazy(
"""<p>Note that a tag may consist of more than one word, to separate
the tags, use a semicolon or a comma, for example, [One tag; Other tag]</p>"""
)
@@ -266,16 +273,12 @@ def bounce_email(
def extract_reply(text):
"""take the part above the separator
and discard the last line above the separator
+ ``text`` is the input text
"""
- if const.REPLY_SEPARATOR_REGEX.search(text):
- text = const.REPLY_SEPARATOR_REGEX.split(text)[0]
- text_lines = text.splitlines(False)
- #log last 10 lines of text - to capture email responses
- logging.debug('reply-border-separator|' + '|'.join(text_lines[-10:]))
- #here we need code stripping the "On ... somebody wrote:"
- return '\n'.join(text_lines[:-3])
- else:
- return text
+ return parsing.extract_reply_contents(
+ text,
+ const.REPLY_SEPARATOR_REGEX
+ )
def process_attachment(attachment):
"""will save a single
@@ -294,11 +297,11 @@ def process_attachment(attachment):
def extract_user_signature(text, reply_code):
"""extracts email signature as text trailing
the reply code"""
- striped_text = strip_tags(text)
- if reply_code in striped_text:
+ stripped_text = strip_tags(text)
+ if reply_code in stripped_text:
#extract the signature
tail = list()
- for line in reversed(striped_text.splitlines()):
+ for line in reversed(stripped_text.splitlines()):
#scan backwards from the end until the magic line
if reply_code in line:
break
@@ -311,13 +314,13 @@ def extract_user_signature(text, reply_code):
return '\n'.join(tail)
else:
- return ''
+ return None
-def process_parts(parts, reply_code = None):
- """Process parts will upload the attachments and parse out the
- body, if body is multipart. Secondly - links to attachments
- will be added to the body of the question.
+def process_parts(parts, reply_code=None):
+ """Uploads the attachments and parses out the
+ body, if body is multipart.
+ Links to attachments will be added to the body of the question.
Returns ready to post body of the message and the list
of uploaded files.
"""
@@ -366,7 +369,7 @@ def process_emailed_question(
'subject': subject,
'body_text': body_text
}
- user = User.objects.get(email__iexact = email_address)
+ user = User.objects.get(email__iexact=from_address)
form = AskByEmailForm(data, user=user)
if form.is_valid():
email_address = form.cleaned_data['email']
diff --git a/askbot/mail/lamson_handlers.py b/askbot/mail/lamson_handlers.py
index da09eec2..8bfa86f7 100644
--- a/askbot/mail/lamson_handlers.py
+++ b/askbot/mail/lamson_handlers.py
@@ -3,13 +3,13 @@ import functools
from django.core.files.uploadedfile import SimpleUploadedFile
from django.conf import settings as django_settings
from django.template import Context
+from django.template.loader import get_template
from django.utils.translation import ugettext as _
from lamson.routing import route, stateless
from lamson.server import Relay
from askbot.models import ReplyAddress, Group, Tag
from askbot import mail
from askbot.conf import settings as askbot_settings
-from askbot.skins.loaders import get_template
#we might end up needing to use something like this
#to distinguish the reply text from the quoted original message
@@ -147,13 +147,6 @@ def process_reply(func):
#here is the business part of this function
parts = get_parts(message)
- for part_type, content in parts:
- if part_type == 'body':
- print '==============================='
- print 'message :', content
- break
- else:
- continue
func(
from_address = message.From,
subject_line = message['Subject'],
@@ -173,7 +166,7 @@ def process_reply(func):
if error is not None:
template = get_template('email/reply_by_email_error.html')
- body_text = template.render(Context({'error':error}))
+ body_text = template.render(Context({'error':error}))#todo: set lang
mail.send_mail(
subject_line = "Error posting your reply",
body_text = body_text,
@@ -250,7 +243,7 @@ def VALIDATE_EMAIL(
mail.send_mail(
subject_line = _('Re: Welcome to %(site_name)s') % data,
- body_text = template.render(Context(data)),
+ body_text = template.render(Context(data)),#todo: set lang
recipient_list = [from_address,]
)
except ValueError:
@@ -281,7 +274,7 @@ def PROCESS(
#2) process body text and email signature
user = reply_address_object.user
- if signature:#if there, then it was stripped
+ if signature is not None:#if there, then it was stripped
if signature != user.email_signature:
user.email_signature = signature
else:#try to strip signature
@@ -319,6 +312,6 @@ def PROCESS(
mail.send_mail(
subject_line = _('Re: %s') % subject_line,
- body_text = template.render(Context(data)),
+ body_text = template.render(Context(data)),#todo: set lang
recipient_list = [from_address,]
)
diff --git a/askbot/mail/messages.py b/askbot/mail/messages.py
index 3ab3ff2f..0e888545 100644
--- a/askbot/mail/messages.py
+++ b/askbot/mail/messages.py
@@ -3,8 +3,8 @@ of email messages for various occasions
"""
import functools
from django.template import Context
+from django.template.loader import get_template
from askbot.conf import settings as askbot_settings
-from askbot.skins.loaders import get_template
from askbot.utils import html as html_utils
def message(template = None):
@@ -16,7 +16,7 @@ def message(template = None):
def wrapped(*args, **kwargs):
template_object = get_template(template)
data = func(*args, **kwargs)
- return template_object.render(Context(data))
+ return template_object.render(Context(data))#todo: set lang
return wrapped
return decorate
diff --git a/askbot/mail/parsing.py b/askbot/mail/parsing.py
new file mode 100644
index 00000000..31be6abb
--- /dev/null
+++ b/askbot/mail/parsing.py
@@ -0,0 +1,85 @@
+"""a module for parsing email response text
+this file is a candidate for publishing as an independent module
+"""
+import re
+import sys
+
+#Regexes for quote separators
+#add more via variables ending with _QUOTE_RE
+#These regexes do not contain any trailing:
+#* newline chars,
+#* lines starting with | or >
+#* lines consisting entirely of empty space
+#expressions are stripped of month and day names
+#to keep them simpler and make the additions of language variants
+#easier.
+GMAIL_QUOTE_RE = r'\nOn [^\n]* wrote:\Z'
+GMAIL_SECOND_QUOTE_RE = r'\n\d{4}/\d{1,2}/\d{1,2} [^\n]*\Z'
+YAHOO_QUOTE_RE = r'\n_+\n\s*From: [^\n]+\nTo: [^\n]+\nSent: [^\n]+\nSubject: [^\n]+\Z'
+KMAIL_QUOTE_RE = r'\AOn [^\n]+ you wrote:\s*\n\n'
+OUTLOOK_RTF_QUOTE_RE = r'\nSubject: [^\n]+\nFrom: [^\n]+\nTo: [^\n]+\nDate: [^\n]+\Z'
+OUTLOOK_TEXT_QUOTE_RE = r'\n_+\Z'
+
+def compile_quote_regexes():
+ regex_names = filter(
+ lambda v: v.endswith('_QUOTE_RE'),
+ globals().keys()
+ )
+ compiled_regexes = list()
+ for regex_name in regex_names:
+ regex = globals()[regex_name]
+ compiled_regexes.append(
+ re.compile(
+ regex,
+ re.MULTILINE | re.IGNORECASE
+ )
+ )
+ return compiled_regexes
+
+CLIENT_SPECIFIC_QUOTE_REGEXES = compile_quote_regexes()
+
+def strip_trailing_empties_and_quotes(text):
+ #strip empty lines and quote lines starting with | and >
+ return re.sub(r'(([\n\s\xa0])|(\n[\|>][^\n]*))*\Z', '', text)
+
+def strip_leading_empties(text):
+ return re.sub(r'\A[\n\s\xa0]*', '', text)
+
+def strip_email_client_quote_separator(text):
+ """strips email client quote separator from the responses,
+ e.g. (on such date XYZ wrote)
+
+ if one client-specific separator matches, then result
+ is immediately returned
+ """
+ for regex in CLIENT_SPECIFIC_QUOTE_REGEXES:
+ if regex.search(text):
+ return regex.sub('', text)
+ #did not find a quote separator!!! log it
+ log_message = u'\nno matching quote separator: %s\n' % text
+ sys.stderr.write(log_message.encode('utf-8'))
+ text_lines = text.splitlines(False)
+ return ''.join(text_lines[:-3])#strip 3 lines as a guess
+
+def extract_reply_contents(text, reply_separator=None):
+ """If reply_separator is given,
+ take the part above the separator.
+ After, strip the email-client-specific text
+
+ ``text`` is the input text
+ ``reply_separator`` is either a string or a regex object
+ """
+ if reply_separator:
+ if isinstance(reply_separator, basestring):
+ text = text.split(reply_separator)[0]
+ else:
+ testre = re.compile('test')
+ if type(testre) == type(reply_separator):
+ text = reply_separator.split(text)[0]
+ else:
+ raise ValueError('reply_separator must be a string or a compiled regex')
+
+ text = strip_trailing_empties_and_quotes(text)
+ text = strip_email_client_quote_separator(text)
+ text = strip_trailing_empties_and_quotes(text)
+ return strip_leading_empties(text)
diff --git a/askbot/management/commands/askbot_add_test_content.py b/askbot/management/commands/askbot_add_test_content.py
index 7867fcec..0efd8c1f 100644
--- a/askbot/management/commands/askbot_add_test_content.py
+++ b/askbot/management/commands/askbot_add_test_content.py
@@ -1,8 +1,10 @@
-from django.core.management.base import NoArgsCommand
+from askbot.conf import settings as askbot_settings
from askbot.models import User
-from optparse import make_option
from askbot.utils.console import choice_dialog
-from askbot.conf import settings as askbot_settings
+from django.core.management.base import NoArgsCommand
+from django.conf import settings as django_settings
+from django.utils import translation
+from optparse import make_option
NUM_USERS = 40
@@ -236,6 +238,8 @@ class Command(NoArgsCommand):
if answer != "yes":
return
+ translation.activate(django_settings.LANGUAGE_CODE)
+
self.save_alert_settings()
self.stop_alerts()# saves time on running the command
diff --git a/askbot/management/commands/askbot_create_test_fixture.py b/askbot/management/commands/askbot_create_test_fixture.py
deleted file mode 100644
index e7045e8c..00000000
--- a/askbot/management/commands/askbot_create_test_fixture.py
+++ /dev/null
@@ -1,76 +0,0 @@
-from django.core.management.base import NoArgsCommand
-from django.core import management
-import os
-import askbot
-from optparse import make_option
-from askbot.utils.console import choice_dialog
-
-
-# FULL PATH HERE
-# DEFAULTS TO askbot_path/tests/test_data.json
-FIXTURE_NAME = os.path.join(os.path.dirname(askbot.__file__),
- "tests", "test_data.json")
-
-# The data from these apps gets auto-populated on signals, saves and updates
-# We have to exclude it otherwise we get Constraint errors
-EXCLUDE_APPS = ['contenttypes',
- 'sites',
- 'askbot.activity',
- 'askbot.activityauditstatus',
- 'askbot.badgedata',
- 'askbot.Post',
- 'askbot.EmailFeedSetting',
- 'auth.Message']
-
-
-class Command(NoArgsCommand):
- """
- Flushes the database, fills it with test data, dumps a fixture and then
- flushes the database again.
- """
-
- option_list = NoArgsCommand.option_list + (
- make_option('--noinput', action='store_false', dest='interactive', default=True,
- help='Do not prompt the user for input of any kind.'),
- )
-
- def print_if_verbose(self, text):
- "Only print if user chooses verbose output"
- if self.verbosity > 0:
- print text
-
-
- def handle_noargs(self, **options):
- self.verbosity = int(options.get("verbosity", 1))
- self.interactive = options.get("interactive")
-
- if self.interactive:
- answer = choice_dialog("This command will DELETE ALL DATA in the current database, fill the database with test data and flush the test data. Are you absolutely sure you want to proceed?",
- choices = ("yes", "no", ))
- if answer != "yes":
- return
-
- # First, flush the data
- self.print_if_verbose("FLUSHING THE DATABASE")
- management.call_command('flush', verbosity=0, interactive=False)
-
- # Then, fill the database with test content
- self.print_if_verbose("FILLING THE DB WITH TEST CONTENT")
- management.call_command('askbot_add_test_content', verbosity=0,
- interactive=False)
-
- # At last, dump the data into a fixture
- # Create a file object ready for writing
- self.print_if_verbose("DUMPING THE DATA IN FILE '%s'" % FIXTURE_NAME)
- fixture = open(FIXTURE_NAME, 'wb')
- management.call_command('dumpdata', stdout = fixture,
- exclude = EXCLUDE_APPS, indent = 4, natural = True)
- fixture.close()
-
- # FLUSH AGAIN
- self.print_if_verbose("FLUSHING THE DATABASE")
- management.call_command('flush', verbosity=0, interactive=False)
-
- self.print_if_verbose("You can load this data now by invoking ./manage.py %s" % FIXTURE_NAME)
-
-
diff --git a/askbot/management/commands/fix_revisionless_posts.py b/askbot/management/commands/fix_revisionless_posts.py
index 9535bef3..69520157 100644
--- a/askbot/management/commands/fix_revisionless_posts.py
+++ b/askbot/management/commands/fix_revisionless_posts.py
@@ -14,9 +14,9 @@ def fix_revisionless_posts(post_class):
print 'have %d corrupted posts' % len(posts)
for post in posts:
post.add_revision(
- author = post.author,
- text = post.text,
- comment = const.POST_STATUS['default_version'],
+ author=post.author,
+ text=post.text,
+ comment=unicode(const.POST_STATUS['default_version']),
revised_at = post.added_at
)
post.last_edited_at = None
diff --git a/askbot/management/commands/send_accept_answer_reminders.py b/askbot/management/commands/send_accept_answer_reminders.py
index 119d7611..2b8b0851 100644
--- a/askbot/management/commands/send_accept_answer_reminders.py
+++ b/askbot/management/commands/send_accept_answer_reminders.py
@@ -1,6 +1,7 @@
import datetime
from django.core.management.base import NoArgsCommand
from django.conf import settings as django_settings
+from django.template.loader import get_template
from askbot import models
from askbot import const
from askbot.conf import settings as askbot_settings
@@ -8,7 +9,6 @@ from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
from askbot import mail
from askbot.utils.classes import ReminderSchedule
-from askbot.skins.loaders import get_template
from django.template import Context
DEBUG_THIS_COMMAND = False
@@ -73,7 +73,7 @@ class Command(NoArgsCommand):
}
template = get_template('email/accept_answer_reminder.html')
- body_text = template.render(Context(data))
+ body_text = template.render(Context(data))#todo: set lang
if DEBUG_THIS_COMMAND:
print "User: %s<br>\nSubject:%s<br>\nText: %s<br>\n" % \
diff --git a/askbot/management/commands/send_unanswered_question_reminders.py b/askbot/management/commands/send_unanswered_question_reminders.py
index 3fa390ad..982dbafb 100644
--- a/askbot/management/commands/send_unanswered_question_reminders.py
+++ b/askbot/management/commands/send_unanswered_question_reminders.py
@@ -1,4 +1,5 @@
from django.core.management.base import NoArgsCommand
+from django.template.loader import get_template
from askbot import models
from askbot import const
from askbot.conf import settings as askbot_settings
@@ -6,7 +7,6 @@ from django.utils.translation import ungettext
from askbot import mail
from askbot.utils.classes import ReminderSchedule
from askbot.models.question import Thread
-from askbot.skins.loaders import get_template
from django.template import Context
DEBUG_THIS_COMMAND = False
@@ -78,7 +78,7 @@ class Command(NoArgsCommand):
}
template = get_template('email/unanswered_question_reminder.html')
- body_text = template.render(Context(data))
+ body_text = template.render(Context(data))#todo: set lang
if DEBUG_THIS_COMMAND:
diff --git a/askbot/media/images/ajax-loader.gif b/askbot/media/images/ajax-loader.gif
new file mode 100644
index 00000000..212a8197
--- /dev/null
+++ b/askbot/media/images/ajax-loader.gif
Binary files differ
diff --git a/askbot/media/images/delete.png b/askbot/media/images/delete.png
index 9263eae3..90349e69 100644
--- a/askbot/media/images/delete.png
+++ b/askbot/media/images/delete.png
Binary files differ
diff --git a/askbot/media/images/edit2.png b/askbot/media/images/edit2.png
index f142a68c..e683fddf 100644
--- a/askbot/media/images/edit2.png
+++ b/askbot/media/images/edit2.png
Binary files differ
diff --git a/askbot/media/images/flag.png b/askbot/media/images/flag.png
index fc302335..f9d8f0c0 100644
--- a/askbot/media/images/flag.png
+++ b/askbot/media/images/flag.png
Binary files differ
diff --git a/askbot/media/images/link.png b/askbot/media/images/link.png
index 6ad60f5e..7dd90f10 100644
--- a/askbot/media/images/link.png
+++ b/askbot/media/images/link.png
Binary files differ
diff --git a/askbot/media/images/sprites.png b/askbot/media/images/sprites.png
index c4e9029c..4f23e088 100644
--- a/askbot/media/images/sprites.png
+++ b/askbot/media/images/sprites.png
Binary files differ
diff --git a/askbot/media/jquery-openid/images/launchpad.gif b/askbot/media/jquery-openid/images/launchpad.gif
new file mode 100644
index 00000000..af277ad8
--- /dev/null
+++ b/askbot/media/jquery-openid/images/launchpad.gif
Binary files differ
diff --git a/askbot/media/jquery-openid/images/launchpad.xcf b/askbot/media/jquery-openid/images/launchpad.xcf
new file mode 100644
index 00000000..f275c204
--- /dev/null
+++ b/askbot/media/jquery-openid/images/launchpad.xcf
Binary files differ
diff --git a/askbot/media/jquery-openid/jquery.openid.js b/askbot/media/jquery-openid/jquery.openid.js
index 249413b9..881b2098 100644
--- a/askbot/media/jquery-openid/jquery.openid.js
+++ b/askbot/media/jquery-openid/jquery.openid.js
@@ -405,12 +405,7 @@ $.fn.authenticator = function() {
);
setup_event_handlers(
- signin_page.find('input.facebook'),
- start_facebook_login
- );
-
- setup_event_handlers(
- signin_page.find('input.oauth'),
+ signin_page.find('input.oauth,input.oauth2'),
start_simple_login
);
diff --git a/askbot/media/js/group_messaging.js b/askbot/media/js/group_messaging.js
index 2522f72e..30519f1f 100644
--- a/askbot/media/js/group_messaging.js
+++ b/askbot/media/js/group_messaging.js
@@ -265,15 +265,19 @@ NewThreadComposer.prototype.onAfterShow = function() {
NewThreadComposer.prototype.onSendErrorInternal = function(data) {
var missingUsers = data['missing_users']
+ var errors = [];
if (missingUsers) {
var errorTpl = ngettext(
'user {{str}} does not exist',
'users {{str}} do not exist',
missingUsers.length
)
- error = errorTpl.replace('{{str}}', joinAsPhrase(missingUsers));
- this._toInputError.html(error);
+ errors.push(errorTpl.replace('{{str}}', joinAsPhrase(missingUsers)));
}
+ if (data['self_message']) {
+ errors.push(gettext('cannot send message to yourself'));
+ }
+ this._toInputError.html(errors.join(', '));
};
NewThreadComposer.prototype.getInputData = function() {
@@ -331,6 +335,14 @@ var ThreadHeading = function() {
};
inherits(ThreadHeading, SimpleControl);
+ThreadHeading.prototype.setParent = function(elem) {
+ this._threadsList = elem;
+};
+
+ThreadHeading.prototype.getParent = function() {
+ return this._threadsList;
+};
+
ThreadHeading.prototype.getId = function() {
return this._id;
};
@@ -338,6 +350,12 @@ ThreadHeading.prototype.getId = function() {
ThreadHeading.prototype.decorate = function(element) {
this._element = element;
this._id = element.data('threadId');
+ var deleter = element.find('.delete-or-restore');
+ var me = this;
+ setupButtonEventHandlers($(deleter), function() {
+ me.getParent().deleteOrRestoreThread(me.getId());
+ return false;
+ });
};
/**
@@ -359,12 +377,17 @@ ThreadsList.prototype.getOpenThreadHandler = function(threadId) {
};
};
-ThreadsList.prototype.setHTML = function(html) {
- $.each(this._threads, function(idx, thread) {
- thread.dispose();
- });
- this._element.html(html);
- this.decorate(this._element);
+ThreadsList.prototype.deleteOrRestoreThread = function(threadId) {
+ var ctr = this._messageCenter;
+ ctr.deleteOrRestoreThread(threadId, this._senderId);
+};
+
+ThreadsList.prototype.getThreadsCount = function() {
+ if (self._threads) {
+ return self._threads.length;
+ } else {
+ return 0;
+ }
};
ThreadsList.prototype.decorate = function(element) {
@@ -374,12 +397,14 @@ ThreadsList.prototype.decorate = function(element) {
var threads = [];
$.each(headingElements, function(idx, headingElement) {
var heading = new ThreadHeading();
+ heading.setParent(me);
heading.decorate($(headingElement));
var threadId = heading.getId();
heading.setHandler(me.getOpenThreadHandler(threadId));
threads.push(heading);
});
this._threads = threads;
+ this._senderId = element.data('senderId');
}
@@ -443,16 +468,31 @@ ThreadContainer.prototype.setReplyUrl = function(url) {
this._replyUrl = url;
};
+ThreadContainer.prototype.appendEditor = function() {
+ var editor = new ReplyComposer();
+ editor.setSendUrl(this._replyUrl);
+ this._element.append(editor.getElement());
+ this._editor = editor;
+ editor.show();
+};
+
ThreadContainer.prototype.createDom = function() {
this._element = this.makeElement('div');
var content = this.makeElement('div');
this._contentElement = content;
this._element.append(content);
+ this.appendEditor();
+};
- var editor = new ReplyComposer();
- editor.setSendUrl(this._replyUrl);
- this._element.append(editor.getElement());
- this._editor = editor;
+ThreadContainer.prototype.decorate = function(element) {
+ this._element = element;
+ this._contentElement = $(element.children()[0]);
+ var thread = new Thread();
+ thread.decorate(element.find('.thread'));
+ this.appendEditor();
+ var postData = {parent_id: thread.getLastMessageId()};
+ this._editor.setPostData(postData);
+ this._editor.setThread(thread);
};
@@ -570,6 +610,7 @@ SendersList.prototype.decorate = function(element) {
*/
var MessageCenter = function() {
Widget.call(this);
+ this._loadingStatus = false;//true when loading in is process
};
inherits(MessageCenter, Widget);
@@ -604,23 +645,53 @@ MessageCenter.prototype.openThread = function(threadId) {
});
};
-MessageCenter.prototype.loadThreadsForSender = function(senderId) {
+MessageCenter.prototype.setThreadsList = function(list) {
+ this._threadsList = list;
+ this._secondCol.prepend(list.getElement());
+};
+
+MessageCenter.prototype.setLoadingStatus = function(loadingStatus) {
+ this._loadingStatus = loadingStatus;
+};
+
+MessageCenter.prototype.hitThreadsList = function(url, senderId, requestMethod) {
+ if (this._loadingStatus === true) {
+ return;
+ };
var threadsList = this._threadsList;
- var url = this._urls['getThreads'];
- me = this;
+ var me = this;
$.ajax({
- type: 'GET',
+ type: requestMethod,
dataType: 'json',
url: url,
cache: false,
data: {sender_id: senderId},
success: function(data) {
if (data['success']) {
- threadsList.setHTML(data['html']);
+ threadsList.dispose();
+ var threads = new ThreadsList();
+ threads.setMessageCenter(me);
+ threads.decorate($(data['html']));
+ me.setThreadsList(threads);
me.setState('show-list');
+ me.setLoadingStatus(false);
+ },
+ error: function() {
+ me.setLoadingStatus(false);
}
}
});
+ this.setLoadingStatus(true);
+};
+
+MessageCenter.prototype.deleteOrRestoreThread = function(threadId, senderId) {
+ var url = this._urls['getThreads'] + threadId + '/delete-or-restore/';
+ this.hitThreadsList(url, senderId, 'POST');
+};
+
+MessageCenter.prototype.loadThreadsForSender = function(senderId) {
+ var url = this._urls['getThreads'];
+ this.hitThreadsList(url, senderId, 'GET');
};
MessageCenter.prototype.decorate = function(element) {
@@ -644,19 +715,31 @@ MessageCenter.prototype.decorate = function(element) {
threads.setMessageCenter(this);
threads.decorate($('.threads-list'));
this._threadsList = threads;
- //add empty thread container
+ //add empty thread container or decorate existing one
var threadContainer = new ThreadContainer();
this._threadContainer = threadContainer;
threadContainer.setReplyUrl(this._urls['reply']);
- this._secondCol.append(threadContainer.getElement());
+
+ var threadElement = $('.thread').parent().parent();
+ if (threadElement.length) {
+ threadContainer.decorate(threadElement);
+ } else {
+ this._secondCol.append(threadContainer.getElement());
+ threadContainer.hide();
+ }
var me = this;
//create editor
var editor = new NewThreadComposer();
this._secondCol.append(editor.getElement());
editor.setSendUrl(element.data('createThreadUrl'));
- editor.onAfterCancel(function() { me.setState('show-list') });
+ editor.onAfterCancel(function() {
+ me.setState('show-list')
+ });
editor.onSendSuccess(function() {
+ if (threads.getThreadsCount() === 0) {
+ me.loadThreadsForSender(-1);
+ }
editor.cancel();
notify.show(gettext('message sent'), true);
});
diff --git a/askbot/media/js/live_search.js b/askbot/media/js/live_search.js
index f7d89c2a..99ffade4 100644
--- a/askbot/media/js/live_search.js
+++ b/askbot/media/js/live_search.js
@@ -1,3 +1,214 @@
+var SearchDropMenu = function() {
+ WrappedElement.call(this);
+ this._data = undefined;
+ this._selectedItemIndex = 0;
+ this._askButtonEnabled = true;
+}
+inherits(SearchDropMenu, WrappedElement);
+
+SearchDropMenu.prototype.setData = function(data) {
+ this._data = data;
+};
+
+SearchDropMenu.prototype.setAskHandler = function(handler) {
+ this._askHandler = handler;
+};
+
+SearchDropMenu.prototype.setAskButtonEnabled = function(isEnabled) {
+ this._askButtonEnabled = isEnabled;
+};
+
+/**
+ * assumes that data is already set
+ */
+SearchDropMenu.prototype.render = function() {
+ var list = this._resultsList;
+ list.empty();
+ var me = this;
+ $.each(this._data, function(idx, item) {
+ var listItem = me.makeElement('li');
+ var link = me.makeElement('a');
+ link.attr('href', item['url']);
+ link.html(item['title']);
+ listItem.append(link);
+ list.append(listItem);
+ });
+ if (this._data.length === 0) {
+ list.addClass('empty');
+ this._element.addClass('empty');
+ } else {
+ list.removeClass('empty');
+ this._element.removeClass('empty');
+ }
+};
+
+/**
+ * @param {number} idx position of item starting from 1 for the topmost
+ * Selects item inentified by position.
+ * Scrolls the list to make top of the item visible.
+ */
+SearchDropMenu.prototype.selectItem = function(idx) {
+ //idx is 1-based index
+ this._selectedItemIndex = idx;
+ var list = this._resultsList;
+ list.find('li').removeClass('selected');
+ var item = this.getItem(idx);
+ if (item && idx > 0) {
+ item.addClass('selected');
+ var itemTopY = item.position().top;//relative to visible area
+ var curScrollTop = list.scrollTop();
+
+ /* if item is clipped on top, scroll down */
+ if (itemTopY < 0) {
+ list.scrollTop(curScrollTop + itemTopY);
+ return;
+ }
+
+ var listHeight = list.outerHeight();
+ /* pixels above the lower border of the list */
+ var itemPeepHeight = listHeight - itemTopY;
+ /* pixels below the lower border */
+ var itemSinkHeight = item.outerHeight() - itemPeepHeight;
+ if (itemSinkHeight > 0) {
+ list.scrollTop(curScrollTop + itemSinkHeight);
+ }
+ }
+
+};
+
+SearchDropMenu.prototype.getItem = function(idx) {
+ return $(this._resultsList.find('li')[idx - 1]);
+};
+
+SearchDropMenu.prototype.getItemCount = function() {
+ return this._resultsList.find('li').length;
+};
+
+SearchDropMenu.prototype.getSelectedItemIndex = function() {
+ return this._selectedItemIndex;
+};
+
+SearchDropMenu.prototype.navigateToItem = function(idx) {
+ var item = this.getItem(idx);
+ if (item) {
+ window.location.href = item.find('a').attr('href');
+ }
+};
+
+SearchDropMenu.prototype.makeKeyHandler = function() {
+ var me = this;
+ return function(e) {
+ var keyCode = getKeyCode(e);
+ if (keyCode === 27) {//escape
+ me.hide();
+ return false;
+ }
+ if (keyCode !== 38 && keyCode !== 40 && keyCode !== 13) {
+ return;
+ }
+ var itemCount = me.getItemCount();
+ if (itemCount > 0) {
+ //count is 0 with no title matches, curItem is 0 when none is selected
+ var curItem = me.getSelectedItemIndex();
+ if (keyCode === 38) {//upArrow
+ if (curItem > 0) {
+ curItem = curItem - 1;
+ }
+ } else if (keyCode === 40) {//downArrow
+ if (curItem < itemCount) {
+ curItem = curItem + 1;
+ }
+ } else if (keyCode === 13) {//enter
+ if (curItem === 0) {
+ return true;
+ } else {
+ me.navigateToItem(curItem);
+ return false;
+ }
+ }
+ me.selectItem(curItem);
+ return false
+ }
+ };
+};
+
+/** todo: change this to state management as >1 thing happens */
+SearchDropMenu.prototype.showWaitIcon = function() {
+ if (this._askButtonEnabled) {
+ this._waitIcon.show();
+ this._footer.hide();
+ this._element.addClass('empty');
+ }
+};
+
+SearchDropMenu.prototype.hideWaitIcon = function() {
+ if (this._askButtonEnabled) {
+ this._waitIcon.hide();
+ this._footer.show();
+ this._element.removeClass('empty');
+ }
+};
+
+SearchDropMenu.prototype.createDom = function() {
+ this._element = this.makeElement('div');
+ this._element.addClass('search-drop-menu');
+ this._element.hide();
+
+ this._resultsList = this.makeElement('ul');
+ this._element.append(this._resultsList);
+ this._element.addClass('empty');
+
+ var waitIcon = new WaitIcon();
+ waitIcon.hide();
+ this._element.append(waitIcon.getElement());
+ this._waitIcon = waitIcon;
+
+ //add ask button, @todo: make into separate class?
+ var footer = this.makeElement('div');
+ this._element.append(footer);
+ this._footer = footer;
+
+ if (this._askButtonEnabled) {
+ footer.addClass('footer');
+ var button = this.makeElement('button');
+ button.addClass('submit');
+ button.html(gettext('Ask Your Question'))
+ footer.append(button);
+ var handler = this._askHandler;
+ setupButtonEventHandlers(button, handler);
+ }
+
+ $(document).keydown(this.makeKeyHandler());
+};
+
+SearchDropMenu.prototype.isOpen = function() {
+ return this._element.is(':visible');
+};
+
+SearchDropMenu.prototype.show = function() {
+ var searchBar = this._element.prev();
+ var searchBarHeight = searchBar.outerHeight();
+ var topOffset = searchBar.offset().top + searchBarHeight;
+ this._element.show();//show so that size calcs work
+ var footerHeight = this._footer.outerHeight();
+ var windowHeight = $(window).height();
+ this._resultsList.css(
+ 'max-height',
+ windowHeight - topOffset - footerHeight - 40 //what is this number?
+ );
+};
+
+SearchDropMenu.prototype.hide = function() {
+ this._element.hide();
+};
+
+SearchDropMenu.prototype.reset = function() {
+ this._data = undefined;
+ this._resultsList.empty();
+ this._selectedItemIndex = 0;
+ this._element.hide();
+};
+
var TagWarningBox = function(){
WrappedElement.call(this);
this._tags = [];
@@ -6,9 +217,8 @@ inherits(TagWarningBox, WrappedElement);
TagWarningBox.prototype.createDom = function(){
this._element = this.makeElement('div');
- this._element
- .css('display', 'block')
- .css('margin', '0 0 13px 2px');
+ this._element.css('display', 'block');
+ this._element.css('margin', '0 0 13px 2px');
this._element.addClass('non-existing-tags');
this._warning = this.makeElement('p');
this._element.append(this._warning);
@@ -51,355 +261,619 @@ TagWarningBox.prototype.showWarning = function(){
this._warning.show();
};
-var liveSearch = function(query_string) {
- var query = $('input#keywords');
- var query_val = function () {return $.trim(query.val());};
- var prev_text = query_val();
- var running = false;
- var q_list_sel = 'question-list';//id of question listing div
- var search_url = askbot['urls']['questions'];
- var x_button = $('input[name=reset_query]');
- var tag_warning_box = new TagWarningBox();
+/**
+ * @constructor
+ * tool tip to be shown on top of the search input
+ */
+var InputToolTip = function() {
+ WrappedElement.call(this);
+};
+inherits(InputToolTip, WrappedElement);
- //the tag search input is optional in askbot
- $('#ab-tag-search').parent().before(
- tag_warning_box.getElement()
- );
+InputToolTip.prototype.show = function() {
+ this._element.removeClass('dimmed');
+ this._element.show();
+};
- var run_tag_search = function(){
- var search_tags = $('#ab-tag-search').val().split(/\s+/);
- if (search_tags.length === 0) {
- return;
- }
- /** @todo: the questions/ might need translation... */
- query_string = '/questions/scope:all/sort:activity-desc/page:1/'
- $.each(search_tags, function(idx, tag) {
- query_string = QSutils.add_search_tag(query_string, search_tags);
- });
- var url = search_url + query_string;
- $.ajax({
- url: url,
- dataType: 'json',
- success: function(data, text_status, xhr){
- render_result(data, text_status, xhr);
- $('#ab-tag-search').val('');
- },
- });
- updateHistory(url);
- };
+InputToolTip.prototype.hide = function() {
+ this._element.removeClass('dimmed');
+ this._element.hide();
+};
- var activate_tag_search_input = function(){
- //the autocomplete is set up in tag_selector.js
- var button = $('#ab-tag-search-add');
- if (button.length === 0){//may be absent
- return;
- }
- var ac = new AutoCompleter({
- url: askbot['urls']['get_tag_list'],
- preloadData: true,
- minChars: 1,
- useCache: true,
- matchInside: true,
- maxCacheLength: 100,
- maxItemsToShow: 20,
- onItemSelect: run_tag_search,
- delay: 10
- });
- ac.decorate($('#ab-tag-search'));
- setupButtonEventHandlers(button, run_tag_search);
- //var tag_search_input = $('#ab-tag-search');
- //tag_search_input.keydown(
- // makeKeyHandler(13, run_tag_search)
- //);
- };
+InputToolTip.prototype.dim = function() {
+ this._element.addClass('dimmed');
+};
- var render_tag_warning = function(tag_list){
- if ( !tag_list ) {
- return;
- }
- tag_warning_box.clear();
- $.each(tag_list, function(idx, tag_name){
- tag_warning_box.addTag(tag_name);
- });
- tag_warning_box.showWarning();
- };
+InputToolTip.prototype.setClickHandler = function(handler) {
+ this._clickHandler = handler;
+};
- var refresh_x_button = function(){
- if(query_val().length > 0){
- if (query.hasClass('searchInput')){
- query.attr('class', 'searchInputCancelable');
- x_button.show();
- }
- } else {
- x_button.hide();
- query.attr('class', 'searchInput');
- }
- };
+InputToolTip.prototype.createDom = function() {
+ var element = this.makeElement('div');
+ this._element = element;
- var restart_query = function() {
- sortMethod = 'activity-desc';
- query.val('');
- refresh_x_button();
- send_query();
- };
+ element.html(gettext('search or ask your question'));
+ element.addClass('input-tool-tip');
- var eval_query = function(){
- cur_query = query_val();
- if (cur_query !== prev_text && running === false){
- if (cur_query.length >= minSearchWordLength){
- send_query(cur_query);
- } else if (cur_query.length === 0){
- restart_query();
- }
+ var handler = this._clickHandler;
+ var me = this;
+ element.click(function() {
+ handler();
+ me.dim();
+ return false;
+ });
+ $(document).click(function() {
+ if (element.css('display') === 'block') {
+ element.removeClass('dimmed');
}
- };
+ });
+};
+
+
+/**
+ * @constructor
+ * provides full text search functionality
+ * which re-draws contents of the main page
+ * in response to the search query
+ */
+var FullTextSearch = function() {
+ WrappedElement.call(this);
+ this._running = false;
+ this._baseUrl = askbot['urls']['questions'];
+ this._q_list_sel = 'question-list';//id of question listing div
+ /** @todo: the questions/ needs translation... */
+ this._searchUrl = '/scope:all/sort:activity-desc/page:1/'
+ this._askButtonEnabled = true;
+};
+inherits(FullTextSearch, WrappedElement);
+
+/**
+ * @param {{boolean=}} optional, if given then function is setter
+ * otherwise it is a getter
+ * isRunning returns `true` when search is running
+ */
+FullTextSearch.prototype.isRunning = function(val) {
+ if (val === undefined) {
+ return this._running;
+ } else {
+ this._running = val;
+ }
+};
- var update_query_string = function(query_text){
- if(query_text === undefined) { // handle missing parameter
- query_text = query_val();
- }
- query_string = QSutils.patch_query_string(
- query_string,
- 'query:' + encodeURIComponent(query_text),
- query_text === '' // remove if empty
- );
- return query_text;
- };
+FullTextSearch.prototype.setAskButtonEnabled = function(isEnabled) {
+ this._askButtonEnabled = isEnabled;
+}
- var send_query = function(query_text){
- running = true;
- if(!prev_text && query_text && showSortByRelevance) {
- // If there was no query but there is some query now - and we support relevance search - then switch to it */
- query_string = QSutils.patch_query_string(query_string, 'sort:relevance-desc');
- }
- prev_text = update_query_string(query_text);
- query_string = QSutils.patch_query_string(query_string, 'page:1'); /* if something has changed, then reset the page no. */
- var url = search_url + query_string;
- $.ajax({
- url: url,
- dataType: 'json',
- success: render_result,
- complete: function(){
- running = false;
- eval_query();
- },
- cache: false
- });
- updateHistory(url);
- };
+/**
+ * @param {{string}} url for the page displaying search results
+ */
+FullTextSearch.prototype.setSearchUrl = function(url) {
+ this._searchUrl = url;
+};
- var updateHistory = function(url) {
- var context = { state:1, rand:Math.random() };
- History.pushState( context, "Questions", url );
- setTimeout(function (){
- /* HACK: For some weird reson, sometimes something overrides the above pushState so we re-aplly it
- This might be caused by some other JS plugin.
- The delay of 10msec allows the other plugin to override the URL.
- */
- History.replaceState( context, "Questions", url );
- }, 10);
- };
+FullTextSearch.prototype.getSearchUrl = function() {
+ return this._searchUrl;
+};
- /* *********************************** */
+FullTextSearch.prototype.renderTagWarning = function(tag_list){
+ if ( !tag_list ) {
+ return;
+ }
+ var tagWarningBox = this._tag_warning_box;
+ tagWarningBox.clear();
+ $.each(tag_list, function(idx, tag_name){
+ tagWarningBox.addTag(tag_name);
+ });
+ tagWarningBox.showWarning();
+};
- var render_related_tags = function(tags, query_string){
- if (tags.length === 0) return;
+FullTextSearch.prototype.runTagSearch = function() {
+ var search_tags = $('#ab-tag-search').val().split(/\s+/);
+ if (search_tags.length === 0) {
+ return;
+ }
+ var searchUrl = this.getSearchUrl();
+ //add all tags to the url
+ searchUrl = QSutils.add_search_tag(searchUrl, search_tags);
+ var url = this._baseUrl + searchUrl;
+ var me = this;
+ $.ajax({
+ url: url,
+ dataType: 'json',
+ success: function(data, text_status, xhr){
+ me.renderFullTextResult(data, text_status, xhr);
+ $('#ab-tag-search').val('');
+ },
+ });
+ this.updateHistory(url);
+};
- var html_list = [];
- for (var i=0; i<tags.length; i++){
- var tag = new Tag();
- tag.setName(tags[i]['name']);
- tag.setDeletable(false);
- tag.setLinkable(true);
- tag.setUrlParams(query_string);
-
- html_list.push(tag.getElement().outerHTML());
- html_list.push('<span class="tag-number">&#215; ');
- html_list.push(tags[i]['used_count']);
- html_list.push('</span>');
- html_list.push('<br />');
+FullTextSearch.prototype.updateHistory = function(url) {
+ var context = { state:1, rand:Math.random() };
+ History.pushState( context, "Questions", url );
+ setTimeout(function(){
+ /* HACK: For some weird reson, sometimes
+ * overrides the above pushState so we re-aplly it
+ * This might be caused by some other JS plugin.
+ * The delay of 10msec allows the other plugin to override the URL.
+ */
+ History.replaceState(context, "Questions", url);
+ },
+ 10
+ );
+};
+
+FullTextSearch.prototype.activateTagSearchInput = function() {
+ //the autocomplete is set up in tag_selector.js
+ var button = $('#ab-tag-search-add');
+ if (button.length === 0){//may be absent
+ return;
+ }
+ var me = this;
+ var ac = new AutoCompleter({
+ url: askbot['urls']['get_tag_list'],
+ preloadData: true,
+ minChars: 1,
+ useCache: true,
+ matchInside: true,
+ maxCacheLength: 100,
+ maxItemsToShow: 20,
+ onItemSelect: function(){ this.runTagSearch(); },
+ delay: 10
+ });
+ ac.decorate($('#ab-tag-search'));
+ setupButtonEventHandlers(
+ button,
+ function() { me.runTagSearch() }
+ );
+};
+
+FullTextSearch.prototype.sendTitleSearchQuery = function(query_text) {
+ this.isRunning(true);
+ this._prevText = query_text;
+ var data = {query_text: query_text};
+ var me = this;
+ $.ajax({
+ url: askbot['urls']['titleSearch'],
+ data: data,
+ dataType: 'json',
+ success: function(data, text_status, xhr){
+ me.renderTitleSearchResult(data, text_status, xhr);
+ },
+ complete: function(){
+ me.isRunning(false);
+ me.evalTitleSearchQuery();
+ },
+ cache: false
+ });
+};
+
+
+FullTextSearch.prototype.sendFullTextSearchQuery = function(query_text) {
+ this.isRunning(true);
+ var searchUrl = this.getSearchUrl();
+ var prevText = this._prevText;
+ if(!prevText && query_text && askbot['settings']['showSortByRelevance']) {
+ /* If there was no query but there is some
+ * query now - and we support relevance search
+ * - then switch to it
+ */
+ searchUrl = QSutils.patch_query_string(
+ searchUrl, 'sort:relevance-desc'
+ );
+ }
+ this._prevText = this.updateQueryString(query_text);
+
+ /* if something has changed, then reset the page no. */
+ searchUrl = QSutils.patch_query_string(searchUrl, 'page:1');
+ var url = this._baseUrl + searchUrl;
+ var me = this;
+ $.ajax({
+ url: url,
+ dataType: 'json',
+ success: function(data, text_status, xhr){
+ me.renderFullTextSearchResult(data, text_status, xhr);
+ },
+ complete: function(){
+ me.isRunning(false);
+ },
+ cache: false
+ });
+ this.updateHistory(url);
+};
+
+FullTextSearch.prototype.refresh = function() {
+ this.sendFullTextSearchQuery();/* used for tag search, maybe not necessary */
+};
+
+FullTextSearch.prototype.getSearchQuery = function() {
+ return $.trim(this._query.val());
+};
+
+/**
+ * renders title search result in the dropdown under the search input
+ */
+FullTextSearch.prototype.renderTitleSearchResult = function(data) {
+ var menu = this._dropMenu;
+ menu.hideWaitIcon();
+ menu.setData(data);
+ menu.render();
+ menu.show();
+};
+
+FullTextSearch.prototype.renderFullTextSearchResult = function(data) {
+ if (data['questions'].length === 0) {
+ return;
+ }
+
+ $('#pager').toggle(data['paginator'] !== '').html(data['paginator']);
+ $('#questionCount').html(data['question_counter']);
+ this.renderSearchTags(data['query_data']['tags'], data['query_string']);
+ if(data['faces'].length > 0) {
+ $('#contrib-users > a').remove();
+ $('#contrib-users').append(data['faces'].join(''));
+ }
+ this.renderRelatedTags(data['related_tags'], data['query_string']);
+ this.renderRelevanceSortTab(data['query_string']);
+ this.renderTagWarning(data['non_existing_tags']);
+ this.setActiveSortTab(
+ data['query_data']['sort_order'],
+ data['query_string']
+ );
+ if(data['feed_url']){
+ // Change RSS URL
+ $("#ContentLeft a.rss:first").attr("href", data['feed_url']);
+ }
+
+ // Patch scope selectors
+ var baseUrl = this._baseUrl;
+ $('#scopeWrapper > a.scope-selector').each(function(index) {
+ var old_qs = $(this).attr('href').replace(baseUrl, '');
+ var scope = QSutils.get_query_string_selector_value(old_qs, 'scope');
+ qs = QSutils.patch_query_string(data['query_string'], 'scope:' + scope);
+ $(this).attr('href', baseUrl + qs);
+ });
+
+ // Patch "Ask your question"
+ var askButton = $('#askButton');
+ var askHrefBase = askButton.attr('href').split('?')[0];
+ askButton.attr(
+ 'href',
+ askHrefBase + data['query_data']['ask_query_string']
+ ); /* INFO: ask_query_string should already be URL-encoded! */
+
+ this._query.focus();
+
+ var old_list = $('#' + this._q_list_sel);
+ var new_list = $('<div></div>').hide().html(data['questions']);
+ new_list.find('.timeago').timeago();
+
+ var q_list_sel = this._q_list_sel;
+ old_list.stop(true).after(new_list).fadeOut(200, function() {
+ //show new div with a fadeIn effect
+ old_list.remove();
+ new_list.attr('id', q_list_sel);
+ new_list.fadeIn(400);
+ });
+};
+
+FullTextSearch.prototype.evalTitleSearchQuery = function() {
+ var cur_query = this.getSearchQuery();
+ var prevText = this._prevText;
+ if (cur_query !== prevText && this.isRunning() === false){
+ if (cur_query.length >= askbot['settings']['minSearchWordLength']){
+ this.sendTitleSearchQuery(cur_query);
+ } else if (cur_query.length === 0){
+ this.reset();
}
- $('#related-tags').html(html_list.join(''));
- };
+ }
+};
- var render_search_tags = function(tags, query_string){
- var search_tags = $('#searchTags');
- search_tags.empty();
- if (tags.length === 0){
- $('#listSearchTags').hide();
- $('#search-tips').hide();//wrong - if there are search users
- } else {
- $('#listSearchTags').show();
- $('#search-tips').show();
- $.each(tags, function(idx, tag_name){
- var tag = new Tag();
- tag.setName(tag_name);
- tag.setLinkable(false);
- tag.setDeletable(true);
- tag.setDeleteHandler(
- function(){
- remove_search_tag(tag_name, query_string);
- }
- );
- search_tags.append(tag.getElement());
- });
+FullTextSearch.prototype.reset = function() {
+ this._prevText = '';
+ this._dropMenu.reset();
+ this._element.val('');
+ this._element.focus();
+ this._xButton.hide();
+ this._toolTip.show();
+};
+
+FullTextSearch.prototype.refreshXButton = function() {
+ if(this.getSearchQuery().length > 0){
+ if (this._query.hasClass('searchInput')){
+ $('#searchBar').attr('class', 'cancelable');
+ this._xButton.show();
}
- };
+ } else {
+ this._xButton.hide();
+ $('#searchBar').removeClass('cancelable');
+ }
+};
- var create_relevance_tab = function(query_string){
- relevance_tab = $('<a></a>');
- href = search_url + QSutils.patch_query_string(query_string, 'sort:relevance-desc');
- relevance_tab.attr('href', href);
- relevance_tab.attr('id', 'by_relevance');
- relevance_tab.html('<span>' + sortButtonData['relevance']['label'] + '</span>');
- return relevance_tab;
- };
+FullTextSearch.prototype.updateQueryString = function(query_text) {
+ if (query_text === undefined) { // handle missing parameter
+ query_text = this.getSearchQuery();
+ }
+ var newUrl = QSutils.patch_query_string(
+ this._searchUrl,
+ 'query:' + encodeURIComponent(query_text),
+ query_text === '' // remove if empty
+ );
+ this.setSearchUrl(newUrl);
+ return query_text;
+};
- /* *************************************** */
+FullTextSearch.prototype.renderRelatedTags = function(tags, query_string){
+ if (tags.length === 0) return;
- var remove_search_tag = function(tag){
- query_string = QSutils.remove_search_tag(query_string, tag);
- send_query();
- };
+ var html_list = [];
+ for (var i=0; i<tags.length; i++){
+ var tag = new Tag();
+ tag.setName(tags[i]['name']);
+ tag.setDeletable(false);
+ tag.setLinkable(true);
+ tag.setUrlParams(query_string);
+
+ html_list.push(tag.getElement().outerHTML());
+ html_list.push('<span class="tag-number">&#215; ');
+ html_list.push(tags[i]['used_count']);
+ html_list.push('</span>');
+ html_list.push('<br />');
+ }
+ $('#related-tags').html(html_list.join(''));
+};
- var set_active_sort_tab = function(sort_method, query_string){
- var tabs = $('#sort_tabs > a');
- tabs.attr('class', 'off');
- tabs.each(function(index, element){
- var tab = $(element);
- if ( tab.attr('id') ) {
- var tab_name = tab.attr('id').replace(/^by_/,'');
- if (tab_name in sortButtonData){
- href = search_url + QSutils.patch_query_string(
- query_string,
- 'sort:' + tab_name + '-desc'
- );
- tab.attr('href', href);
- tab.attr('title', sortButtonData[tab_name]['desc_tooltip']);
- tab.html(sortButtonData[tab_name]['label']);
+FullTextSearch.prototype.renderSearchTags = function(tags, query_string){
+ var search_tags = $('#searchTags');
+ search_tags.empty();
+ var me = this;
+ if (tags.length === 0){
+ $('#listSearchTags').hide();
+ $('#search-tips').hide();//wrong - if there are search users
+ } else {
+ $('#listSearchTags').show();
+ $('#search-tips').show();
+ $.each(tags, function(idx, tag_name){
+ var tag = new Tag();
+ tag.setName(tag_name);
+ tag.setLinkable(false);
+ tag.setDeletable(true);
+ tag.setDeleteHandler(
+ function(){
+ me.removeSearchTag(tag_name, query_string);
}
- }
+ );
+ search_tags.append(tag.getElement());
});
- var bits = sort_method.split('-', 2);
- var name = bits[0];
- var sense = bits[1];//sense of sort
- var antisense = (sense == 'asc' ? 'desc':'asc');
- var arrow = (sense == 'asc' ? ' &#9650;':' &#9660;');
- var active_tab = $('#by_' + name);
- active_tab.attr('class', 'on');
- active_tab.attr('title', sortButtonData[name][antisense + '_tooltip']);
- active_tab.html(sortButtonData[name]['label'] + arrow);
- };
+ }
+};
- var render_relevance_sort_tab = function(query_string){
- if (showSortByRelevance === false){
- return;
- }
- var relevance_tab = $('#by_relevance');
- if (prev_text && prev_text.length > 0){
- if (relevance_tab.length == 0){
- relevance_tab = create_relevance_tab(query_string);
- $('#sort_tabs>span').after(relevance_tab);
+FullTextSearch.prototype.createRelevanceTab = function(query_string){
+ var relevance_tab = $('<a></a>');
+ href = this._baseUrl + QSutils.patch_query_string(query_string, 'sort:relevance-desc');
+ relevance_tab.attr('href', href);
+ relevance_tab.attr('id', 'by_relevance');
+ relevance_tab.html(
+ '<span>' + askbot['data']['sortButtonData']['relevance']['label'] + '</span>'
+ );
+ return relevance_tab;
+};
+
+FullTextSearch.prototype.removeSearchTag = function(tag) {
+ var searchUrl = this.getSearchUrl()
+ searchUrl = QSutils.remove_search_tag(searchUrl, tag);
+ this.setSearchUrl(searchUrl);
+ this.sendFullTextSearchQuery();
+};
+
+FullTextSearch.prototype.setActiveSortTab = function(sort_method, query_string){
+ var tabs = $('#sort_tabs > a');
+ tabs.attr('class', 'off');
+ var baseUrl = this._baseUrl;
+ tabs.each(function(index, element){
+ var tab = $(element);
+ if ( tab.attr('id') ) {
+ var tab_name = tab.attr('id').replace(/^by_/,'');
+ if (tab_name in askbot['data']['sortButtonData']){
+ href = baseUrl + QSutils.patch_query_string(
+ query_string,
+ 'sort:' + tab_name + '-desc'
+ );
+ tab.attr('href', href);
+ tab.attr(
+ 'title',
+ askbot['data']['sortButtonData'][tab_name]['desc_tooltip']
+ );
+ tab.html(
+ askbot['data']['sortButtonData'][tab_name]['label']
+ );
}
}
- else {
- if (relevance_tab.length > 0){
- relevance_tab.remove();
- }
+ });
+ var bits = sort_method.split('-', 2);
+ var name = bits[0];
+ var sense = bits[1];//sense of sort
+ var antisense = (sense == 'asc' ? 'desc':'asc');
+ var arrow = (sense == 'asc' ? ' &#9650;':' &#9660;');
+ var active_tab = $('#by_' + name);
+ active_tab.attr('class', 'on');
+ active_tab.attr(
+ 'title',
+ askbot['data']['sortButtonData'][name][antisense + '_tooltip']
+ );
+ active_tab.html(
+ askbot['data']['sortButtonData'][name]['label'] + arrow
+ );
+};
+
+FullTextSearch.prototype.renderRelevanceSortTab = function(query_string) {
+ if (askbot['settings']['showSortByRelevance'] === false){
+ return;
+ }
+ var relevance_tab = $('#by_relevance');
+ var prevText = this._prevText;
+ if (prevText && prevText.length > 0){
+ if (relevance_tab.length == 0){
+ relevance_tab = this.createRelevanceTab(query_string);
+ $('#sort_tabs>span').after(relevance_tab);
+ }
+ } else {
+ if (relevance_tab.length > 0){
+ relevance_tab.remove();
}
+ }
+};
+
+FullTextSearch.prototype.makeAskHandler = function() {
+ var me = this;
+ return function() {
+ var query = me.getSearchQuery();
+ window.location.href = askbot['urls']['ask'] + '?title=' + query;
+ return false;
};
+};
- var render_result = function(data, text_status, xhr){
- if (data['questions'].length > 0){
- $('#pager').toggle(data['paginator'] !== '').html(data['paginator']);
- $('#questionCount').html(data['question_counter']);
- render_search_tags(data['query_data']['tags'], data['query_string']);
- if(data['faces'].length > 0) {
- $('#contrib-users > a').remove();
- $('#contrib-users').append(data['faces'].join(''));
- }
- render_related_tags(data['related_tags'], data['query_string']);
- render_relevance_sort_tab(data['query_string']);
- render_tag_warning(data['non_existing_tags']);
- set_active_sort_tab(data['query_data']['sort_order'], data['query_string']);
- if(data['feed_url']){
- // Change RSS URL
- $("#ContentLeft a.rss:first").attr("href", data['feed_url']);
+FullTextSearch.prototype.updateToolTip = function() {
+ var query = this.getSearchQuery();
+ if (query === '') {
+ this._toolTip.show();
+ } else {
+ this._toolTip.hide();
+ }
+};
+
+/**
+ * keydown handler operates on the tooltip and the X button
+ * also opens and closes drop menu according to the min search word threshold
+ * keyup is not good enough, because in that case
+ * tooltip will be displayed with the input box simultaneously
+ */
+FullTextSearch.prototype.makeKeyDownHandler = function() {
+ var me = this;
+ var toolTip = this._toolTip;
+ var xButton = this._xButton;
+ var dropMenu = this._dropMenu;
+ var formSubmitHandler = this.makeFormSubmitHandler();
+ return function(e) {//don't like the keyup delay to
+ var keyCode = getKeyCode(e);
+
+ if (keyCode === 27) {//escape key
+ if (dropMenu.isOpen() === false) {
+ me.reset();
+ return false;
}
+ } else if (keyCode === 13) {
+ formSubmitHandler(e);
+ return false;
+ }
- // Patch scope selectors
- $('#scopeWrapper > a.scope-selector').each(function(index) {
- var old_qs = $(this).attr('href').replace(search_url, '');
- var scope = QSutils.get_query_string_selector_value(old_qs, 'scope');
- qs = QSutils.patch_query_string(data['query_string'], 'scope:' + scope);
- $(this).attr('href', search_url + qs);
- });
-
- // Patch "Ask your question"
- var askButton = $('#askButton');
- var askHrefBase = askButton.attr('href').split('?')[0];
- askButton.attr('href', askHrefBase + data['query_data']['ask_query_string']); /* INFO: ask_query_string should already be URL-encoded! */
-
- query.focus();
-
- var old_list = $('#' + q_list_sel);
- var new_list = $('<div></div>').hide().html(data['questions']);
- new_list.find('.timeago').timeago();
- old_list.stop(true).after(new_list).fadeOut(200, function() {
- //show new div with a fadeIn effect
- old_list.remove();
- new_list.attr('id', q_list_sel);
- new_list.fadeIn(400);
- });
+ var query = me.getSearchQuery();
+ if (query.length === 0) {
+ if (keyCode !== 8 && keyCode !== 48) {//del and backspace
+ toolTip.hide();//hide tooltip
+ }
+ } else {
+ me.updateToolTip();
+ me.refreshXButton();
+ var minQueryLength = askbot['settings']['minSearchWordLength'];
+ if (query.length === minQueryLength) {
+ if (keyCode !== 8 && keyCode !== 48) {//del and backspace
+ /* we get here if we were expanding the query
+ past the minimum length to trigger search */
+ dropMenu.show();
+ dropMenu.showWaitIcon();
+ } else {
+ //close drop menu if we were deleting the query
+ dropMenu.reset();
+ }
+ }
}
};
+};
+
+FullTextSearch.prototype.makeFormSubmitHandler = function() {
+ var me = this;
+ var baseUrl = me._baseUrl;
+ return function(evt) {
+ // if user clicks the button the s(h)e probably wants page reload,
+ // so provide that experience but first update the query string
+ me.updateQueryString();
+ var searchUrl = me.getSearchUrl();
+ evt.preventDefault();
+ window.location.href = baseUrl + searchUrl;
+ };
+};
+
+FullTextSearch.prototype.decorate = function(element) {
+ this._element = element;/* this is a bit artificial we don't use _element */
+ this._query = element;
+ this._xButton = $('input[name=reset_query]');
+ this._prevText = this.getSearchQuery();
+ this._tag_warning_box = new TagWarningBox();
+
+ var toolTip = new InputToolTip();
+ toolTip.setClickHandler(function() {
+ element.focus();
+ });
+ this._element.after(toolTip.getElement());
+ //below is called after getElement, b/c element must be defined
+ if (this._prevText !== '') {
+ toolTip.hide();//hide if search query is not empty
+ }
+ this._toolTip = toolTip;
+
+ var dropMenu = new SearchDropMenu();
+ dropMenu.setAskHandler(this.makeAskHandler());
+ dropMenu.setAskButtonEnabled(this._askButtonEnabled);
+ this._dropMenu = dropMenu;
+ element.parent().after(this._dropMenu.getElement());
- /* *********************************** */
+ $(element).click(function(e) { return false });
+ $(document).click(function() { dropMenu.reset(); });
- // Wire search tags
+ //the tag search input is optional in askbot
+ $('#ab-tag-search').parent().before(
+ this._tag_warning_box.getElement()
+ );
+
+ // make search tags functional
var search_tags = $('#searchTags .tag-left');
+ var searchUrl = this.getSearchUrl();
+ var me = this;
$.each(search_tags, function(idx, element){
var tag = new Tag();
tag.decorate($(element));
//todo: setDeleteHandler and setHandler
//must work after decorate & must have getName
tag.setDeleteHandler(
- function(){
- remove_search_tag(tag.getName(), query_string);
- }
+ function(){
+ me.removeSearchTag(tag.getName(), searchUrl);
+ }
);
});
-
- // Wire X button
- x_button.click(function () {
- restart_query(); /* wrapped in closure because it's not yet defined at this point */
+ // enable x button (search reset)
+ this._xButton.click(function () {
+ /* wrapped in closure because it's not yet defined at this point */
+ me.reset();
});
- refresh_x_button();
+ this.refreshXButton();
- // Wire query box
+ // enable query box
var main_page_eval_handle;
- query.keyup(function(e){
- refresh_x_button();
- if (running === false){
+ this._query.keydown(this.makeKeyDownHandler());
+ this._query.keyup(function(e){
+ me.updateToolTip();
+ me.refreshXButton();
+ if (me.isRunning() === false){
clearTimeout(main_page_eval_handle);
- main_page_eval_handle = setTimeout(eval_query, 400);
+ main_page_eval_handle = setTimeout(
+ function() { me.evalTitleSearchQuery() },
+ 400
+ );
}
});
- activate_tag_search_input();
+ this.activateTagSearchInput();
- $("form#searchForm").submit(function(event) {
- // if user clicks the button the s(h)e probably wants page reload,
- // so provide that experience but first update the query string
- event.preventDefault();
- update_query_string();
- window.location.href = search_url + query_string;
- });
-
- /* *********************************** */
-
- // Hook for tag_selector.js
- liveSearch.refresh = function () {
- send_query();
- };
+ $("form#searchForm").submit(me.makeFormSubmitHandler());
};
diff --git a/askbot/media/js/live_search_new_thread.js b/askbot/media/js/live_search_new_thread.js
index eedd5fe8..d17951eb 100644
--- a/askbot/media/js/live_search_new_thread.js
+++ b/askbot/media/js/live_search_new_thread.js
@@ -2,7 +2,7 @@
var liveSearchNewThreadInit = function(auto_focus_out) {
var query = $('input#id_title.questionTitleInput');
var prev_text = $.trim(query.val());
- var search_url = askbot['urls']['api_get_questions'];
+ var search_url = askbot['urls']['titleSearch'];
var running = false;
var q_list_sel = 'question-list'; //id of question listing div
@@ -32,7 +32,7 @@ var liveSearchNewThreadInit = function(auto_focus_out) {
var eval_query = function(){
cur_text = $.trim(query.val());
if (cur_text !== prev_text && running === false){
- if (cur_text.length >= minSearchWordLength){
+ if (cur_text.length >= askbot['settings']['minSearchWordLength']){
send_query(cur_text);
} else if (cur_text.length === 0){
restart_query();
diff --git a/askbot/media/js/post.js b/askbot/media/js/post.js
index fb6f6ef0..94e230a2 100644
--- a/askbot/media/js/post.js
+++ b/askbot/media/js/post.js
@@ -23,6 +23,7 @@ var lanai = {
}
};
+//todo: clean-up now there is utils:WaitIcon
function appendLoader(element) {
loading = gettext('loading...')
element.append('<img class="ajax-loader" ' +
@@ -547,10 +548,8 @@ var Vote = function(){
var acceptAnonymousMessage = gettext('insufficient privilege');
var acceptOwnAnswerMessage = gettext('cannot pick own answer as best');
- var pleaseLogin = " <a href='" + askbot['urls']['user_signin']
- + "?next=" + askbot['urls']['question_url_template']
- + "'>"
- + gettext('please login') + "</a>";
+ var pleaseLogin = " <a href='" + askbot['urls']['user_signin'] + ">"
+ + gettext('please login') + "</a>";
var favoriteAnonymousMessage = gettext('anonymous users cannot follow questions') + pleaseLogin;
var subscribeAnonymousMessage = gettext('anonymous users cannot subscribe to questions') + pleaseLogin;
@@ -777,7 +776,7 @@ var Vote = function(){
type: "POST",
cache: false,
dataType: "json",
- url: askbot['urls']['vote_url_template'].replace('{{QuestionID}}', questionId),
+ url: askbot['urls']['vote_url'],
data: { "type": voteType, "postId": postId },
error: handleFail,
success: function(data) {
@@ -1444,7 +1443,7 @@ EditCommentForm.prototype.attachTo = function(comment, mode){
this._submit_btn.html(gettext('save comment'));
}
this.getElement().show();
- this.enableButtons();
+ this.enableForm();
this.focus();
putCursorAtEnd(this._textarea);
};
@@ -1571,12 +1570,16 @@ EditCommentForm.prototype.createDom = function(){
this._textarea.val(this._text);
};
-EditCommentForm.prototype.enableButtons = function(){
+EditCommentForm.prototype.isEnabled = function() {
+ return (this._submit_btn.attr('disabled') !== 'disabled');//confusing! setters use boolean
+};
+
+EditCommentForm.prototype.enableForm = function() {
this._submit_btn.attr('disabled', false);
this._cancel_btn.attr('disabled', false);
};
-EditCommentForm.prototype.disableButtons = function(){
+EditCommentForm.prototype.disableForm = function() {
this._submit_btn.attr('disabled', true);
this._cancel_btn.attr('disabled', true);
};
@@ -1585,7 +1588,7 @@ EditCommentForm.prototype.reset = function(){
this._comment = null;
this._text = '';
this._textarea.val('');
- this.enableButtons();
+ this.enableForm();
};
EditCommentForm.prototype.confirmAbandon = function(){
@@ -1607,6 +1610,9 @@ EditCommentForm.prototype.getSaveHandler = function(){
var me = this;
return function(){
+ if (me.isEnabled() === false) {//prevent double submits
+ return false;
+ }
var text = me._textarea.val();
if (text.length < 10){
me.focus();
@@ -1627,7 +1633,7 @@ EditCommentForm.prototype.getSaveHandler = function(){
post_url = askbot['urls']['postComments'];
}
- me.disableButtons();
+ me.disableForm();
$.ajax({
type: "POST",
@@ -1650,7 +1656,7 @@ EditCommentForm.prototype.getSaveHandler = function(){
me._comment.getElement().show();
showMessage(me._comment.getElement(), xhr.responseText, 'after');
me.detach();
- me.enableButtons();
+ me.enableForm();
}
});
return false;
@@ -1778,6 +1784,7 @@ Comment.prototype.setContent = function(data){
this._user_link = $('<a></a>').attr('class', 'author');
this._user_link.attr('href', this._data['user_url']);
this._user_link.html(this._data['user_display_name']);
+ this._comment_body.append(' ');
this._comment_body.append(this._user_link);
this._comment_body.append(' (');
@@ -2066,18 +2073,25 @@ var socialSharing = function(){
var share_page = function(service_name){
if (SERVICE_DATA[service_name]){
var url = SERVICE_DATA[service_name]['url'];
+ url = url.replace('{TEXT}', TEXT);
+ url = url.replace('{URL}', URL);
+ var params = SERVICE_DATA[service_name]['params'];
+ if(!window.open(url, "sharing", params)){
+ window.location.href=url;
+ }
+ return false;
+ //@todo: change to some other url shortening service
$.ajax({
- async: false,
url: "http://json-tinyurl.appspot.com/?&callback=?",
dataType: "json",
data: {'url':URL},
- success: function(data){
+ success: function(data) {
url = url.replace('{URL}', data.tinyurl);
},
- error: function(data){
+ error: function(xhr, opts, error) {
url = url.replace('{URL}', URL);
},
- complete: function(data){
+ complete: function(data) {
url = url.replace('{TEXT}', TEXT);
var params = SERVICE_DATA[service_name]['params'];
if(!window.open(url, "sharing", params)){
@@ -2091,7 +2105,14 @@ var socialSharing = function(){
return {
init: function(){
URL = window.location.href;
+ var urlBits = URL.split('/');
+ URL = urlBits.slice(0, -2).join('/') + '/';
TEXT = escape($('h1 > a').html());
+ var hashtag = encodeURIComponent(
+ askbot['settings']['sharingSuffixText']
+ );
+ TEXT = TEXT.substr(0, 134 - URL.length - hashtag.length);
+ TEXT = TEXT + '... ' + hashtag;
var fb = $('a.facebook-share')
var tw = $('a.twitter-share');
var ln = $('a.linkedin-share');
@@ -2100,10 +2121,10 @@ var socialSharing = function(){
copyAltToTitle(tw);
copyAltToTitle(ln);
copyAltToTitle(ica);
- setupButtonEventHandlers(fb, function(){share_page("facebook")});
- setupButtonEventHandlers(tw, function(){share_page("twitter")});
- setupButtonEventHandlers(ln, function(){share_page("linkedin")});
- setupButtonEventHandlers(ica, function(){share_page("identica")});
+ setupButtonEventHandlers(fb, function(){ share_page("facebook") });
+ setupButtonEventHandlers(tw, function(){ share_page("twitter") });
+ setupButtonEventHandlers(ln, function(){ share_page("linkedin") });
+ setupButtonEventHandlers(ica, function(){ share_page("identica") });
}
}
}();
@@ -2139,15 +2160,7 @@ QASwapper.prototype.startSwapping = function(){
url: askbot['urls']['swap_question_with_answer'],
data: data,
success: function(data){
- var url_template = askbot['urls']['question_url_template'];
- new_question_url = url_template.replace(
- '{{QuestionID}}',
- data['id']
- ).replace(
- '{{questionSlug}}',
- data['slug']
- );
- window.location.href = new_question_url;
+ window.location.href = data['question_url'];
}
});
break;
@@ -4082,9 +4095,32 @@ $(document).ready(function() {
}
});
-
-/*
-Prettify
-http://www.apache.org/licenses/LICENSE-2.0
-*/
-var PR_SHOULD_USE_CONTINUATION = true; var PR_TAB_WIDTH = 8; var PR_normalizedHtml; var PR; var prettyPrintOne; var prettyPrint; function _pr_isIE6() { var isIE6 = navigator && navigator.userAgent && /\bMSIE 6\./.test(navigator.userAgent); _pr_isIE6 = function() { return isIE6; }; return isIE6; } (function() { function wordSet(words) { words = words.split(/ /g); var set = {}; for (var i = words.length; --i >= 0; ) { var w = words[i]; if (w) { set[w] = null; } } return set; } var FLOW_CONTROL_KEYWORDS = "break continue do else for if return while "; var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " + "double enum extern float goto int long register short signed sizeof " + "static struct switch typedef union unsigned void volatile "; var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " + "new operator private protected public this throw true try "; var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " + "concept concept_map const_cast constexpr decltype " + "dynamic_cast explicit export friend inline late_check " + "mutable namespace nullptr reinterpret_cast static_assert static_cast " + "template typeid typename typeof using virtual wchar_t where "; var JAVA_KEYWORDS = COMMON_KEYWORDS + "boolean byte extends final finally implements import instanceof null " + "native package strictfp super synchronized throws transient "; var CSHARP_KEYWORDS = JAVA_KEYWORDS + "as base by checked decimal delegate descending event " + "fixed foreach from group implicit in interface internal into is lock " + "object out override orderby params readonly ref sbyte sealed " + "stackalloc string select uint ulong unchecked unsafe ushort var "; var JSCRIPT_KEYWORDS = COMMON_KEYWORDS + "debugger eval export function get null set undefined var with " + "Infinity NaN "; var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " + "goto if import last local my next no our print package redo require " + "sub undef unless until use wantarray while BEGIN END "; var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " + "elif except exec finally from global import in is lambda " + "nonlocal not or pass print raise try with yield " + "False True None "; var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" + " defined elsif end ensure false in module next nil not or redo rescue " + "retry self super then true undef unless until when yield BEGIN END "; var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " + "function in local set then until "; var ALL_KEYWORDS = (CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS + PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS); var PR_STRING = 'str'; var PR_KEYWORD = 'kwd'; var PR_COMMENT = 'com'; var PR_TYPE = 'typ'; var PR_LITERAL = 'lit'; var PR_PUNCTUATION = 'pun'; var PR_PLAIN = 'pln'; var PR_TAG = 'tag'; var PR_DECLARATION = 'dec'; var PR_SOURCE = 'src'; var PR_ATTRIB_NAME = 'atn'; var PR_ATTRIB_VALUE = 'atv'; var PR_NOCODE = 'nocode'; function isWordChar(ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } function spliceArrayInto(inserted, container, containerPosition, countReplaced) { inserted.unshift(containerPosition, countReplaced || 0); try { container.splice.apply(container, inserted); } finally { inserted.splice(0, 2); } } var REGEXP_PRECEDER_PATTERN = function() { var preceders = ["!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=", "&=", "(", "*", "*=", "+=", ",", "-=", "->", "/", "/=", ":", "::", ";", "<", "<<", "<<=", "<=", "=", "==", "===", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[", "^", "^=", "^^", "^^=", "{", "|", "|=", "||", "||=", "~", "break", "case", "continue", "delete", "do", "else", "finally", "instanceof", "return", "throw", "try", "typeof"]; var pattern = '(?:' + '(?:(?:^|[^0-9.])\\.{1,3})|' + '(?:(?:^|[^\\+])\\+)|' + '(?:(?:^|[^\\-])-)'; for (var i = 0; i < preceders.length; ++i) { var preceder = preceders[i]; if (isWordChar(preceder.charAt(0))) { pattern += '|\\b' + preceder; } else { pattern += '|' + preceder.replace(/([^=<>:&])/g, '\\$1'); } } pattern += '|^)\\s*$'; return new RegExp(pattern); } (); var pr_amp = /&/g; var pr_lt = /</g; var pr_gt = />/g; var pr_quot = /\"/g; function attribToHtml(str) { return str.replace(pr_amp, '&amp;').replace(pr_lt, '&lt;').replace(pr_gt, '&gt;').replace(pr_quot, '&quot;'); } function textToHtml(str) { return str.replace(pr_amp, '&amp;').replace(pr_lt, '&lt;').replace(pr_gt, '&gt;'); } var pr_ltEnt = /&lt;/g; var pr_gtEnt = /&gt;/g; var pr_aposEnt = /&apos;/g; var pr_quotEnt = /&quot;/g; var pr_ampEnt = /&amp;/g; var pr_nbspEnt = /&nbsp;/g; function htmlToText(html) { var pos = html.indexOf('&'); if (pos < 0) { return html; } for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0; ) { var end = html.indexOf(';', pos); if (end >= 0) { var num = html.substring(pos + 3, end); var radix = 10; if (num && num.charAt(0) === 'x') { num = num.substring(1); radix = 16; } var codePoint = parseInt(num, radix); if (!isNaN(codePoint)) { html = (html.substring(0, pos) + String.fromCharCode(codePoint) + html.substring(end + 1)); } } } return html.replace(pr_ltEnt, '<').replace(pr_gtEnt, '>').replace(pr_aposEnt, "'").replace(pr_quotEnt, '"').replace(pr_ampEnt, '&').replace(pr_nbspEnt, ' '); } function isRawContent(node) { return 'XMP' === node.tagName; } function normalizedHtml(node, out) { switch (node.nodeType) { case 1: var name = node.tagName.toLowerCase(); out.push('<', name); for (var i = 0; i < node.attributes.length; ++i) { var attr = node.attributes[i]; if (!attr.specified) { continue; } out.push(' '); normalizedHtml(attr, out); } out.push('>'); for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } if (node.firstChild || !/^(?:br|link|img)$/.test(name)) { out.push('<\/', name, '>'); } break; case 2: out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"'); break; case 3: case 4: out.push(textToHtml(node.nodeValue)); break; } } var PR_innerHtmlWorks = null; function getInnerHtml(node) { if (null === PR_innerHtmlWorks) { var testNode = document.createElement('PRE'); testNode.appendChild(document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />')); PR_innerHtmlWorks = !/</.test(testNode.innerHTML); } if (PR_innerHtmlWorks) { var content = node.innerHTML; if (isRawContent(node)) { content = textToHtml(content); } return content; } var out = []; for (var child = node.firstChild; child; child = child.nextSibling) { normalizedHtml(child, out); } return out.join(''); } function makeTabExpander(tabWidth) { var SPACES = ' '; var charInLine = 0; return function(plainText) { var out = null; var pos = 0; for (var i = 0, n = plainText.length; i < n; ++i) { var ch = plainText.charAt(i); switch (ch) { case '\t': if (!out) { out = []; } out.push(plainText.substring(pos, i)); var nSpaces = tabWidth - (charInLine % tabWidth); charInLine += nSpaces; for (; nSpaces >= 0; nSpaces -= SPACES.length) { out.push(SPACES.substring(0, nSpaces)); } pos = i + 1; break; case '\n': charInLine = 0; break; default: ++charInLine; } } if (!out) { return plainText; } out.push(plainText.substring(pos)); return out.join(''); }; } var pr_chunkPattern = /(?:[^<]+|<!--[\s\S]*?-->|<!\[CDATA\[([\s\S]*?)\]\]>|<\/?[a-zA-Z][^>]*>|<)/g; var pr_commentPrefix = /^<!--/; var pr_cdataPrefix = /^<\[CDATA\[/; var pr_brPrefix = /^<br\b/i; var pr_tagNameRe = /^<(\/?)([a-zA-Z]+)/; function extractTags(s) { var matches = s.match(pr_chunkPattern); var sourceBuf = []; var sourceBufLen = 0; var extractedTags = []; if (matches) { for (var i = 0, n = matches.length; i < n; ++i) { var match = matches[i]; if (match.length > 1 && match.charAt(0) === '<') { if (pr_commentPrefix.test(match)) { continue; } if (pr_cdataPrefix.test(match)) { sourceBuf.push(match.substring(9, match.length - 3)); sourceBufLen += match.length - 12; } else if (pr_brPrefix.test(match)) { sourceBuf.push('\n'); ++sourceBufLen; } else { if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) { var name = match.match(pr_tagNameRe)[2]; var depth = 1; end_tag_loop: for (var j = i + 1; j < n; ++j) { var name2 = matches[j].match(pr_tagNameRe); if (name2 && name2[2] === name) { if (name2[1] === '/') { if (--depth === 0) { break end_tag_loop; } } else { ++depth; } } } if (j < n) { extractedTags.push(sourceBufLen, matches.slice(i, j + 1).join('')); i = j; } else { extractedTags.push(sourceBufLen, match); } } else { extractedTags.push(sourceBufLen, match); } } } else { var literalText = htmlToText(match); sourceBuf.push(literalText); sourceBufLen += literalText.length; } } } return { source: sourceBuf.join(''), tags: extractedTags }; } function isNoCodeTag(tag) { return !!tag.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g, ' $1="$2$3$4"').match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/); } function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) { var shortcuts = {}; (function() { var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns); for (var i = allPatterns.length; --i >= 0; ) { var patternParts = allPatterns[i]; var shortcutChars = patternParts[3]; if (shortcutChars) { for (var c = shortcutChars.length; --c >= 0; ) { shortcuts[shortcutChars.charAt(c)] = patternParts; } } } })(); var nPatterns = fallthroughStylePatterns.length; var notWs = /\S/; return function(sourceCode, opt_basePos) { opt_basePos = opt_basePos || 0; var decorations = [opt_basePos, PR_PLAIN]; var lastToken = ''; var pos = 0; var tail = sourceCode; while (tail.length) { var style; var token = null; var match; var patternParts = shortcuts[tail.charAt(0)]; if (patternParts) { match = tail.match(patternParts[1]); token = match[0]; style = patternParts[0]; } else { for (var i = 0; i < nPatterns; ++i) { patternParts = fallthroughStylePatterns[i]; var contextPattern = patternParts[2]; if (contextPattern && !contextPattern.test(lastToken)) { continue; } match = tail.match(patternParts[1]); if (match) { token = match[0]; style = patternParts[0]; break; } } if (!token) { style = PR_PLAIN; token = tail.substring(0, 1); } } decorations.push(opt_basePos + pos, style); pos += token.length; tail = tail.substring(token.length); if (style !== PR_COMMENT && notWs.test(token)) { lastToken = token; } } return decorations; }; } var PR_MARKUP_LEXER = createSimpleLexer([], [[PR_PLAIN, /^[^<]+/, null], [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/, null], [PR_COMMENT, /^<!--[\s\S]*?(?:-->|$)/, null], [PR_SOURCE, /^<\?[\s\S]*?(?:\?>|$)/, null], [PR_SOURCE, /^<%[\s\S]*?(?:%>|$)/, null], [PR_SOURCE, /^<(script|style|xmp)\b[^>]*>[\s\S]*?<\/\1\b[^>]*>/i, null], [PR_TAG, /^<\/?\w[^<>]*>/, null]]); var PR_SOURCE_CHUNK_PARTS = /^(<[^>]*>)([\s\S]*)(<\/[^>]*>)$/; function tokenizeMarkup(source) { var decorations = PR_MARKUP_LEXER(source); for (var i = 0; i < decorations.length; i += 2) { if (decorations[i + 1] === PR_SOURCE) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var sourceChunk = source.substring(start, end); var match = sourceChunk.match(PR_SOURCE_CHUNK_PARTS); if (match) { decorations.splice(i, 2, start, PR_TAG, start + match[1].length, PR_SOURCE, start + match[1].length + (match[2] || '').length, PR_TAG); } } } return decorations; } var PR_TAG_LEXER = createSimpleLexer([[PR_ATTRIB_VALUE, /^\'[^\']*(?:\'|$)/, null, "'"], [PR_ATTRIB_VALUE, /^\"[^\"]*(?:\"|$)/, null, '"'], [PR_PUNCTUATION, /^[<>\/=]+/, null, '<>/=']], [[PR_TAG, /^[\w:\-]+/, /^</], [PR_ATTRIB_VALUE, /^[\w\-]+/, /^=/], [PR_ATTRIB_NAME, /^[\w:\-]+/, null], [PR_PLAIN, /^\s+/, null, ' \t\r\n']]); function splitTagAttributes(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_TAG) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var chunk = source.substring(start, end); var subDecorations = PR_TAG_LEXER(chunk, start); spliceArrayInto(subDecorations, decorations, i, 2); i += subDecorations.length - 2; } } return decorations; } function sourceDecorator(options) { var shortcutStylePatterns = [], fallthroughStylePatterns = []; if (options.tripleQuotedStrings) { shortcutStylePatterns.push([PR_STRING, /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/, null, '\'"']); } else if (options.multiLineStrings) { shortcutStylePatterns.push([PR_STRING, /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/, null, '\'"`']); } else { shortcutStylePatterns.push([PR_STRING, /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/, null, '"\'']); } fallthroughStylePatterns.push([PR_PLAIN, /^(?:[^\'\"\`\/\#]+)/, null, ' \r\n']); if (options.hashComments) { shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']); } if (options.cStyleComments) { fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]); fallthroughStylePatterns.push([PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]); } if (options.regexLiterals) { var REGEX_LITERAL = ('^/(?=[^/*])' + '(?:[^/\\x5B\\x5C]' + '|\\x5C[\\s\\S]' + '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+' + '(?:/|$)'); fallthroughStylePatterns.push([PR_STRING, new RegExp(REGEX_LITERAL), REGEXP_PRECEDER_PATTERN]); } var keywords = wordSet(options.keywords); options = null; var splitStringAndCommentTokens = createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns); var styleLiteralIdentifierPuncRecognizer = createSimpleLexer([], [[PR_PLAIN, /^\s+/, null, ' \r\n'], [PR_PLAIN, /^[a-z_$@][a-z_$@0-9]*/i, null], [PR_LITERAL, /^0x[a-f0-9]+[a-z]/i, null], [PR_LITERAL, /^(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d+)(?:e[+\-]?\d+)?[a-z]*/i, null, '123456789'], [PR_PUNCTUATION, /^[^\s\w\.$@]+/, null]]); function splitNonStringNonCommentTokens(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_PLAIN) { var start, end, chunk, subDecs; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; chunk = source.substring(start, end); subDecs = styleLiteralIdentifierPuncRecognizer(chunk, start); for (var j = 0, m = subDecs.length; j < m; j += 2) { var subStyle = subDecs[j + 1]; if (subStyle === PR_PLAIN) { var subStart = subDecs[j]; var subEnd = j + 2 < m ? subDecs[j + 2] : chunk.length; var token = source.substring(subStart, subEnd); if (token === '.') { subDecs[j + 1] = PR_PUNCTUATION; } else if (token in keywords) { subDecs[j + 1] = PR_KEYWORD; } else if (/^@?[A-Z][A-Z$]*[a-z][A-Za-z$]*$/.test(token)) { subDecs[j + 1] = token.charAt(0) === '@' ? PR_LITERAL : PR_TYPE; } } } spliceArrayInto(subDecs, decorations, i, 2); i += subDecs.length - 2; } } return decorations; } return function(sourceCode) { var decorations = splitStringAndCommentTokens(sourceCode); decorations = splitNonStringNonCommentTokens(sourceCode, decorations); return decorations; }; } var decorateSource = sourceDecorator({ keywords: ALL_KEYWORDS, hashComments: true, cStyleComments: true, multiLineStrings: true, regexLiterals: true }); function splitSourceNodes(source, decorations) { for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; if (style === PR_SOURCE) { var start, end; start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var subDecorations = decorateSource(source.substring(start, end)); for (var j = 0, m = subDecorations.length; j < m; j += 2) { subDecorations[j] += start; } spliceArrayInto(subDecorations, decorations, i, 2); i += subDecorations.length - 2; } } return decorations; } function splitSourceAttributes(source, decorations) { var nextValueIsSource = false; for (var i = 0; i < decorations.length; i += 2) { var style = decorations[i + 1]; var start, end; if (style === PR_ATTRIB_NAME) { start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; nextValueIsSource = /^on|^style$/i.test(source.substring(start, end)); } else if (style === PR_ATTRIB_VALUE) { if (nextValueIsSource) { start = decorations[i]; end = i + 2 < decorations.length ? decorations[i + 2] : source.length; var attribValue = source.substring(start, end); var attribLen = attribValue.length; var quoted = (attribLen >= 2 && /^[\"\']/.test(attribValue) && attribValue.charAt(0) === attribValue.charAt(attribLen - 1)); var attribSource; var attribSourceStart; var attribSourceEnd; if (quoted) { attribSourceStart = start + 1; attribSourceEnd = end - 1; attribSource = attribValue; } else { attribSourceStart = start + 1; attribSourceEnd = end - 1; attribSource = attribValue.substring(1, attribValue.length - 1); } var attribSourceDecorations = decorateSource(attribSource); for (var j = 0, m = attribSourceDecorations.length; j < m; j += 2) { attribSourceDecorations[j] += attribSourceStart; } if (quoted) { attribSourceDecorations.push(attribSourceEnd, PR_ATTRIB_VALUE); spliceArrayInto(attribSourceDecorations, decorations, i + 2, 0); } else { spliceArrayInto(attribSourceDecorations, decorations, i, 2); } } nextValueIsSource = false; } } return decorations; } function decorateMarkup(sourceCode) { var decorations = tokenizeMarkup(sourceCode); decorations = splitTagAttributes(sourceCode, decorations); decorations = splitSourceNodes(sourceCode, decorations); decorations = splitSourceAttributes(sourceCode, decorations); return decorations; } function recombineTagsAndDecorations(sourceText, extractedTags, decorations) { var html = []; var outputIdx = 0; var openDecoration = null; var currentDecoration = null; var tagPos = 0; var decPos = 0; var tabExpander = makeTabExpander(PR_TAB_WIDTH); var adjacentSpaceRe = /([\r\n ]) /g; var startOrSpaceRe = /(^| ) /gm; var newlineRe = /\r\n?|\n/g; var trailingSpaceRe = /[ \r\n]$/; var lastWasSpace = true; function emitTextUpTo(sourceIdx) { if (sourceIdx > outputIdx) { if (openDecoration && openDecoration !== currentDecoration) { html.push('</span>'); openDecoration = null; } if (!openDecoration && currentDecoration) { openDecoration = currentDecoration; html.push('<span class="', openDecoration, '">'); } var htmlChunk = textToHtml(tabExpander(sourceText.substring(outputIdx, sourceIdx))).replace(lastWasSpace ? startOrSpaceRe : adjacentSpaceRe, '$1&nbsp;'); lastWasSpace = trailingSpaceRe.test(htmlChunk); html.push(htmlChunk.replace(newlineRe, '<br />')); outputIdx = sourceIdx; } } while (true) { var outputTag; if (tagPos < extractedTags.length) { if (decPos < decorations.length) { outputTag = extractedTags[tagPos] <= decorations[decPos]; } else { outputTag = true; } } else { outputTag = false; } if (outputTag) { emitTextUpTo(extractedTags[tagPos]); if (openDecoration) { html.push('</span>'); openDecoration = null; } html.push(extractedTags[tagPos + 1]); tagPos += 2; } else if (decPos < decorations.length) { emitTextUpTo(decorations[decPos]); currentDecoration = decorations[decPos + 1]; decPos += 2; } else { break; } } emitTextUpTo(sourceText.length); if (openDecoration) { html.push('</span>'); } return html.join(''); } var langHandlerRegistry = {}; function registerLangHandler(handler, fileExtensions) { for (var i = fileExtensions.length; --i >= 0; ) { var ext = fileExtensions[i]; if (!langHandlerRegistry.hasOwnProperty(ext)) { langHandlerRegistry[ext] = handler; } else if ('console' in window) { console.log('cannot override language handler %s', ext); } } } registerLangHandler(decorateSource, ['default-code']); registerLangHandler(decorateMarkup, ['default-markup', 'html', 'htm', 'xhtml', 'xml', 'xsl']); registerLangHandler(sourceDecorator({ keywords: CPP_KEYWORDS, hashComments: true, cStyleComments: true }), ['c', 'cc', 'cpp', 'cs', 'cxx', 'cyc']); registerLangHandler(sourceDecorator({ keywords: JAVA_KEYWORDS, cStyleComments: true }), ['java']); registerLangHandler(sourceDecorator({ keywords: SH_KEYWORDS, hashComments: true, multiLineStrings: true }), ['bsh', 'csh', 'sh']); registerLangHandler(sourceDecorator({ keywords: PYTHON_KEYWORDS, hashComments: true, multiLineStrings: true, tripleQuotedStrings: true }), ['cv', 'py']); registerLangHandler(sourceDecorator({ keywords: PERL_KEYWORDS, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['perl', 'pl', 'pm']); registerLangHandler(sourceDecorator({ keywords: RUBY_KEYWORDS, hashComments: true, multiLineStrings: true, regexLiterals: true }), ['rb']); registerLangHandler(sourceDecorator({ keywords: JSCRIPT_KEYWORDS, cStyleComments: true, regexLiterals: true }), ['js']); function prettyPrintOne(sourceCodeHtml, opt_langExtension) { try { var sourceAndExtractedTags = extractTags(sourceCodeHtml); var source = sourceAndExtractedTags.source; var extractedTags = sourceAndExtractedTags.tags; if (!langHandlerRegistry.hasOwnProperty(opt_langExtension)) { opt_langExtension = /^\s*</.test(source) ? 'default-markup' : 'default-code'; } var decorations = langHandlerRegistry[opt_langExtension].call({}, source); return recombineTagsAndDecorations(source, extractedTags, decorations); } catch (e) { if ('console' in window) { console.log(e); console.trace(); } return sourceCodeHtml; } } function prettyPrint(opt_whenDone) { var isIE6 = _pr_isIE6(); var codeSegments = [document.getElementsByTagName('pre'), document.getElementsByTagName('code'), document.getElementsByTagName('xmp')]; var elements = []; for (var i = 0; i < codeSegments.length; ++i) { for (var j = 0; j < codeSegments[i].length; ++j) { elements.push(codeSegments[i][j]); } } codeSegments = null; var k = 0; function doWork() { var endTime = (PR_SHOULD_USE_CONTINUATION ? new Date().getTime() + 250 : Infinity); for (; k < elements.length && new Date().getTime() < endTime; k++) { var cs = elements[k]; if (cs.className && cs.className.indexOf('prettyprint') >= 0) { var langExtension = cs.className.match(/\blang-(\w+)\b/); if (langExtension) { langExtension = langExtension[1]; } var nested = false; for (var p = cs.parentNode; p; p = p.parentNode) { if ((p.tagName === 'pre' || p.tagName === 'code' || p.tagName === 'xmp') && p.className && p.className.indexOf('prettyprint') >= 0) { nested = true; break; } } if (!nested) { var content = getInnerHtml(cs); content = content.replace(/(?:\r\n?|\n)$/, ''); var newContent = prettyPrintOne(content, langExtension); if (!isRawContent(cs)) { cs.innerHTML = newContent; } else { var pre = document.createElement('PRE'); for (var i = 0; i < cs.attributes.length; ++i) { var a = cs.attributes[i]; if (a.specified) { var aname = a.name.toLowerCase(); if (aname === 'class') { pre.className = a.value; } else { pre.setAttribute(a.name, a.value); } } } pre.innerHTML = newContent; cs.parentNode.replaceChild(pre, cs); cs = pre; } if (isIE6 && cs.tagName === 'PRE') { var lineBreaks = cs.getElementsByTagName('br'); for (var j = lineBreaks.length; --j >= 0; ) { var lineBreak = lineBreaks[j]; lineBreak.parentNode.replaceChild(document.createTextNode('\r\n'), lineBreak); } } } } } if (k < elements.length) { setTimeout(doWork, 250); } else if (opt_whenDone) { opt_whenDone(); } } doWork(); } window['PR_normalizedHtml'] = normalizedHtml; window['prettyPrintOne'] = prettyPrintOne; window['prettyPrint'] = prettyPrint; window['PR'] = { 'createSimpleLexer': createSimpleLexer, 'registerLangHandler': registerLangHandler, 'sourceDecorator': sourceDecorator, 'PR_ATTRIB_NAME': PR_ATTRIB_NAME, 'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE, 'PR_COMMENT': PR_COMMENT, 'PR_DECLARATION': PR_DECLARATION, 'PR_KEYWORD': PR_KEYWORD, 'PR_LITERAL': PR_LITERAL, 'PR_NOCODE': PR_NOCODE, 'PR_PLAIN': PR_PLAIN, 'PR_PUNCTUATION': PR_PUNCTUATION, 'PR_SOURCE': PR_SOURCE, 'PR_STRING': PR_STRING, 'PR_TAG': PR_TAG, 'PR_TYPE': PR_TYPE }; })();
+/* google prettify.js from google code */
+var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
+(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
+[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
+f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
+(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
+{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
+t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
+"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
+l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
+q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
+q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
+"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
+a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
+for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
+m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
+a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
+j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
+"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
+H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
+J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
+I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
+["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
+/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
+["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
+hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
+!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
+250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
+PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
diff --git a/askbot/media/js/tag_moderation.js b/askbot/media/js/tag_moderation.js
index 31e05e37..009e4e32 100644
--- a/askbot/media/js/tag_moderation.js
+++ b/askbot/media/js/tag_moderation.js
@@ -86,9 +86,14 @@ PerThreadTagModerator.prototype.afterActionHandler = function() {
ancestor.hideButtons();
this.dispose();
} else if (childCount == 0) {
- var table = $('.suggested-tags-table');
- table.before($('<p>' + gettext('No suggested tags left') + '</p>'));
- table.remove();
+ //this does not work with the fade-out of table rows...
+ /* var callback = function() {
+ var table = $('.suggested-tags-table');
+ if (table.find('tr.suggested-tag-row').length == 0) {
+ table.before($('<p>' + gettext('No suggested tags left') + '</p>'));
+ table.remove();
+ }
+ }; */
ancestor.dispose();
} else {
this.dispose();
@@ -164,7 +169,7 @@ AllThreadsTagModerator.prototype.afterActionHandler = function() {
};
AllThreadsTagModerator.prototype.dispose = function() {
- this._tag_entry_element.fadeOut('fast', function() {
+ var eventChain = this._tag_entry_element.fadeOut('fast', function() {
$.each(this._children, function(idx, child) {
child.dispose();
});
@@ -200,6 +205,7 @@ AllThreadsTagModerator.prototype.decorate = function(element) {
var tagEntry = $(element);
var tagId = tagEntry.data('tagId');
+ //handles the case where there are >1 threads per tag
var tagMod = new AllThreadsTagModerator();
tagMod.decorate(tagEntry.next());
tagMod.setTagId(tagId);
diff --git a/askbot/media/js/tag_selector.js b/askbot/media/js/tag_selector.js
index 790acce2..c1ccd691 100644
--- a/askbot/media/js/tag_selector.js
+++ b/askbot/media/js/tag_selector.js
@@ -123,7 +123,8 @@ function pickedTags(){
var data = JSON.stringify({
tagnames: tagnames,
- reason: reason
+ reason: reason,
+ user: askbot['data']['viewUserId']
});
var call_settings = {
type:'POST',
@@ -150,7 +151,9 @@ function pickedTags(){
'remove',
function(){
deleteTagLocally();
- liveSearch.refresh();
+ if ($('body').hasClass('main-page')) {
+ askbot['controllers']['fullTextSearch'].refresh();
+ }
}
);
}
@@ -293,7 +296,7 @@ function pickedTags(){
to_tag_container
);
$(input_sel).val('');
- liveSearch.refresh();
+ askbot['controllers']['fullTextSearch'].refresh();
}
);
}
@@ -348,7 +351,7 @@ function pickedTags(){
filter_value: $(this).val()
},
success: function(){
- liveSearch.refresh();
+ askbot['controllers']['fullTextSearch'].refresh();
}
});
});
diff --git a/askbot/media/js/utils.js b/askbot/media/js/utils.js
index 2534fb21..304caa8b 100644
--- a/askbot/media/js/utils.js
+++ b/askbot/media/js/utils.js
@@ -97,6 +97,18 @@ var showMessage = function(element, msg, where) {
};
})(jQuery);
+/**
+ * @return {number} key code of the event or `undefined`
+ */
+var getKeyCode = function(e) {
+ if (e.which) {
+ return e.which;
+ } else if (e.keyCode) {
+ return e.keyCode;
+ }
+ return undefined;
+};
+
var makeKeyHandler = function(key, callback){
return function(e){
if ((e.which && e.which == key) || (e.keyCode && e.keyCode == key)){
@@ -116,15 +128,16 @@ var setupButtonEventHandlers = function(button, callback){
var putCursorAtEnd = function(element){
- var el = element.get()[0];
+ var el = $(element).get()[0];
+ var jEl = $(el);
if (el.setSelectionRange){
- var len = element.val().length * 2;
+ var len = jEl.val().length * 2;
el.setSelectionRange(len, len);
}
else{
- element.val(element.val());
+ jEl.val(jEl.val());
}
- element.scrollTop = 999999;
+ jEl.scrollTop(999999);
};
var setCheckBoxesIn = function(selector, value){
@@ -201,7 +214,8 @@ QSutils.patch_query_string = function (query_string, patch, remove) {
var mapping = {};
if(!remove) {
- mapping[patch_split[0]] = patch_split[1]; // prepopulate the patched selector if it's not meant to be removed
+ // prepopulate the patched selector if it's not meant to be removed
+ mapping[patch_split[0]] = patch_split[1];
}
for (var i = 0; i < params.length; i++) {
@@ -368,6 +382,110 @@ WrappedElement.prototype.dispose = function(){
this._in_document = false;
};
+/**
+ * @constructor
+ * a loader
+ */
+var WaitIcon = function() {
+ WrappedElement.call(this);
+ this._isVisible = false;
+};
+inherits(WaitIcon, WrappedElement);
+
+WaitIcon.prototype.setVisible = function(isVisible) {
+ this._isVisible = isVisible;
+ if (this._element) {
+ if (this._isVisible === true) {
+ this._element.show();
+ } else {
+ this._element.hide();
+ }
+ }
+};
+
+WaitIcon.prototype.hide = function() {
+ this.setVisible(false);
+};
+
+WaitIcon.prototype.show = function() {
+ this.setVisible(true);
+};
+
+WaitIcon.prototype.createDom = function() {
+ var box = this.makeElement('div');
+ box.addClass('wait-icon-box');
+ this._element = box;
+ var img = this.makeElement('img');
+ img.attr('src', mediaUrl('media/images/ajax-loader.gif'));
+ box.append(img);
+ this.setVisible(this._isVisible);
+};
+
+/**
+ * @contsructor
+ * a form helper that disables submit button
+ * after it is submitted the first time
+ * to prevent double submits
+ */
+var OneShotForm = function() {
+ WrappedElement.call(this);
+ this._submitBtn = undefined;
+};
+inherits(OneShotForm, WrappedElement);
+
+OneShotForm.prototype.setSubmitButton = function(button) {
+ this._submitBtn = button;
+};
+
+OneShotForm.prototype.enable = function() {
+ this._element.data('submitted', false);
+ this._submitBtn.removeClass('disabled');
+};
+
+OneShotForm.prototype.disable = function() {
+ this._element.data('submitted', true);
+ this._submitBtn.addClass('disabled');
+};
+
+OneShotForm.prototype.decorate = function(element) {
+ this._element = element;
+ var me = this;
+ var button = this._submitBtn;
+ var disabler = function(evt) {
+ if (element.data('submitted') === true) {
+ evt.preventDefault();
+ } else {
+ me.disable();
+ return true;
+ }
+ };
+ element.submit(disabler);
+};
+
+/**
+ * @constructor
+ * a simple link
+ */
+var Link = function() {
+ WrappedElement.call(this);
+};
+inherits(Link, WrappedElement);
+
+Link.prototype.setUrl = function(url) {
+ this._url = url;
+};
+
+Link.prototype.setText = function(text) {
+ this._text = text;
+};
+
+Link.prototype.createDom = function() {
+ var link = this.makeElement('a');
+ this._element = link;
+ link.attr('href', this._url);
+ link.html(this._text);
+};
+
/**
* @constructor
* Widget is a Wrapped element with state
@@ -1501,6 +1619,10 @@ var SelectBox = function(){
};
inherits(SelectBox, Widget);
+SelectBox.prototype.setItemClass = function(itemClass) {
+ this._item_class = itemClass;
+};
+
SelectBox.prototype.setEditable = function(is_editable) {
this._is_editable = is_editable;
};
@@ -1531,7 +1653,21 @@ SelectBox.prototype.getItemByIndex = function(idx) {
return this._items[idx];
};
-//why do we have these two almost identical methods?
+/**
+ * removes all items
+ */
+SelectBox.prototype.empty = function() {
+ var items = this._items;
+ $.each(items, function(idx, item){
+ item.dispose();
+ });
+ this._items = [];
+};
+
+/*
+ * why do we have these two almost identical methods?
+ * the difference seems to be remove/vs fade out
+ */
SelectBox.prototype.removeItem = function(id){
var item = this.getItem(id);
item.getElement().fadeOut();
@@ -1656,6 +1792,12 @@ SelectBox.prototype.decorate = function(element){
});
};
+SelectBox.prototype.createDom = function() {
+ var element = this.makeElement('ul');
+ this._element = element;
+ element.addClass('select-box');
+};
+
/**
* This is a dropdown list elment
*/
@@ -2929,22 +3071,24 @@ AutoCompleter.prototype.setCaret = function(pos) {
} else if (days == 1) {
return gettext('yesterday')
} else if (minutes >= 60) {
+ var wholeHours = Math.floor(hours);
return interpolate(
ngettext(
'%s hour ago',
'%s hours ago',
- hours
+ wholeHours
),
- [Math.floor(hours),]
+ [wholeHours,]
)
} else if (seconds > 90){
+ var wholeMinutes = Math.floor(minutes);
return interpolate(
ngettext(
'%s min ago',
'%s mins ago',
- minutes
+ wholeMinutes
),
- [Math.floor(minutes),]
+ [wholeMinutes,]
)
} else {
return gettext('just now')
diff --git a/askbot/media/style/style.css b/askbot/media/style/style.css
index dc4190b7..cb5f3801 100644
--- a/askbot/media/style/style.css
+++ b/askbot/media/style/style.css
@@ -120,13 +120,9 @@ pre {
font-family: Consolas, Monaco, Liberation Mono, Lucida Console, Monospace;
font-size: 100%;
margin-bottom: 10px;
- /*overflow: auto;*/
-
background-color: #F5F5F5;
padding-left: 5px;
padding-top: 5px;
- /*width: 671px;*/
-
padding-bottom: 20px ! ie7;
}
code {
@@ -167,6 +163,9 @@ html {
a:hover {
text-decoration: underline;
}
+.avatar-box {
+ text-decoration: none;
+}
.badge-context-toggle.active {
cursor: pointer;
text-decoration: underline;
@@ -199,7 +198,8 @@ body.user-messages {
top: 0px;
left: 0px;
width: 100%;
- z-index: 100;
+ height: 34px;
+ z-index: 100000;
padding: 0;
text-align: center;
background-color: #f5dd69;
@@ -212,6 +212,10 @@ body.user-messages {
font-size: 16px;
color: #424242;
}
+.wait-icon-box {
+ text-align: center;
+ margin-bottom: 8px;
+}
#closeNotify {
position: absolute;
right: 5px;
@@ -246,11 +250,32 @@ body.user-messages {
width: auto;
float: left;
}
+.lang-nav {
+ position: relative;
+}
+.lang-nav ul {
+ display: none;
+ list-style: none;
+ z-index: 10000;
+ margin: 0;
+}
+.lang-nav:hover ul,
+.lang-nav ul:hover {
+ display: block;
+ position: absolute;
+ width: 100px;
+}
+.lang-nav li {
+ color: #707070;
+ background: white;
+ display: block;
+}
#userToolsNav {
/* Navigation bar containing login link or user information, check widgets/user_navigation.html*/
height: 20px;
padding-bottom: 5px;
+ white-space: nowrap;
}
#userToolsNav a {
height: 35px;
@@ -360,6 +385,7 @@ body.user-messages {
#metaNav .dropdown-menu {
border-top: none;
left: 7%;
+ z-index: 10100;
}
#metaNav .dropdown-menu a {
color: #666;
@@ -384,7 +410,7 @@ body.user-messages {
margin-bottom: 10px;
font-family: 'Open Sans Condensed', Arial, sans-serif;
}
-#secondaryHeader #homeButton {
+#homeButton {
border-right: #afaf9e 1px solid;
background: -6px -36px url(../images/sprites.png) no-repeat;
height: 55px;
@@ -392,28 +418,22 @@ body.user-messages {
display: block;
float: left;
}
-#secondaryHeader #homeButton:hover {
+#homeButton:hover {
background: -51px -36px url(../images/sprites.png) no-repeat;
}
-#secondaryHeader #scopeWrapper {
- width: 688px;
- float: left;
-}
-#secondaryHeader #scopeWrapper a {
+.scope-selector {
display: block;
float: left;
-}
-#secondaryHeader #scopeWrapper .scope-selector {
font-size: 20px;
color: #7a7a6b;
height: 55px;
line-height: 55px;
margin-left: 16px;
}
-#secondaryHeader #scopeWrapper .on {
+.scope-selector.on {
background: url(../images/scopearrow.png) no-repeat center bottom;
}
-#secondaryHeader #scopeWrapper .ask-message {
+.scope-selector.ask-message {
font-size: 24px;
}
.validate-email-page label {
@@ -435,78 +455,137 @@ body.user-messages {
#searchBar {
/* Main search form , check widgets/search_bar.html */
- display: inline-block;
+ display: block;
background-color: #fff;
- width: 400px;
border: 1px solid #c9c9b5;
- float: right;
- height: 42px;
- margin: 6px 0px 0px 15px;
+ height: 41px;
+ z-index: 10000;
+ position: relative;
}
-#searchBar .searchInput,
-#searchBar .searchInputCancelable {
- font-size: 26px;
- height: 39px;
- line-height: 39px;
+#searchBar input.searchInput {
+ font-size: 22px;
+ height: 26px;
+ line-height: 26px;
font-weight: 300;
background: #FFF;
border: 0px;
color: #484848;
- padding-left: 10px;
- padding-top: 1px;
font-family: Arial;
- vertical-align: top;
+ width: 100%;
+ margin: 8px 0 6px 0;
+ padding: 0;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
}
-#searchBar .searchInput {
- width: 340px;
+#searchBar div.input-tool-tip {
+ margin-top: -40px;
+ padding-top: 10px;
+ height: 30px;
+ line-height: 20px;
+ font-size: 20px;
+ font-style: italic;
+}
+.search-drop-menu {
+ box-sizing: border-box;
+ background: whitesmoke;
+ border: 1px solid #c9c9b5;
+ border-top: none;
+ margin: 0;
+ position: relative;
+ top: 0;
+ z-index: 10000;
+}
+.search-drop-menu ul {
+ list-style: none;
+ overflow: auto;
+ padding: 0 0 10px 0;
+ margin: 0;
+ position: relative;
+}
+.search-drop-menu ul li {
+ padding: 5px 10px;
+ position: relative;
+}
+.search-drop-menu ul li a {
+ text-decoration: none;
+}
+.search-drop-menu ul li.selected {
+ background: #08c;
+}
+.search-drop-menu ul li.selected a {
+ color: whitesmoke;
}
-#searchBar .searchInputCancelable {
- width: 305px;
+.search-drop-menu ul.empty {
+ margin-bottom: 0;
+}
+.search-drop-menu .footer {
+ text-align: center;
+ padding-bottom: 10px;
}
-#searchBar .logoutsearch {
- width: 337px;
+.search-drop-menu.empty ul {
+ padding: 5px;
+ margin: 0;
}
-#searchBar .searchBtn {
+.input-tool-tip {
+ color: #999;
+}
+.input-tool-tip.dimmed {
+ color: #ccc;
+}
+input[type="submit"].searchBtn {
font-size: 10px;
color: #666;
background-color: #eee;
- height: 42px;
+ height: 41px;
border: #FFF 1px solid;
line-height: 22px;
text-align: center;
float: right;
- margin: 0px;
+ margin: 7px 28px 0 0;
width: 48px;
background: -98px -36px url(../images/sprites.png) no-repeat;
cursor: pointer;
+ position: relative;
+ z-index: 10001;
+}
+.ask-page input[type="submit"].searchBtn {
+ display: none;
+}
+.ask-page .input-tool-tip {
+ color: white;
+ height: 0;
+ z-index: 0;
+}
+.ask-page .search-drop-menu.empty {
+ border: none;
+ padding: 0;
}
-#searchBar .searchBtn:hover {
+.ask-page .search-drop-menu.empty ul {
+ padding: 0;
+}
+.searchBtn:hover {
background: -146px -36px url(../images/sprites.png) no-repeat;
}
-#searchBar .cancelSearchBtn {
+.cancelSearchBtn {
font-size: 30px;
color: #ce8888;
background: #fff;
- height: 42px;
+ height: 41px;
line-height: 42px;
border: 0px;
border-left: #deded0 1px solid;
text-align: center;
width: 35px;
cursor: pointer;
+ float: right;
+ margin-top: 7px;
+ position: relative;
+ z-index: 10001;
}
-#searchBar .cancelSearchBtn:hover {
+.cancelSearchBtn:hover {
color: #d84040;
}
-body.anon #searchBar {
- width: 500px;
-}
-body.anon #searchBar .searchInput {
- width: 440px;
-}
-body.anon #searchBar .searchInputCancelable {
- width: 405px;
-}
#askButton {
/* check blocks/secondary_header.html and widgets/ask_button.html*/
@@ -559,6 +638,35 @@ body.anon #searchBar .searchInputCancelable {
-moz-text-shadow: 0px 1px 0px #c6d9dd;
-webkit-text-shadow: 0px 1px 0px #c6d9dd;
}
+/*
+ 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;
+}
+.ask-page .search-drop-menu,
+body.anon.ask-page .search-drop-menu {
+ margin: 0;
+}
+body.anon #searchBar,
+body.anon .search-drop-menu {
+ margin-left: 227px;
+ /* we don't have the "followed" scope */
+
+}
+#searchBar.cancelable {
+ padding-right: 82px;
+}
/* ----- Content layout, check two_column_body.html or one_column_body.html ----- */
#ContentLeft {
width: 730px;
@@ -847,13 +955,20 @@ body.anon #searchBar .searchInputCancelable {
line-height: 1.3;
}
/* tips and markdown help are widgets for ask template */
-#tips li {
- color: #707070;
- font-size: 13px;
- list-style-image: url(../images/tips.png);
+.question-instructions {
+ background: #e9e9e1;
+ -moz-border-radius: 5px;
+ -khtml-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -webkit-box-shadow: 1px 1px 3px #999999;
+ -moz-box-shadow: 1px 1px 3px #999999;
+ box-shadow: 1px 1px 3px #999999;
+ padding: 7px 0 1px 2px;
+ margin-bottom: 10px;
+ width: 100%;
}
-#tips a {
- font-size: 16px;
+.question-instructions ul {
+ margin: 0 0 0 27px;
}
#markdownHelp li {
color: #707070;
@@ -1347,7 +1462,7 @@ ul#related-tags li {
padding-right: 20px;
}
.moderate-tags-page td.per-thread-controls {
- width: 120px;
+ width: 160px;
/* 20px more to compensate for the padding */
height: 30px;
@@ -1355,11 +1470,13 @@ ul#related-tags li {
.moderate-tags-page td.per-thread-controls button {
display: none;
}
-.moderate-tags-page th.decision-col,
.moderate-tags-page th.tags-col,
.moderate-tags-page th.users-col {
width: 100px;
}
+.moderate-tags-page th.decision-col {
+ width: 140px;
+}
.moderate-tags-page tr.per-tag-controls {
height: 30px;
text-align: center;
@@ -1430,8 +1547,9 @@ ul#related-tags li {
}
#askFormBar {
display: inline-block;
- padding: 4px 7px 0px 0px;
+ padding: 4px 0 0 0;
margin-top: 0px;
+ width: 100%;
}
#askFormBar p {
margin: 0 0 5px 0;
@@ -1443,10 +1561,14 @@ ul#related-tags li {
font-size: 24px;
height: 36px;
line-height: 36px;
- margin: 0px;
- padding: 0px 0 0 5px;
+ margin: 0;
+ padding: 0;
+ /*-left: 5px;*/
+
border: #cce6ec 3px solid;
- width: 719px;
+ width: 100%;
+ /*719px;*/
+
}
.ask-page div#question-list,
.edit-question-page div#question-list {
@@ -1492,11 +1614,17 @@ ul#related-tags li {
}
.ask-page #id_tags,
.edit-question-page #id_tags {
+ box-sizing: border-box;
border: #cce6ec 3px solid;
- height: 25px;
+ height: 31px;
padding-left: 5px;
font-size: 14px;
- width: 395px;
+ width: 100%;
+ max-width: 395px;
+}
+.ask-page .lang-selector,
+.edit-question-page .lang-selector {
+ margin: 1px 0 0 5px;
}
.ask-page #id_post_author_username,
.question-page #id_post_author_username,
@@ -1754,7 +1882,6 @@ ul#related-tags li {
}
.wmd-container {
border: #cce6ec 3px solid;
- min-height: 250px;
}
.wmd-container textarea {
border: none;
@@ -1767,12 +1894,17 @@ ul#related-tags li {
.edit-question-page .wmd-container,
.edit-answer-page .wmd-container {
width: 723px;
+ width: 100%;
}
.ask-page #editor,
.question-page #editor,
.edit-question-page #editor,
.edit-answer-page #editor {
- width: 710px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
padding: 6px;
}
.ask-page .retagger-buttons button,
@@ -1786,7 +1918,7 @@ ul#related-tags li {
display: block;
font-size: 100%;
- min-height: 200px;
+ min-height: 210px;
line-height: 18px;
margin: 0;
border: 0;
@@ -1798,7 +1930,8 @@ ul#related-tags li {
width: 100%;
}
.wmd-preview {
- margin: 0;
+ color: #525252;
+ margin: 0 0 12px 0;
padding: 5px;
background-color: #F5F5F5;
min-height: 20px;
@@ -1820,9 +1953,16 @@ ul#related-tags li {
.wmd-preview blockquote {
background-color: #eee;
}
-.wmd-preview IMG {
+.wmd-preview img {
max-width: 600px;
}
+.wmd-preview a {
+ color: #1b79bd;
+}
+.wmd-preview li {
+ margin-bottom: 7px;
+ font-size: 14px;
+}
.defaultSkin table.mceLayout,
.defaultSkin table.mceLayout tr.mceFirst td {
border: none;
@@ -1845,11 +1985,12 @@ ul#related-tags li {
width: 725px;
}
.preview-toggle {
- width: 100%;
color: #b6a475;
/*letter-spacing:1px;*/
+ line-height: 28px;
text-align: left;
+ width: 100%;
}
.preview-toggle span:hover {
cursor: pointer;
@@ -1888,6 +2029,7 @@ ul#related-tags li {
font-size: 14px;
margin-top: 5px;
margin-bottom: 5px;
+ width: 100%;
}
.edit-question-page #id_title,
#fmedit #id_title,
@@ -1898,7 +2040,7 @@ ul#related-tags li {
margin: 0px;
padding: 0px 0 0 5px;
border: #cce6ec 3px solid;
- width: 719px;
+ width: 100%;
margin-bottom: 10px;
}
.edit-question-page #id_summary,
@@ -1977,6 +2119,7 @@ ul#related-tags li {
margin-top: 10px;
font-family: Arial;
color: #4b4b4b;
+ word-wrap: break-word;
}
.question-page .question-body p,
.question-page .answer-body p {
@@ -2940,6 +3083,71 @@ a:hover.medal {
padding: 10px 0px 10px 0px;
font-family: 'Open Sans Condensed', Arial, sans-serif;
}
+.user-profile-page .inputs {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+.user-profile-page .inputs input[type='submit'] {
+ height: 26px;
+ font-size: 15px;
+ text-align: center;
+ text-decoration: none;
+ cursor: pointer;
+ color: #4a757f;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
+ text-shadow: 0px 1px 0px #c6d9dd;
+ -moz-text-shadow: 0px 1px 0px #c6d9dd;
+ -webkit-text-shadow: 0px 1px 0px #c6d9dd;
+ border-top: #eaf2f3 1px solid;
+ background-color: #d1e2e5;
+ background-repeat: no-repeat;
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#d1e2e5), color-stop(25%, #d1e2e5), to(#a9c2c7));
+ background-image: -webkit-linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: -moz-linear-gradient(top, #d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: -ms-linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: -o-linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ border-radius: 4px;
+ -ms-border-radius: 4px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ -khtml-border-radius: 4px;
+ -webkit-box-shadow: 1px 1px 2px #636363;
+ -moz-box-shadow: 1px 1px 2px #636363;
+ box-shadow: 1px 1px 2px #636363;
+}
+.user-profile-page input[type='submit'].select-language {
+ height: 26px;
+ font-size: 15px;
+ text-align: center;
+ text-decoration: none;
+ cursor: pointer;
+ color: #4a757f;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
+ text-shadow: 0px 1px 0px #c6d9dd;
+ -moz-text-shadow: 0px 1px 0px #c6d9dd;
+ -webkit-text-shadow: 0px 1px 0px #c6d9dd;
+ border-top: #eaf2f3 1px solid;
+ background-color: #d1e2e5;
+ background-repeat: no-repeat;
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#d1e2e5), color-stop(25%, #d1e2e5), to(#a9c2c7));
+ background-image: -webkit-linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: -moz-linear-gradient(top, #d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: -ms-linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: -o-linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ border-radius: 4px;
+ -ms-border-radius: 4px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ -khtml-border-radius: 4px;
+ -webkit-box-shadow: 1px 1px 2px #636363;
+ -moz-box-shadow: 1px 1px 2px #636363;
+ box-shadow: 1px 1px 2px #636363;
+}
+.user-profile-page select {
+ margin-bottom: 12px;
+}
.user-details {
font-size: 13px;
}
@@ -3749,14 +3957,6 @@ p.signup_p {
.simple-subscribe-options input {
display: inline;
}
-/* a workaround to set link colors correctly */
-.wmd-preview a {
- color: #1b79bd;
-}
-.wmd-preview li {
- margin-bottom: 7px;
- font-size: 14px;
-}
.search-result-summary {
font-weight: bold;
font-size: 18px;
@@ -3777,6 +3977,10 @@ p.signup_p {
line-height: 18px;
margin-bottom: 15px;
}
+#responses h2 {
+ margin: 0;
+ padding: 0;
+}
#responses div.face {
float: left;
text-align: center;
@@ -3785,7 +3989,7 @@ p.signup_p {
overflow: hidden;
}
.response-parent {
- margin-top: 18px;
+ margin-top: 8px;
}
.response-parent strong {
font-size: 20px;
@@ -3798,9 +4002,6 @@ p.signup_p {
#responses input {
float: left;
}
-#re_tools {
- margin-bottom: 10px;
-}
#re_sections {
margin-bottom: 6px;
}
@@ -3839,110 +4040,123 @@ img.flag {
.main-page img.flag {
vertical-align: text-bottom;
}
-/* Pretty printing styles. Used with prettify.js. */
a.edit {
padding-left: 3px;
color: #145bff;
}
-pre {
- /* name conflict here with tags */
-
-}
-pre .str {
- color: #080;
-}
-pre .kwd {
- color: #008;
-}
-pre .com {
- color: #800;
-}
-pre .typ {
- color: #606;
-}
-pre .lit {
- color: #066;
-}
-pre .pun {
- color: #660;
-}
-pre .pln {
- color: #000;
-}
-pre .tag {
- color: #008;
-}
-pre .atn {
- color: #606;
+/* Pretty printing styles. Used with prettify.js. minified in one line */
+.pln {
+ color: #000000;
}
-pre .atv {
- color: #080;
-}
-pre .dec {
- color: #606;
-}
-pre.prettyprint {
- clear: both;
- padding: 3px;
- border: 0px solid #888;
+@media screen {
+ .str {
+ color: #008800;
+ }
+ .kwd {
+ color: #000088;
+ }
+ .com {
+ color: #880000;
+ }
+ .typ {
+ color: #660066;
+ }
+ .lit {
+ color: #006666;
+ }
+ .pun,
+ .opn,
+ .clo {
+ color: #666600;
+ }
+ .tag {
+ color: #000088;
+ }
+ .atn {
+ color: #660066;
+ }
+ .atv {
+ color: #008800;
+ }
+ .dec,
+ .var {
+ color: #660066;
+ }
+ .fun {
+ color: #ff0000;
+ }
}
-@media print {
- pre .str {
- color: #060;
+@media print, projection {
+ .str {
+ color: #006600;
}
- pre .kwd {
+ .kwd {
color: #006;
font-weight: bold;
}
- pre .com {
+ .com {
color: #600;
font-style: italic;
}
- pre .typ {
+ .typ {
color: #404;
font-weight: bold;
}
- pre .lit {
- color: #044;
+ .lit {
+ color: #004444;
}
- pre .pun {
- color: #440;
+ .pun,
+ .opn,
+ .clo {
+ color: #444400;
}
- pre .pln {
- color: #000;
- }
- pre .tag {
+ .tag {
color: #006;
font-weight: bold;
}
- pre .atn {
- color: #404;
+ .atn {
+ color: #440044;
}
- pre .atv {
- color: #060;
+ .atv {
+ color: #006600;
}
}
+pre.prettyprint {
+ padding: 2px;
+ border: 1px solid #888888;
+}
+ol.linenums {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+li.L0,
+li.L1,
+li.L2,
+li.L3,
+li.L5,
+li.L6,
+li.L7,
+li.L8 {
+ list-style-type: none;
+}
+li.L1,
+li.L3,
+li.L5,
+li.L7,
+li.L9 {
+ background: #eeeeee;
+}
#leading-sidebar {
float: left;
}
/* language-specific fixes */
body.lang-es #searchBar {
- width: 398px;
-}
-body.lang-es #searchBar .searchInput {
- width: 337px;
-}
-body.lang-es #searchBar .searchInputCancelable {
- width: 302px;
+ /* need special left padding */
+
}
body.anon.lang-es #searchBar {
- width: 485px;
-}
-body.anon.lang-es #searchBar .searchInput {
- width: 425px;
-}
-body.anon.lang-es #searchBar .searchInputCancelable {
- width: 390px;
+ /* need special left padding */
+
}
/* user groups */
#user-groups ul {
@@ -4094,7 +4308,7 @@ textarea.tipped-input {
}
.editor-status {
float: right;
- margin: 7px 350px 0 0;
+ margin: 8px 350px 0 0;
font-weight: bold;
}
.editor-status span {
@@ -4147,3 +4361,218 @@ textarea.tipped-input {
width: 515px;
margin-bottom: 0px;
}
+/* modifications for small screens */
+@media screen and (max-width: 960px) {
+ /* content margins touch viewport */
+ #homeButton {
+ background: 1px -36px url(../images/sprites.png) no-repeat;
+ }
+ #homeButton:hover {
+ background: -44px -36px url(../images/sprites.png) no-repeat;
+ }
+}
+@media screen and (max-width: 480px) {
+ .content-wrapper {
+ width: 100%;
+ }
+ #ContentRight {
+ display: none;
+ }
+ #ContentLeft {
+ width: 100%;
+ }
+ .main-page h1,
+ #askButton,
+ #metaNav #navBadges,
+ .user-info,
+ .copyright,
+ .counts .views,
+ .counts .votes,
+ .help,
+ .rss,
+ .scope-selector,
+ .settings,
+ .tabBar,
+ .tags,
+ .userinfo,
+ .widgets {
+ display: none;
+ }
+ .ask-page input[type="submit"].searchBtn,
+ .edit-question-page input[type="submit"].searchBtn {
+ display: none;
+ }
+ .ask-page .preview-toggle,
+ .edit-answer-page .preview-toggle,
+ .edit-question-page .preview-toggle,
+ .ask-page .proxy-user-info,
+ .edit-answer-page .proxy-user-info,
+ .edit-question-page .proxy-user-info,
+ .ask-page .answer-options,
+ .edit-answer-page .answer-options,
+ .edit-question-page .answer-options,
+ .ask-page .question-options,
+ .edit-answer-page .question-options,
+ .edit-question-page .question-options,
+ .ask-page .revision-comment,
+ .edit-answer-page .revision-comment,
+ .edit-question-page .revision-comment,
+ .ask-page .wmd-preview,
+ .edit-answer-page .wmd-preview,
+ .edit-question-page .wmd-preview,
+ .ask-page #wmd-hr-button,
+ .edit-answer-page #wmd-hr-button,
+ .edit-question-page #wmd-hr-button,
+ .ask-page #wmd-heading-button,
+ .edit-answer-page #wmd-heading-button,
+ .edit-question-page #wmd-heading-button {
+ display: none;
+ }
+ .edit-answer-page label[for="id_title"],
+ .edit-question-page label[for="id_title"],
+ .edit-answer-page label[for="id_revision"],
+ .edit-question-page label[for="id_revision"],
+ .edit-answer-page #id_revision,
+ .edit-question-page #id_revision {
+ display: none;
+ }
+ .edit-answer-page #fmedit #id_title,
+ .edit-question-page #fmedit #id_title {
+ margin: 15px 0 0 0;
+ }
+ .question-page .comment-votes {
+ display: none;
+ }
+ .question-page .comments form.post-comments {
+ margin: 0 10px 0 0;
+ }
+ .question-page .comments .comment .comment-body {
+ margin-left: 5px;
+ }
+ .question-page .post-update-info-container {
+ float: none;
+ width: 100%;
+ }
+ .question-page .post-update-info {
+ float: none;
+ margin-left: 0;
+ width: 95%;
+ }
+ .question-page .post-update-info br,
+ .question-page .post-update-info .badge1,
+ .question-page .post-update-info .badge2,
+ .question-page .post-update-info .badge3,
+ .question-page .post-update-info .gravatar,
+ .question-page .post-update-info .reputation-score,
+ .question-page .post-update-info .badge-count {
+ display: none;
+ }
+ .question-page .question-content,
+ .question-page ul.post-retag input {
+ width: 88%;
+ }
+ .question-page .answer-table,
+ .question-page #question-table {
+ width: 85%;
+ }
+ .users-page .userList td {
+ display: block;
+ width: 100%;
+ }
+ .users-page .userList td .user {
+ width: 100%;
+ }
+ .user-profile-page td {
+ display: block;
+ }
+ .footer-links,
+ .powered-link {
+ text-align: center;
+ width: 100%;
+ }
+ #userToolsNav {
+ margin-left: 10px;
+ }
+ #metaNav {
+ float: left;
+ }
+ #metaNav a#navUsers,
+ #metaNav a#navTags,
+ #metaNav a#navGroups {
+ background: none;
+ color: #d0e296;
+ font-size: 16px;
+ text-decoration: underline;
+ margin-left: 20px;
+ padding-left: 0;
+ }
+ .powered-link {
+ margin-bottom: 15px;
+ }
+ .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;
+ }
+ input[type="submit"].searchBtn {
+ margin-right: 8px;
+ }
+ .short-summary {
+ width: 100%;
+ }
+}
+.tag-subscriptions {
+ border-spacing: 10px;
+ border-collapse: separate;
+}
+.tag-subscriptions button {
+ height: 27px;
+ font-size: 14px;
+ text-align: center;
+ text-decoration: none;
+ cursor: pointer;
+ color: #4a757f;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
+ text-shadow: 0px 1px 0px #c6d9dd;
+ -moz-text-shadow: 0px 1px 0px #c6d9dd;
+ -webkit-text-shadow: 0px 1px 0px #c6d9dd;
+ border-top: #eaf2f3 1px solid;
+ background-color: #d1e2e5;
+ background-repeat: no-repeat;
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#d1e2e5), color-stop(25%, #d1e2e5), to(#a9c2c7));
+ background-image: -webkit-linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: -moz-linear-gradient(top, #d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: -ms-linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: -o-linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ background-image: linear-gradient(#d1e2e5, #d1e2e5 25%, #a9c2c7);
+ border-radius: 4px;
+ -ms-border-radius: 4px;
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ -khtml-border-radius: 4px;
+ -webkit-box-shadow: 1px 1px 2px #636363;
+ -moz-box-shadow: 1px 1px 2px #636363;
+ box-shadow: 1px 1px 2px #636363;
+}
+.tag-subscriptions form {
+ display: inline-block;
+ margin-bottom: 0;
+}
+.tag-subscriptions td {
+ vertical-align: middle;
+}
+.tag-subscriptions .action {
+ cursor: pointer;
+ color: #4A757F;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
+ text-decoration: none;
+}
+.tag-subscriptions ul.tags li {
+ margin: 2px 5px;
+}
diff --git a/askbot/media/style/style.less b/askbot/media/style/style.less
index 1404b4c0..5dce292c 100644
--- a/askbot/media/style/style.less
+++ b/askbot/media/style/style.less
@@ -152,6 +152,10 @@ a:hover {
text-decoration: underline;
}
+.avatar-box {
+ text-decoration: none;
+}
+
.badge-context-toggle.active {
cursor: pointer;
text-decoration: underline;
@@ -187,7 +191,8 @@ body.user-messages {
top: 0px;
left: 0px;
width: 100%;
- z-index: 100;
+ height: 34px;
+ z-index: 100000;
padding: 0;
text-align: center;
background-color: #f5dd69;
@@ -201,6 +206,11 @@ body.user-messages {
}
}
+.wait-icon-box {
+ text-align: center;
+ margin-bottom: 8px;
+}
+
#closeNotify {
position: absolute;
right: 5px;
@@ -239,9 +249,31 @@ body.user-messages {
float: left;
}
+.lang-nav {
+ position: relative;
+ ul {
+ display: none;
+ list-style: none;
+ z-index: 10000;
+ margin: 0;
+ }
+ &:hover ul,
+ ul:hover {
+ display: block;
+ position: absolute;
+ width: 100px;
+ }
+ li {
+ color: @info-text;
+ background: white;
+ display: block;
+ }
+}
+
#userToolsNav {/* Navigation bar containing login link or user information, check widgets/user_navigation.html*/
height: 20px;
padding-bottom:5px;
+ white-space: nowrap;
a {
height: 35px;
@@ -368,6 +400,7 @@ body.user-messages {
.dropdown-menu{
border-top: none;
left: 7%;
+ z-index: 10100;
a{
color: #666;
height: 25px;
@@ -395,44 +428,37 @@ body.user-messages {
border-top:#fcfcfc 1px solid;
margin-bottom:10px;
font-family:@main-font;
+}
- #homeButton{
- border-right:#afaf9e 1px solid;
- .sprites(-6px,-36px);
- height:55px;
- width:43px;
- display:block;
- float:left;
- }
-
- #homeButton:hover{
- .sprites(-6px-45,-36px);
- }
-
- #scopeWrapper{
- width:688px;
- float:left;
-
- a{
- display:block;
- float:left;
- }
+#homeButton{
+ border-right: #afaf9e 1px solid;
+ .sprites(-6px,-36px);
+ height:55px;
+ width:43px;
+ display:block;
+ float:left;
+}
- .scope-selector{
- font-size:20px;
- color:#7a7a6b;
- height:55px;
- line-height:55px;
- margin-left:16px
- }
- .on{
- background:url(../images/scopearrow.png) no-repeat center bottom;
- }
+#homeButton:hover{
+ .sprites(-51px,-36px);
+}
- .ask-message{
- font-size:24px;
- }
- }
+.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;
}
.validate-email-page {
@@ -455,90 +481,153 @@ body.user-messages {
}
#searchBar { /* Main search form , check widgets/search_bar.html */
- display: inline-block;
+ display: block;
background-color: #fff;
- width: 400px;
border: 1px solid #c9c9b5;
- float:right;
- height:42px;
- margin:6px 0px 0px 15px;
+ height: 41px;
+ z-index: 10000;
+ position: relative;
- .searchInput, .searchInputCancelable{
- font-size: 26px;
- height: 39px;
- line-height: 39px;
+ input.searchInput {
+ font-size: 22px;
+ height: 26px;
+ line-height: 26px;
font-weight:300;
background:#FFF;
border:0px;
color:#484848;
- padding-left:10px;
- padding-top: 1px;
font-family:@body-font;
- vertical-align: top;
- }
-
- .searchInput,{
- width: 340px;
+ width: 100%;
+ margin: 8px 0 6px 0;
+ padding: 0;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
}
- .searchInputCancelable {
- width: 305px;
+ div.input-tool-tip {
+ margin-top: -40px;
+ padding-top: 10px;
+ height: 30px;
+ line-height: 20px;
+ font-size: 20px;
+ font-style: italic;
}
+}
- .logoutsearch {
- width: 337px;
- }
+.search-drop-menu {
+ box-sizing: border-box;
+ background: whitesmoke;
+ border: 1px solid #c9c9b5;
+ border-top: none;
+ margin: 0;
+ position: relative;
+ top: 0;
+ z-index: 10000;
- .searchBtn {
- font-size: 10px;
- color: #666;
- background-color: #eee;
- height: 42px;
- border:#FFF 1px solid;
- line-height: 22px;
- text-align: center;
- float:right;
- margin: 0px;
- width:48px;
- .sprites(-98px,-36px);
- cursor:pointer;
+ ul {
+ list-style: none;
+ overflow: auto;
+ padding: 0 0 10px 0;
+ margin: 0;
+ position: relative;
+ li {
+ padding: 5px 10px;
+ position: relative;
+ a {
+ text-decoration: none;
+ }
+ }
+ li.selected {
+ background: #08c;
+ a {
+ color: whitesmoke;
+ }
+ }
}
- .searchBtn:hover {
- .sprites(-98px-48,-36px);
+ ul.empty {
+ margin-bottom: 0;
}
- .cancelSearchBtn {
- font-size: 30px;
- color: #ce8888;
- background:#fff;
- height: 42px;
- line-height: 42px;
- border:0px;
- border-left:#deded0 1px solid;
+ .footer {
text-align: center;
- width: 35px;
- cursor:pointer;
+ padding-bottom: 10px;
}
+}
- .cancelSearchBtn:hover {
- color: #d84040;
+.search-drop-menu.empty {
+ ul {
+ padding: 5px;
+ margin: 0;
}
}
-body.anon {
- #searchBar {
- width: 500px;
- .searchInput {
- width: 440px;
- }
+.input-tool-tip {
+ color: #999;
+}
+.input-tool-tip.dimmed {
+ color: #ccc;
+}
- .searchInputCancelable {
- width: 405px;
+input[type="submit"].searchBtn {
+ font-size: 10px;
+ color: #666;
+ background-color: #eee;
+ height: 41px;
+ border:#FFF 1px solid;
+ line-height: 22px;
+ text-align: center;
+ float:right;
+ margin: 7px 28px 0 0;
+ width: 48px;
+ .sprites(-98px,-36px);
+ cursor:pointer;
+ position: relative;
+ z-index: 10001;
+}
+.ask-page {
+ input[type="submit"].searchBtn {
+ display: none;
+ }
+ .input-tool-tip {
+ color: white;
+ height: 0;
+ z-index: 0;
+ }
+ .search-drop-menu.empty {
+ border: none;
+ padding: 0;
+ ul {
+ padding: 0;
}
}
}
+.searchBtn:hover {
+ .sprites(-98px-48,-36px);
+}
+
+.cancelSearchBtn {
+ font-size: 30px;
+ color: #ce8888;
+ background:#fff;
+ height: 41px;
+ line-height: 42px;
+ border:0px;
+ border-left:#deded0 1px solid;
+ text-align: center;
+ width: 35px;
+ cursor:pointer;
+ float: right;
+ margin-top: 7px;
+ position: relative;
+ z-index: 10001;
+}
+
+.cancelSearchBtn:hover {
+ color: #d84040;
+}
#askButton{ /* check blocks/secondary_header.html and widgets/ask_button.html*/
line-height:44px;
@@ -553,6 +642,37 @@ body.anon {
.button-style-hover;
}
+/*
+ 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;
+}
+.ask-page .search-drop-menu,
+body.anon.ask-page .search-drop-menu {
+ margin: 0;
+}
+body.anon {
+ #searchBar,
+ .search-drop-menu {
+ margin-left: 227px;/* we don't have the "followed" scope */
+ }
+}
+#searchBar.cancelable {
+ padding-right: 82px;
+}
+
+
/* ----- Content layout, check two_column_body.html or one_column_body.html ----- */
#ContentLeft {
@@ -783,14 +903,17 @@ body.anon {
}
/* tips and markdown help are widgets for ask template */
-#tips{
- li{
- color:@info-text;
- font-size:13px;
- list-style-image: url(../images/tips.png);
- }
- a{
- font-size:16px;
+.question-instructions {
+ background: #e9e9e1;
+ -moz-border-radius: 5px;
+ -khtml-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ .box-shadow(1px, 1px, 3px, #999);
+ padding: 7px 0 1px 2px;
+ margin-bottom: 10px;
+ width: 100%;
+ ul {
+ margin: 0 0 0 27px;
}
}
@@ -1335,17 +1458,19 @@ ul#related-tags li {
padding-right: 20px;
}
td.per-thread-controls {
- width: 120px;/* 20px more to compensate for the padding */
+ width: 160px;/* 20px more to compensate for the padding */
height: 30px;
button {
display: none;
}
}
- th.decision-col,
th.tags-col,
th.users-col {
width: 100px;
}
+ th.decision-col {
+ width: 140px;
+ }
tr.per-tag-controls {
height: 30px;
text-align: center;
@@ -1423,10 +1548,11 @@ ul#related-tags li {
#askFormBar {
display:inline-block;
- padding: 4px 7px 0px 0px;
+ padding: 4px 0 0 0;
margin-top:0px;
+ width: 100%;
- p{
+ p {
margin:0 0 5px 0;
font-size:14px;
color:@info-text-dark;
@@ -1436,10 +1562,10 @@ ul#related-tags li {
font-size: 24px;
height: 36px;
line-height: 36px;
- margin: 0px;
- padding: 0px 0 0 5px;
+ margin: 0;
+ padding: 0;/*-left: 5px;*/
border:#cce6ec 3px solid;
- width:719px;
+ width: 100%;/*719px;*/
}
}
@@ -1483,11 +1609,16 @@ ul#related-tags li {
}
#id_tags {
- border:#cce6ec 3px solid;
- height:25px;
- padding-left:5px;
- font-size:14px;
- width:395px;
+ box-sizing: border-box;
+ border: #cce6ec 3px solid;
+ height: 31px;
+ padding-left: 5px;
+ font-size: 14px;
+ width: 100%;
+ max-width: 395px;
+ }
+ .lang-selector {
+ margin: 1px 0 0 5px;
}
}
@@ -1632,7 +1763,6 @@ ul#related-tags li {
.wmd-container {
border:#cce6ec 3px solid;
- min-height: 250px;
textarea {
border: none;
}
@@ -1646,9 +1776,14 @@ ul#related-tags li {
.edit-answer-page {
.wmd-container {
width: 723px;
+ width: 100%;
}
#editor {
- width: 710px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
padding: 6px;
}
.retagger-buttons {
@@ -1661,7 +1796,7 @@ ul#related-tags li {
#editor { /* adjustment for editor preview */
display: block;
font-size: 100%;
- min-height: 200px;
+ min-height: 210px;
line-height: 18px;
margin: 0;
border: 0;
@@ -1677,7 +1812,7 @@ ul#related-tags li {
.wmd-preview {
color: #525252;
- margin: 0;
+ margin: 0 0 12px 0;
padding: 5px;
background-color: #F5F5F5;
min-height: 20px;
@@ -1741,9 +1876,10 @@ ul#related-tags li {
}
.preview-toggle {
- width: 100%;
color: #b6a475; /*letter-spacing:1px;*/
+ line-height: 28px;
text-align: left;
+ width: 100%;
}
.preview-toggle span:hover {
@@ -1784,6 +1920,7 @@ ul#related-tags li {
font-size:14px;
margin-top:5px;
margin-bottom:5px;
+ width: 100%;
}
#id_title{
font-size: 24px;
@@ -1792,7 +1929,7 @@ ul#related-tags li {
margin: 0px;
padding: 0px 0 0 5px;
border:#cce6ec 3px solid;
- width: 719px;
+ width: 100%;
margin-bottom:10px;
}
#id_summary{
@@ -1838,7 +1975,7 @@ ul#related-tags li {
vertical-align: top;
}
- .question-content{
+ .question-content {
float:right;
width:682px;
margin-bottom:10px;
@@ -1879,6 +2016,7 @@ ul#related-tags li {
margin-top:10px;
font-family:@body-font;
color:#4b4b4b;
+ word-wrap: break-word;
p{
margin-bottom:14px;
@@ -1949,7 +2087,8 @@ ul#related-tags li {
margin-top:10px;
margin-bottom:8px;
- a {
+ a,
+ span.dropdown-toggle {
color: #777;
padding: 0px 7px 3px 18px;
cursor: pointer;
@@ -1958,17 +2097,51 @@ ul#related-tags li {
font-family:@body-font;
text-decoration: none;
height:18px;
- display:block;
- float:right;
line-height:18px;
margin-top:-2px;
margin-left:4px;
}
- a:hover {
+ a:hover,
+ span.dropdown-toggle:hover {
background-color: #f5f0c9;
+ }
+ span.dropdown-toggle {
+ background: url(../images/sprites.png) no-repeat -7px -242px;
.rounded-corners(3px);
-
+ position: relative;
+ }
+ span.dropdown-toggle:hover {
+ padding-right: 0;
+ background: url(../images/sprites.png) no-repeat -7px -274px;
+ form {
+ margin: 0;
+ }
+ input {
+ display: block !important;
+ height: 20px !important;
+ line-height: 20px !important;
+ margin: 0;
+ padding: 0 5px;
+ .rounded-corners(0);
+ width: 100% !important;
+ }
+ .dropdown-menu {
+ display: block;
+ padding: 5px 0;
+ right: -5px !important;
+ left: auto;
+ li,
+ li:hover {
+ display: block !important;
+ margin: 0;
+ padding: 0;
+ width: 100% !important;
+ }
+ li:hover {
+ background-color: #f5f0c9;
+ }
+ }
}
.sep {
color: #ccc;
@@ -1979,11 +2152,11 @@ ul#related-tags li {
}
.post-controls, .answer-controls{
.question-delete{
- background: url(../images/delete.png) no-repeat left 2px;
+ background: url(../images/delete.png) no-repeat left -1px;
padding-left:11px;
}
.question-flag{
- background: url(../images/flag.png) no-repeat center left;
+ background: url(../images/flag.png) no-repeat 2px 0;
}
.answer-publish{
background: url(../images/publish.png) no-repeat center left;
@@ -1992,7 +2165,7 @@ ul#related-tags li {
background: url(../images/unpublish.png) no-repeat 2px center;
}
.question-edit{
- background: url(../images/edit2.png) no-repeat 2px center;
+ background: url(../images/edit2.png) no-repeat 3px 1px;
}
.question-retag{
background: url(../images/retag.png) no-repeat center left;
@@ -2001,7 +2174,7 @@ ul#related-tags li {
background: url(../images/close.png) no-repeat center left;
}
.permant-link{
- background: url(../images/link.png) no-repeat center left;
+ background: url(../images/link.png) no-repeat 2px 1px;
}
.answer-convert{
@@ -2506,12 +2679,14 @@ ul#related-tags li {
.meta,
.users-page,
.user-profile-edit-page,
-.user-profile-page,
-{
+.user-profile-page {
form{
margin-bottom:15px;
}
- input[type="text"],input[type="password"],select{
+
+ input[type="text"],
+ input[type="password"],
+ select{
border:#cce6ec 3px solid;
height:25px;
line-height: 25px;
@@ -2706,7 +2881,7 @@ a:hover.medal {
float:left;
}
-.user-profile-page{
+.user-profile-page {
color:@info-text-dark;
p{
@@ -2714,14 +2889,28 @@ a:hover.medal {
line-height:1.3;
color:@info-text-dark;
}
- .avatar img{
+ .avatar img {
border:#eee 1px solid;
padding:5px;
}
- h2{
+ h2 {
padding:10px 0px 10px 0px;
font-family:@main-font;
}
+
+ .inputs {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ input[type='submit']{
+ .button-style(26px,15px);
+ }
+ }
+ input[type='submit'].select-language {
+ .button-style(26px,15px);
+ }
+ select {
+ margin-bottom: 12px;
+ }
}
.user-details {
@@ -3635,6 +3824,10 @@ p.signup_p {
clear:both;
line-height:18px;
margin-bottom:15px;
+ h2 {
+ margin: 0;
+ padding: 0;
+ }
}
#responses div.face {
@@ -3646,7 +3839,7 @@ p.signup_p {
}
.response-parent {
- margin-top: 18px;
+ margin-top: 8px;
}
.response-parent strong{
@@ -3662,9 +3855,6 @@ p.signup_p {
#responses input {
float:left;
}
-#re_tools {
- margin-bottom:10px;
-}
#re_sections {
margin-bottom:6px;
}
@@ -3712,42 +3902,14 @@ img.flag {
}
-/* Pretty printing styles. Used with prettify.js. */
-
a.edit {
padding-left:3px;
color: #145bff;
}
-pre {
- .str { color: #080; }
- .kwd { color: #008; }
- .com { color: #800; }
- .typ { color: #606; }
- .lit { color: #066; }
- .pun { color: #660; }
- .pln { color: #000; }
- .tag { color: #008; }/* name conflict here with tags */
- .atn { color: #606; }
- .atv { color: #080; }
- .dec { color: #606; }
-}
-pre.prettyprint { clear:both;padding: 3px; border: 0px solid #888; }
-
-@media print {
- pre {
- .str { color: #060; }
- .kwd { color: #006; font-weight: bold; }
- .com { color: #600; font-style: italic; }
- .typ { color: #404; font-weight: bold; }
- .lit { color: #044; }
- .pun { color: #440; }
- .pln { color: #000; }
- .tag { color: #006; font-weight: bold; }
- .atn { color: #404; }
- .atv { color: #060; }
- }
-}
+/* Pretty printing styles. Used with prettify.js. minified in one line */
+.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
+
#leading-sidebar {
float: left;
@@ -3756,24 +3918,12 @@ pre.prettyprint { clear:both;padding: 3px; border: 0px solid #888; }
/* language-specific fixes */
body.lang-es {
#searchBar {
- width: 398px;
- .searchInput {
- width: 337px;
- }
- .searchInputCancelable {
- width: 302px;
- }
+ /* need special left padding */
}
}
body.anon.lang-es {
#searchBar {
- width: 485px;
- .searchInput {
- width: 425px;
- }
- .searchInputCancelable {
- width: 390px;
- }
+ /* need special left padding */
}
}
@@ -3950,7 +4100,7 @@ textarea.tipped-input {
.editor-status {
float: right;
- margin: 7px 350px 0 0;
+ margin: 8px 350px 0 0;
font-weight: bold;
span {
@@ -4004,3 +4154,205 @@ textarea.tipped-input {
width: 515px;
margin-bottom: 0px;
}
+
+/* modifications for small screens */
+@media screen and (max-width: 960px) {/* content margins touch viewport */
+ #homeButton {
+ .sprites(1px,-36px);
+ }
+ #homeButton:hover {
+ .sprites(-44px,-36px);
+ }
+}
+@media screen and (max-width: 480px) {
+ .content-wrapper {
+ width: 100%;
+ }
+ #ContentRight {
+ display: none;
+ }
+ #ContentLeft {
+ width: 100%;
+ }
+ .main-page h1,
+ #askButton,
+ #metaNav #navBadges,
+ .user-info,
+ .copyright,
+ .counts .views,
+ .counts .votes,
+ .help,
+ .rss,
+ .scope-selector,
+ .settings,
+ .tabBar,
+ .tags,
+ .userinfo,
+ .widgets {
+ display: none;
+ }
+
+ .ask-page,
+ .edit-question-page {
+ input[type="submit"].searchBtn {
+ display: none;
+ }
+ }
+
+ .ask-page,
+ .edit-answer-page,
+ .edit-question-page {
+ .preview-toggle,
+ .proxy-user-info,
+ .answer-options,
+ .question-options,
+ .revision-comment,
+ .wmd-preview,
+ #wmd-hr-button,
+ #wmd-heading-button {
+ display: none;
+ }
+ }
+
+ .edit-answer-page,
+ .edit-question-page {
+ label[for="id_title"],
+ label[for="id_revision"],
+ #id_revision {
+ display: none;
+ }
+ #fmedit #id_title {
+ margin: 15px 0 0 0;
+ }
+ }
+
+ .question-page {
+ .comment-votes {
+ display: none;
+ }
+ .comments {
+ form.post-comments {
+ margin: 0 10px 0 0;
+ }
+ .comment .comment-body {
+ margin-left: 5px;
+ }
+ }
+ .post-update-info-container {
+ float: none;
+ width: 100%;
+ }
+ .post-update-info {
+ float: none;
+ margin-left: 0;
+ width: 100%-5;
+
+ br,
+ .badge1,
+ .badge2,
+ .badge3,
+ .gravatar,
+ .reputation-score,
+ .badge-count {
+ display: none;
+ }
+ }
+ .question-content,
+ ul.post-retag input {
+ width: 100%-12;
+ }
+ .answer-table,
+ #question-table {
+ width: 100%-15;
+ }
+ }
+
+ .users-page {
+ .userList td {
+ display: block;
+ width: 100%;
+ .user {
+ width: 100%;
+ }
+ }
+ }
+
+ .user-profile-page {
+ td {
+ display: block;
+ }
+ }
+
+ .footer-links,
+ .powered-link {
+ text-align: center;
+ width: 100%;
+ }
+
+ #userToolsNav {
+ margin-left: 10px;
+ }
+
+ #metaNav {
+ float: left;
+ a#navUsers,
+ a#navTags,
+ a#navGroups {
+ background: none;
+ color: #d0e296;
+ font-size: 16px;
+ text-decoration: underline;
+ margin-left: 20px;
+ padding-left: 0;
+ }
+ }
+ .powered-link {
+ margin-bottom: 15px;
+ }
+ .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;
+ }
+ input[type="submit"].searchBtn {
+ margin-right: 8px;
+ }
+ .short-summary {
+ width: 100%;
+ }
+}
+
+.tag-subscriptions {
+ border-spacing: 10px;
+ border-collapse: separate;
+
+ button {
+ .button-style(27px, 14px);
+ }
+
+ form {
+ display: inline-block;
+ margin-bottom: 0;
+ }
+
+ td {
+ vertical-align: middle;
+ }
+
+ .action {
+ cursor: pointer;
+ color: #4A757F;
+ font-family: 'Open Sans Condensed', Arial, sans-serif;
+ text-decoration: none;
+ }
+
+ ul.tags li {
+ margin: 2px 5px;
+ }
+}
diff --git a/askbot/middleware/forum_mode.py b/askbot/middleware/forum_mode.py
index d593a6f2..331fe85b 100644
--- a/askbot/middleware/forum_mode.py
+++ b/askbot/middleware/forum_mode.py
@@ -11,7 +11,7 @@ from askbot.conf import settings as askbot_settings
PROTECTED_VIEW_MODULES = (
'askbot.views',
- 'django.contrib.syndication.views',
+ 'askbot.feed',
)
ALLOWED_VIEWS = (
'askbot.views.meta.media',
@@ -30,7 +30,13 @@ def is_view_allowed(func):
"""True, if view is allowed to access
by the special rule
"""
- view_path = func.__module__ + '.' + func.__name__
+ if hasattr(func, '__name__'):
+ view_path = func.__module__ + '.' + func.__name__
+ elif hasattr(func, '__class__'):
+ view_path = func.__module__ + '.' + func.__class__.__name__
+ else:
+ view_path = ''
+
return view_path in ALLOWED_VIEWS
class ForumModeMiddleware(object):
@@ -51,7 +57,7 @@ class ForumModeMiddleware(object):
if is_view_allowed(resolver_match.func):
return
-
+
if is_view_protected(resolver_match.func):
request.user.message_set.create(
_('Please log in to use %s') % \
diff --git a/askbot/migrations/0013_add_response_count__to_user.py b/askbot/migrations/0013_add_response_count__to_user.py
index f3d724e3..68ac0c3c 100644
--- a/askbot/migrations/0013_add_response_count__to_user.py
+++ b/askbot/migrations/0013_add_response_count__to_user.py
@@ -3,6 +3,7 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
@@ -13,16 +14,12 @@ class Migration(SchemaMigration):
a bit hacky but we have to do it as long as we keep patching auth models
within the forum application
"""
- try:
- db.add_column(
- u'auth_user',
- 'response_count',
- self.gf('django.db.models.fields.IntegerField')(default=0, ),
- keep_default=False
- )
- except:
- print 'probably already have column User.response_count'
- pass
+ safe_add_column(
+ u'auth_user',
+ 'response_count',
+ self.gf('django.db.models.fields.IntegerField')(default=0, ),
+ keep_default=False
+ )
def backwards(self, orm):
diff --git a/askbot/migrations/0014_rename_schema_from_forum_to_askbot.py b/askbot/migrations/0014_rename_schema_from_forum_to_askbot.py
index f5f913da..f9a5b739 100644
--- a/askbot/migrations/0014_rename_schema_from_forum_to_askbot.py
+++ b/askbot/migrations/0014_rename_schema_from_forum_to_askbot.py
@@ -10,19 +10,20 @@ app_dir_name = os.path.basename(os.path.dirname(os.path.dirname(__file__)))
class Migration(SchemaMigration):
def forwards(self, orm):
- try:
- db.rename_table('forum_anonymousanswer', 'askbot_anonymousanswer')
- db.rename_table('forum_anonymousquestion', 'askbot_anonymousquestion')
- db.rename_table('forum_emailfeedsetting', 'askbot_emailfeedsetting')
- db.rename_table('forum_markedtag', 'askbot_markedtag')
- db.rename_table('forum_questionview', 'askbot_questionview')
- db.rename_table('forum_validationhash', 'askbot_validationhash')
- except:
- pass
+ if app_dir_name == 'forum':
+ try:
+ db.rename_table('forum_anonymousanswer', 'askbot_anonymousanswer')
+ db.rename_table('forum_anonymousquestion', 'askbot_anonymousquestion')
+ db.rename_table('forum_emailfeedsetting', 'askbot_emailfeedsetting')
+ db.rename_table('forum_markedtag', 'askbot_markedtag')
+ db.rename_table('forum_questionview', 'askbot_questionview')
+ db.rename_table('forum_validationhash', 'askbot_validationhash')
+ except:
+ pass
def backwards(self, orm):
- if app_dirname == 'forum':
+ if app_dir_name == 'forum':
db.rename_table('askbot_anonymousanswer', 'forum_anonymousanswer')
db.rename_table('askbot_anonymousquestion', 'forum_anonymousquestion')
db.rename_table('askbot_emailfeedsetting', 'forum_emailfeedsetting')
diff --git a/askbot/migrations/0018_add___status__field_to_user_model.py b/askbot/migrations/0018_add___status__field_to_user_model.py
index 5a713866..b30f30d7 100644
--- a/askbot/migrations/0018_add___status__field_to_user_model.py
+++ b/askbot/migrations/0018_add___status__field_to_user_model.py
@@ -3,21 +3,19 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'User.status'
- try:
- db.add_column(
- u'auth_user',
- 'status',
- self.gf('django.db.models.fields.CharField')(default ='w', max_length = 2),
- keep_default=False
- )
- except:
- pass
+ safe_add_column(
+ u'auth_user',
+ 'status',
+ self.gf('django.db.models.fields.CharField')(default ='w', max_length = 2),
+ keep_default=False
+ )
def backwards(self, orm):
diff --git a/askbot/migrations/0026_add_seen_and_new_response_counts_to_user.py b/askbot/migrations/0026_add_seen_and_new_response_counts_to_user.py
index 4cd05f83..8b6002bf 100644
--- a/askbot/migrations/0026_add_seen_and_new_response_counts_to_user.py
+++ b/askbot/migrations/0026_add_seen_and_new_response_counts_to_user.py
@@ -3,16 +3,14 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding fields
- try:
- db.add_column('auth_user', 'new_response_count', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
- db.add_column('auth_user', 'seen_response_count', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
- except:
- pass
+ safe_add_column('auth_user', 'new_response_count', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
+ safe_add_column('auth_user', 'seen_response_count', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
def backwards(self, orm):
# Deleting fields
diff --git a/askbot/migrations/0033_add__consecutive_days_visit_count__to__auth_user.py b/askbot/migrations/0033_add__consecutive_days_visit_count__to__auth_user.py
index 580c2f25..e5a10faf 100644
--- a/askbot/migrations/0033_add__consecutive_days_visit_count__to__auth_user.py
+++ b/askbot/migrations/0033_add__consecutive_days_visit_count__to__auth_user.py
@@ -3,21 +3,19 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'User.consecutive_days_visit_count'
- try:
- db.add_column(
- u'auth_user',
- 'consecutive_days_visit_count',
- self.gf('django.db.models.fields.IntegerField')(default = 0, max_length = 2),
- keep_default=False
- )
- except:
- pass
+ safe_add_column(
+ u'auth_user',
+ 'consecutive_days_visit_count',
+ self.gf('django.db.models.fields.IntegerField')(default = 0, max_length = 2),
+ keep_default=False
+ )
def backwards(self, orm):
diff --git a/askbot/migrations/0035_add_country_fields_to_user.py b/askbot/migrations/0035_add_country_fields_to_user.py
index 02dd404c..340883ba 100644
--- a/askbot/migrations/0035_add_country_fields_to_user.py
+++ b/askbot/migrations/0035_add_country_fields_to_user.py
@@ -3,17 +3,15 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model country fields to the model auth_user
- try:
- db.add_column(u'auth_user', 'country', self.gf('django_countries.fields.CountryField')(max_length=2, blank=True, null=True))
- db.add_column(u'auth_user', 'show_country', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True))
- except:
- pass
+ safe_add_column(u'auth_user', 'country', self.gf('django_countries.fields.CountryField')(max_length=2, blank=True, null=True))
+ safe_add_column(u'auth_user', 'show_country', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True))
def backwards(self, orm):
diff --git a/askbot/migrations/0037_add_marked_tags_to_user_profile.py b/askbot/migrations/0037_add_marked_tags_to_user_profile.py
index f10f53be..306e16e6 100644
--- a/askbot/migrations/0037_add_marked_tags_to_user_profile.py
+++ b/askbot/migrations/0037_add_marked_tags_to_user_profile.py
@@ -3,18 +3,16 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
def forwards(self, orm):
- try:
- # Adding field 'User.interesting_tags'
- db.add_column(u'auth_user', 'interesting_tags', self.gf('django.db.models.fields.TextField')(blank=True, default = ''), keep_default=False)
- # Adding field 'User.ignored_tags'
- db.add_column(u'auth_user', 'ignored_tags', self.gf('django.db.models.fields.TextField')(blank=True, default = ''), keep_default=False)
- except:
- pass
+ # Adding field 'User.interesting_tags'
+ safe_add_column(u'auth_user', 'interesting_tags', self.gf('django.db.models.fields.TextField')(blank=True, default = ''), keep_default=False)
+ # Adding field 'User.ignored_tags'
+ safe_add_column(u'auth_user', 'ignored_tags', self.gf('django.db.models.fields.TextField')(blank=True, default = ''), keep_default=False)
def backwards(self, orm):
diff --git a/askbot/migrations/0038_add_tag_filter_strategies.py b/askbot/migrations/0038_add_tag_filter_strategies.py
index c2596366..a24d12bf 100644
--- a/askbot/migrations/0038_add_tag_filter_strategies.py
+++ b/askbot/migrations/0038_add_tag_filter_strategies.py
@@ -4,29 +4,27 @@ from south.db import db
from south.v2 import SchemaMigration
from django.db import models
from askbot import const
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model country fields to the model auth_user
- try:
- db.add_column(
- u'auth_user',
- 'email_tag_filter_strategy',
- self.gf(
- 'django.db.models.fields.SmallIntegerField'
- )(default = const.EXCLUDE_IGNORED)
- )
- db.add_column(
- u'auth_user',
- 'display_tag_filter_strategy',
- self.gf(
- 'django.db.models.fields.SmallIntegerField'
- )(default = const.INCLUDE_ALL)
- )
- except:
- pass
+ safe_add_column(
+ u'auth_user',
+ 'email_tag_filter_strategy',
+ self.gf(
+ 'django.db.models.fields.SmallIntegerField'
+ )(default = const.EXCLUDE_IGNORED)
+ )
+ safe_add_column(
+ u'auth_user',
+ 'display_tag_filter_strategy',
+ self.gf(
+ 'django.db.models.fields.SmallIntegerField'
+ )(default = const.INCLUDE_ALL)
+ )
def backwards(self, orm):
diff --git a/askbot/migrations/0043_add_temporal_extra_column_for_datamigration.py b/askbot/migrations/0043_add_temporal_extra_column_for_datamigration.py
index 4a8140a4..7582dc04 100644
--- a/askbot/migrations/0043_add_temporal_extra_column_for_datamigration.py
+++ b/askbot/migrations/0043_add_temporal_extra_column_for_datamigration.py
@@ -3,14 +3,12 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
def forwards(self, orm):
- try:
- db.add_column(u'auth_user', 'avatar_type', self.gf('django.db.models.fields.CharField')(max_length=1, default='n'), keep_default=False)
- except:
- pass
+ safe_add_column(u'auth_user', 'avatar_type', self.gf('django.db.models.fields.CharField')(max_length=1, default='n'), keep_default=False)
def backwards(self, orm):
db.delete_column(u'auth_user', 'avatar_type')
diff --git a/askbot/migrations/0122_auth_user__add_subscribed_tag_field.py b/askbot/migrations/0122_auth_user__add_subscribed_tag_field.py
index d84666fb..7f7ff971 100644
--- a/askbot/migrations/0122_auth_user__add_subscribed_tag_field.py
+++ b/askbot/migrations/0122_auth_user__add_subscribed_tag_field.py
@@ -3,15 +3,13 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
def forwards(self, orm):
- try:
- # Adding field 'User.interesting_tags'
- db.add_column(u'auth_user', 'subscribed_tags', self.gf('django.db.models.fields.TextField')(blank=True, default = ''), keep_default=False)
- except:
- pass
+ # Adding field 'User.interesting_tags'
+ safe_add_column(u'auth_user', 'subscribed_tags', self.gf('django.db.models.fields.TextField')(blank=True, default = ''), keep_default=False)
def backwards(self, orm):
# Deleting field 'User.interesting_tags'
diff --git a/askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py b/askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py
index b5a1e0c9..11b891da 100644
--- a/askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py
+++ b/askbot/migrations/0124_auto__add_field_post_is_private__add_field_replyaddress_reply_action.py
@@ -3,6 +3,7 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
@@ -10,14 +11,14 @@ class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Post.is_private'
db.start_transaction()
- db.add_column('askbot_post', 'is_private',
- self.gf('django.db.models.fields.BooleanField')(default=False),
- keep_default=False)
+ safe_add_column('askbot_post', 'is_private',
+ self.gf('django.db.models.fields.BooleanField')(default=False),
+ keep_default=False)
# Adding field 'ReplyAddress.reply_action'
- db.add_column('askbot_replyaddress', 'reply_action',
- self.gf('django.db.models.fields.CharField')(default='auto_answer_or_comment', max_length=32),
- keep_default=False)
+ safe_add_column('askbot_replyaddress', 'reply_action',
+ self.gf('django.db.models.fields.CharField')(default='auto_answer_or_comment', max_length=32),
+ keep_default=False)
# Changing field 'ReplyAddress.post'
db.alter_column('askbot_replyaddress', 'post_id', self.gf('django.db.models.fields.related.ForeignKey')(null=True, to=orm['askbot.Post']))
@@ -26,7 +27,7 @@ class Migration(SchemaMigration):
try:
db.start_transaction()
# Adding field 'User.interesting_tags'
- db.add_column(u'auth_user', 'email_signature', self.gf('django.db.models.fields.TextField')(blank=True, default = ''), keep_default=False)
+ safe_add_column(u'auth_user', 'email_signature', self.gf('django.db.models.fields.TextField')(blank=True, default = ''), keep_default=False)
db.commit_transaction()
except:
db.rollback_transaction()
diff --git a/askbot/migrations/0125_add_show_tags_field_to_user.py b/askbot/migrations/0125_add_show_tags_field_to_user.py
index cb7ab2bd..fc299d18 100644
--- a/askbot/migrations/0125_add_show_tags_field_to_user.py
+++ b/askbot/migrations/0125_add_show_tags_field_to_user.py
@@ -3,6 +3,7 @@ import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
@@ -10,16 +11,13 @@ class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model show_marked_tags fields to the model auth_user
- try:
- db.add_column(
- u'auth_user',
- 'show_marked_tags',
- self.gf(
- 'django.db.models.fields.BooleanField'
- )(default=True, blank=True)
- )
- except:
- pass
+ safe_add_column(
+ u'auth_user',
+ 'show_marked_tags',
+ self.gf(
+ 'django.db.models.fields.BooleanField'
+ )(default=True, blank=True)
+ )
def backwards(self, orm):
diff --git a/askbot/migrations/0126_add_field__auth_user__is_fake.py b/askbot/migrations/0126_add_field__auth_user__is_fake.py
index e0928ed7..783d1e27 100644
--- a/askbot/migrations/0126_add_field__auth_user__is_fake.py
+++ b/askbot/migrations/0126_add_field__auth_user__is_fake.py
@@ -1,17 +1,14 @@
# -*- coding: utf-8 -*-
from south.db import db
from south.v2 import SchemaMigration
+from askbot.migrations_api import safe_add_column
class Migration(SchemaMigration):
def forwards(self, orm):
- try:
- # Adding field 'User.is_fake'
- db.add_column(
- u'auth_user', 'is_fake',
- self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
- except:
- pass
+ safe_add_column(
+ u'auth_user', 'is_fake',
+ self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
def backwards(self, orm):
db.delete_column('auth_user', 'is_fake')
diff --git a/askbot/migrations/0156_add_message_model_in_new_django.py b/askbot/migrations/0156_add_message_model_in_new_django.py
new file mode 100644
index 00000000..a962b2b4
--- /dev/null
+++ b/askbot/migrations/0156_add_message_model_in_new_django.py
@@ -0,0 +1,388 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models, connection
+import django
+
+DJANGO_VERSION = django.VERSION[:2]
+
+def db_table_exists(table_name):
+ return table_name in connection.introspection.table_names()
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ if DJANGO_VERSION > (1, 3) and not db_table_exists('auth_message'):
+ db.create_table('auth_message', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='_message_set', to=orm['auth.User'])),
+ ('message', self.gf('django.db.models.fields.TextField')())
+ ))
+ db.send_create_signal('askbot', ['Message'])
+
+ def backwards(self, orm):
+ pass
+
+ 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'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ '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'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ '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', 'db_index': 'True'})
+ },
+ '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'})
+ },
+ '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.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'}),
+ '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', [], {}),
+ '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.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'}),
+ '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'}),
+ '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'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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']
diff --git a/askbot/migrations/0157_auto__del_field_anonymousquestion_summary__del_field_anonymousanswer_s.py b/askbot/migrations/0157_auto__del_field_anonymousquestion_summary__del_field_anonymousanswer_s.py
new file mode 100644
index 00000000..1c7fa7b6
--- /dev/null
+++ b/askbot/migrations/0157_auto__del_field_anonymousquestion_summary__del_field_anonymousanswer_s.py
@@ -0,0 +1,387 @@
+# -*- 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):
+ # Deleting field 'AnonymousQuestion.summary'
+ db.delete_column('askbot_anonymousquestion', 'summary')
+
+ # Deleting field 'AnonymousAnswer.summary'
+ db.delete_column('askbot_anonymousanswer', 'summary')
+
+ def backwards(self, orm):
+ # Adding field 'AnonymousQuestion.summary'
+ db.add_column('askbot_anonymousquestion', 'summary',
+ self.gf('django.db.models.fields.CharField')(default='', max_length=180),
+ keep_default=False)
+
+ # Adding field 'AnonymousAnswer.summary'
+ db.add_column('askbot_anonymousanswer', 'summary',
+ self.gf('django.db.models.fields.CharField')(default='', max_length=180),
+ keep_default=False)
+
+ 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.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'})
+ },
+ '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.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'}),
+ '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', [], {}),
+ '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.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'}),
+ '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'}),
+ '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'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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/0158_add_title_search_indices_for_postgresql_and_mysql.py b/askbot/migrations/0158_add_title_search_indices_for_postgresql_and_mysql.py
new file mode 100644
index 00000000..f2351a02
--- /dev/null
+++ b/askbot/migrations/0158_add_title_search_indices_for_postgresql_and_mysql.py
@@ -0,0 +1,405 @@
+# -*- coding: utf-8 -*-
+import askbot
+import datetime
+import os
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from askbot.migrations_api import mysql_table_supports_full_text_search
+from askbot.migrations_api import get_drop_index_sql
+from askbot.migrations_api import get_create_full_text_index_sql
+from askbot.search import postgresql
+
+INDEX_NAME = 'askbot_thread_search_index'
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+ # Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..."
+ if db.backend_name == 'mysql':
+ table_name = orm['askbot.Thread']._meta.db_table
+ if mysql_table_supports_full_text_search(table_name):
+ columns = ('title', 'tagnames')
+ sql = get_create_full_text_index_sql(INDEX_NAME, table_name, columns)
+ db.execute(sql)
+ elif db.backend_name == 'postgres':
+ script_path = os.path.join(
+ askbot.get_install_directory(),
+ 'search',
+ 'postgresql',
+ 'thread_and_post_models_27112012.plsql'
+ )
+ postgresql.setup_full_text_search(script_path)
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+ if db.backend_name == 'mysql':
+ table_name = orm['askbot.Thread']._meta.db_table
+ if mysql_table_supports_full_text_search(table_name):
+ sql = get_drop_index_sql(INDEX_NAME, table_name)
+ db.execute(sql)
+
+ 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'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ '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'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ '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.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'})
+ },
+ '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.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'}),
+ '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', [], {}),
+ '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.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'}),
+ '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'}),
+ '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'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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']
+ symmetrical = True
diff --git a/askbot/migrations/0159_auto__add_field_thread_language_code.py b/askbot/migrations/0159_auto__add_field_thread_language_code.py
new file mode 100644
index 00000000..b38770e9
--- /dev/null
+++ b/askbot/migrations/0159_auto__add_field_thread_language_code.py
@@ -0,0 +1,380 @@
+# -*- 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 field 'Thread.language_code'
+ db.add_column('askbot_thread', 'language_code',
+ self.gf('django.db.models.fields.CharField')(default='en', max_length=16),
+ keep_default=False)
+
+ def backwards(self, orm):
+ # Deleting field 'Thread.language_code'
+ db.delete_column('askbot_thread', 'language_code')
+
+ 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.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'})
+ },
+ '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.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'}),
+ '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', [], {}),
+ '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.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'}),
+ '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(2013, 1, 3, 22, 36, 46, 237368)'}),
+ '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'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2013, 1, 3, 22, 36, 46, 237185)'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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']
diff --git a/askbot/migrations/0160_add_model_BulkTagSubscription.py b/askbot/migrations/0160_add_model_BulkTagSubscription.py
new file mode 100644
index 00000000..11d78108
--- /dev/null
+++ b/askbot/migrations/0160_add_model_BulkTagSubscription.py
@@ -0,0 +1,424 @@
+# -*- 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 'BulkTagSubscription'
+ db.create_table('askbot_bulktagsubscription', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('date_added', self.gf('django.db.models.fields.DateField')(auto_now_add=True, blank=True)),
+ ))
+ db.send_create_signal('askbot', ['BulkTagSubscription'])
+
+ # Adding M2M table for field tags on 'BulkTagSubscription'
+ db.create_table('askbot_bulktagsubscription_tags', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('bulktagsubscription', models.ForeignKey(orm['askbot.bulktagsubscription'], null=False)),
+ ('tag', models.ForeignKey(orm['askbot.tag'], null=False))
+ ))
+ db.create_unique('askbot_bulktagsubscription_tags', ['bulktagsubscription_id', 'tag_id'])
+
+ # Adding M2M table for field users on 'BulkTagSubscription'
+ db.create_table('askbot_bulktagsubscription_users', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('bulktagsubscription', models.ForeignKey(orm['askbot.bulktagsubscription'], null=False)),
+ ('user', models.ForeignKey(orm['auth.user'], null=False))
+ ))
+ db.create_unique('askbot_bulktagsubscription_users', ['bulktagsubscription_id', 'user_id'])
+
+ # Adding M2M table for field groups on 'BulkTagSubscription'
+ db.create_table('askbot_bulktagsubscription_groups', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('bulktagsubscription', models.ForeignKey(orm['askbot.bulktagsubscription'], null=False)),
+ ('group', models.ForeignKey(orm['askbot.group'], null=False))
+ ))
+ db.create_unique('askbot_bulktagsubscription_groups', ['bulktagsubscription_id', 'group_id'])
+
+
+ def backwards(self, orm):
+ # Deleting model 'BulkTagSubscription'
+ db.delete_table('askbot_bulktagsubscription')
+
+ # Removing M2M table for field tags on 'BulkTagSubscription'
+ db.delete_table('askbot_bulktagsubscription_tags')
+
+ # Removing M2M table for field users on 'BulkTagSubscription'
+ db.delete_table('askbot_bulktagsubscription_users')
+
+ # Removing M2M table for field groups on 'BulkTagSubscription'
+ db.delete_table('askbot_bulktagsubscription_groups')
+
+
+ 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': {'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'})
+ },
+ '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.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'}),
+ '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', [], {}),
+ '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.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'}),
+ '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'}),
+ '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'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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']
diff --git a/askbot/migrations/0161_add_field__user_languages.py b/askbot/migrations/0161_add_field__user_languages.py
new file mode 100644
index 00000000..534a3733
--- /dev/null
+++ b/askbot/migrations/0161_add_field__user_languages.py
@@ -0,0 +1,393 @@
+# -*- 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 field 'Thread.language_code'
+ try:
+ db.add_column('auth_user', 'languages',
+ self.gf('django.db.models.fields.CharField')(default='en', max_length=128),
+ keep_default=False)
+ except:
+ pass
+
+ def backwards(self, orm):
+ # Deleting field 'Thread.junk'
+ db.delete_column('auth_user', 'languages')
+
+ 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'})
+ },
+ '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.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'}),
+ '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', [], {}),
+ '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.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'}),
+ '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'}),
+ 'junk': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '128'}),
+ '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(2013, 1, 14, 9, 30, 19, 481370)'}),
+ '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', [], {'max_length': '128'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2013, 1, 14, 9, 30, 19, 481008)'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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']
diff --git a/askbot/migrations/0162_auto__add_field_post_language_code.py b/askbot/migrations/0162_auto__add_field_post_language_code.py
new file mode 100644
index 00000000..9733b817
--- /dev/null
+++ b/askbot/migrations/0162_auto__add_field_post_language_code.py
@@ -0,0 +1,391 @@
+# encoding: 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 field 'Post.language_code'
+ db.add_column('askbot_post', 'language_code', self.gf('django.db.models.fields.CharField')(default='en', max_length=16), keep_default=False)
+
+
+ def backwards(self, orm):
+
+ # Deleting field 'Post.language_code'
+ db.delete_column('askbot_post', 'language_code')
+
+
+ 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', 'db_index': 'True'})
+ },
+ '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'})
+ },
+ '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.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', [], {}),
+ '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.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'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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']
diff --git a/askbot/migrations/0163_update_postgres_multilingual_search.py b/askbot/migrations/0163_update_postgres_multilingual_search.py
new file mode 100644
index 00000000..3e649a4e
--- /dev/null
+++ b/askbot/migrations/0163_update_postgres_multilingual_search.py
@@ -0,0 +1,402 @@
+# encoding: utf-8
+import sys
+import askbot
+from askbot.search.postgresql import setup_full_text_search
+import datetime
+import os
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+ """this migration is the same as 22
+ just ran again to update the postgres search setup
+ """
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+
+ if 'postgresql_psycopg2' in askbot.get_database_engine_name():
+ script_path = os.path.join(
+ askbot.get_install_directory(),
+ 'search',
+ 'postgresql',
+ 'thread_and_post_models_01022013.plsql'
+ )
+ setup_full_text_search(script_path)
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+
+
+ 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', 'db_index': 'True'})
+ },
+ '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'})
+ },
+ '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.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', [], {}),
+ '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.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'}),
+ '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(2013, 2, 2, 15, 51, 27, 332921)'}),
+ '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(2013, 2, 2, 15, 51, 27, 332763)'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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']
diff --git a/askbot/migrations/0164_update_postgres_user_search.py b/askbot/migrations/0164_update_postgres_user_search.py
new file mode 100644
index 00000000..d65c2aa0
--- /dev/null
+++ b/askbot/migrations/0164_update_postgres_user_search.py
@@ -0,0 +1,399 @@
+# -*- coding: utf-8 -*-
+import askbot
+import datetime
+import os.path
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from askbot.search import postgresql
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+ db_engine_name = askbot.get_database_engine_name()
+ if 'postgresql_psycopg2' in db_engine_name:
+ script_path = os.path.join(
+ askbot.get_install_directory(),
+ 'search',
+ 'postgresql',
+ 'user_profile_search_02262013.plsql'
+ )
+ postgresql.setup_full_text_search(script_path)
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+
+
+ 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'})
+ },
+ '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.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', [], {}),
+ '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.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'}),
+ '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(2013, 2, 26, 14, 41, 36, 405005)'}),
+ '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(2013, 2, 26, 14, 41, 36, 404683)'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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']
+ symmetrical = True
diff --git a/askbot/migrations/0165_update_thread_search.py b/askbot/migrations/0165_update_thread_search.py
new file mode 100644
index 00000000..49164d91
--- /dev/null
+++ b/askbot/migrations/0165_update_thread_search.py
@@ -0,0 +1,399 @@
+# -*- coding: utf-8 -*-
+import askbot
+import datetime
+import os.path
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from askbot.search import postgresql
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+ db_engine_name = askbot.get_database_engine_name()
+ if 'postgresql_psycopg2' in db_engine_name:
+ script_path = os.path.join(
+ askbot.get_install_directory(),
+ 'search',
+ 'postgresql',
+ 'thread_and_post_models_10032013.plsql'
+ )
+ postgresql.setup_full_text_search(script_path)
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+
+
+ 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'})
+ },
+ '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.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', [], {}),
+ '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.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'}),
+ '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(2013, 2, 26, 14, 41, 36, 405005)'}),
+ '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(2013, 2, 26, 14, 41, 36, 404683)'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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']
+ symmetrical = True
diff --git a/askbot/migrations/0166_auto__add_field_thread_deleted.py b/askbot/migrations/0166_auto__add_field_thread_deleted.py
new file mode 100644
index 00000000..ed1a88c4
--- /dev/null
+++ b/askbot/migrations/0166_auto__add_field_thread_deleted.py
@@ -0,0 +1,391 @@
+# -*- 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 field 'Thread.deleted'
+ db.add_column('askbot_thread', 'deleted',
+ self.gf('django.db.models.fields.BooleanField')(default=False, db_index=True),
+ keep_default=False)
+
+ def backwards(self, orm):
+ # Deleting field 'Thread.deleted'
+ db.delete_column('askbot_thread', 'deleted')
+
+ 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'})
+ },
+ '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.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', [], {}),
+ '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.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(2013, 3, 10, 19, 4, 54, 674932)'}),
+ '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(2013, 3, 10, 19, 4, 54, 674702)'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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/0167_populate_thread_deleted_field.py b/askbot/migrations/0167_populate_thread_deleted_field.py
new file mode 100644
index 00000000..8fd3dd6d
--- /dev/null
+++ b/askbot/migrations/0167_populate_thread_deleted_field.py
@@ -0,0 +1,397 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from askbot.utils.console import ProgressBar
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+ questions = orm['askbot.Post'].objects.filter(post_type='question')
+ count = questions.count()
+ message = 'Transferring deleted info to thread objects'
+ for question in ProgressBar(questions.iterator(), count, message):
+ thread = question.thread
+ thread.deleted = question.deleted
+ thread.save()
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+ pass
+
+
+ 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'})
+ },
+ '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.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', [], {}),
+ '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.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(2013, 3, 10, 19, 6, 41, 612993)'}),
+ '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(2013, 3, 10, 19, 6, 41, 611993)'}),
+ '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'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ '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']
+ symmetrical = True
diff --git a/askbot/migrations/__init__.py b/askbot/migrations/__init__.py
index 86377b7b..b9683daf 100644
--- a/askbot/migrations/__init__.py
+++ b/askbot/migrations/__init__.py
@@ -1,5 +1,9 @@
from south.db import db
from south.utils import ask_for_it_by_name
+from south.v2 import SchemaMigration
+
+if not db.has_ddl_transactions:
+ SchemaMigration.no_dry_run = True
# Terminal ANSI codes for printing colored text:
# - http://code.google.com/p/testoob/source/browse/trunk/src/testoob/reporting/colored.py#20
@@ -67,3 +71,4 @@ def innodb_ready_rename_column(orm, models, table, old_column_name, new_column_n
# INFO: ask_for_it_by_name() if equivalent to self.gf() which is usually used in migrations, e.g.:
# db.alter_column('askbot_badgedata', 'slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50))
db.alter_column(table, new_column_name, field)
+ db.clear_deferred_sql()
diff --git a/askbot/migrations_api/__init__.py b/askbot/migrations_api/__init__.py
index 586c02d9..3ea250f2 100644
--- a/askbot/migrations_api/__init__.py
+++ b/askbot/migrations_api/__init__.py
@@ -5,6 +5,7 @@ since models change with time, this api is implemented in different
versions. Different versions do not need to have all the same functions.
"""
from south.db import db
+from django.db import connection
def safe_add_column(table, column, column_data, keep_default = False):
"""when user calls syncdb with askbot the first time
@@ -12,14 +13,38 @@ 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
"""
- try:
- db.start_transaction()
- db.add_column(table, column, column_data, keep_default = keep_default)
- db.commit_transaction()
- return True
- except:
- db.rollback_transaction()
- return False
+ if db.backend_name=='mysql':
+ 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:
+ try:
+ db.start_transaction()
+ db.add_column(table, column, column_data, keep_default = keep_default)
+ db.commit_transaction()
+ return True
+ except:
+ db.rollback_transaction()
+ return False
+
+
+def mysql_table_supports_full_text_search(table_name):
+ """true, if engine is MyISAM"""
+ cursor = connection.cursor()
+ cursor.execute("SHOW CREATE TABLE %s" % table_name)
+ data = cursor.fetchone()
+ return 'ENGINE=MyISAM' in data[1]
+
+
+def get_drop_index_sql(index_name, table_name):
+ """returns sql for dropping index by name on table"""
+ return 'ALTER TABLE %s DROP INDEX %s' % (table_name, index_name)
+
+
+def get_create_full_text_index_sql(index_name, table_name, column_list):
+ column_sql = '(%s)' % ','.join(column_list)
+ query_template = 'CREATE FULLTEXT INDEX %s on %s %s'
+ return query_template % (index_name, table_name, column_sql)
class BaseAPI(object):
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index 4648748e..49ce7fae 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -13,6 +13,7 @@ import collections
import datetime
import hashlib
import logging
+import re
import urllib
import uuid
from celery import states
@@ -20,6 +21,7 @@ from celery.task import task
from django.core.urlresolvers import reverse, NoReverseMatch
from django.db.models import signals as django_signals
from django.template import Context
+from django.template.loader import get_template
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
from django.utils.safestring import mark_safe
@@ -45,6 +47,7 @@ from askbot.models.tag import format_personal_group_name
from askbot.models.user import EmailFeedSetting, ActivityAuditStatus, Activity
from askbot.models.user import GroupMembership
from askbot.models.user import Group
+from askbot.models.user import BulkTagSubscription
from askbot.models.post import Post, PostRevision
from askbot.models.post import PostFlagReason, AnonymousAnswer
from askbot.models.post import PostToGroup
@@ -56,6 +59,7 @@ from askbot.models.repute import Award, Repute, Vote
from askbot.models.widgets import AskWidget, QuestionWidget
from askbot import auth
from askbot.utils.decorators import auto_now_timestamp
+from askbot.utils.markup import URL_RE
from askbot.utils.slug import slugify
from askbot.utils.html import replace_links_with_text
from askbot.utils.html import sanitize_html
@@ -63,6 +67,14 @@ from askbot.utils.diff import textDiff as htmldiff
from askbot.utils.url_utils import strip_path
from askbot import mail
+from django import VERSION
+
+#stores the 1.X version not the security release numbers
+DJANGO_VERSION = VERSION[:2]
+
+if DJANGO_VERSION > (1, 3):
+ from askbot.models.message import Message
+
def get_model(model_name):
"""a shortcut for getting model for an askbot app"""
return models.get_model('askbot', model_name)
@@ -101,7 +113,7 @@ def get_users_by_text_query(search_query, users_query_set = None):
users_query_set = User.objects.all()
if 'postgresql_psycopg2' in askbot.get_database_engine_name():
from askbot.search import postgresql
- return postgresql.run_full_text_search(users_query_set, search_query)
+ return postgresql.run_user_search(users_query_set, search_query)
else:
return users_query_set.filter(
models.Q(username__icontains=search_query) |
@@ -114,6 +126,45 @@ def get_users_by_text_query(search_query, users_query_set = None):
# models.Q(about__search = search_query)
# )
+class RelatedObjectSimulator(object):
+ '''Objects that simulates the "messages_set" related field
+ somehow django does not creates it automatically in django1.4.1'''
+
+ def __init__(self, user, model_class):
+ self.user = user
+ self.model_class = model_class
+
+ def all(self):
+ return self.model_class.objects.all()
+
+ def count(self, **kwargs):
+ kwargs['user'] = self.user
+ return self.model_class.objects.filter(**kwargs).count()
+
+ def create(self, **kwargs):
+ return self.model_class.objects.create(user=self.user, **kwargs)
+
+ def filter(self, *args, **kwargs):
+ return self.model_class.objects.filter(*args, **kwargs)
+
+
+#django 1.4.1 and above
+@property
+def user_message_set(self):
+ return RelatedObjectSimulator(self, Message)
+
+#django 1.4.1 and above
+def user_get_and_delete_messages(self):
+ messages = []
+ for message in Message.objects.filter(user=self):
+ messages.append(message.message)
+ message.delete()
+ return messages
+
+if DJANGO_VERSION > (1, 3):
+ User.add_to_class('message_set', user_message_set)
+ User.add_to_class('get_and_delete_messages', user_get_and_delete_messages)
+
User.add_to_class(
'status',
models.CharField(
@@ -169,14 +220,14 @@ User.add_to_class('show_marked_tags', models.BooleanField(default = True))
User.add_to_class(
'email_tag_filter_strategy',
models.SmallIntegerField(
- choices=const.TAG_DISPLAY_FILTER_STRATEGY_CHOICES,
+ choices=const.TAG_EMAIL_FILTER_FULL_STRATEGY_CHOICES,
default=const.EXCLUDE_IGNORED
)
)
User.add_to_class(
'display_tag_filter_strategy',
models.SmallIntegerField(
- choices=const.TAG_EMAIL_FILTER_STRATEGY_CHOICES,
+ choices=const.TAG_DISPLAY_FILTER_STRATEGY_CHOICES,
default=const.INCLUDE_ALL
)
)
@@ -184,8 +235,13 @@ User.add_to_class(
User.add_to_class('new_response_count', models.IntegerField(default=0))
User.add_to_class('seen_response_count', models.IntegerField(default=0))
User.add_to_class('consecutive_days_visit_count', models.IntegerField(default = 0))
+#list of languages for which user should receive email alerts
+User.add_to_class(
+ 'languages',
+ models.CharField(max_length=128, default=django_settings.LANGUAGE_CODE)
+)
-GRAVATAR_TEMPLATE = "http://www.gravatar.com/avatar/%(gravatar)s?" + \
+GRAVATAR_TEMPLATE = "//www.gravatar.com/avatar/%(gravatar)s?" + \
"s=%(size)d&amp;d=%(type)s&amp;r=PG"
def user_get_gravatar_url(self, size):
@@ -458,6 +514,8 @@ def _assert_user_can(
if assertion fails, method raises exception.PermissionDenied
with appropriate text as a payload
"""
+ 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
elif post and owner_can and user == post.get_owner():
@@ -556,10 +614,11 @@ def user_assert_can_unaccept_best_answer(self, answer = None):
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': answer.get_owner().username}
+ ) % {'username': question_owner.username}
raise django_exceptions.PermissionDenied(error_message)
@@ -634,6 +693,19 @@ def user_assert_can_upload_file(request_user):
)
+def user_assert_can_post_text(self, text):
+ """Raises exceptions.PermissionDenied, if user does not have
+ privilege to post given text, depending on the contents
+ """
+ if re.search(URL_RE, text):
+ min_rep = askbot_settings.MIN_REP_TO_SUGGEST_LINK
+ if self.is_authenticated() and self.reputation < min_rep:
+ message = _(
+ 'Could not post, because your karma is insufficient to publish links'
+ )
+ raise django_exceptions.PermissionDenied(message)
+
+
def user_assert_can_post_question(self):
"""raises exceptions.PermissionDenied with
text that has the reason for the denial
@@ -1298,6 +1370,17 @@ def user_mark_tags(
if tagnames is None:
tagnames = list()
+ #figure out which tags don't yet exist
+ existing_tagnames = Tag.objects.filter(
+ name__in=tagnames
+ ).values_list(
+ 'name', flat=True
+ )
+ non_existing_tagnames = set(tagnames) - set(existing_tagnames)
+ #create those tags, and if tags are moderated make them suggested
+ if (len(non_existing_tagnames) > 0):
+ Tag.objects.create_in_bulk(tag_names=tagnames, user=self)
+
#below we update normal tag selections
marked_ts = MarkedTag.objects.filter(
user = self,
@@ -1463,6 +1546,9 @@ def user_delete_question(
question.deleted_at = timestamp
question.save()
+ question.thread.deleted = True
+ question.thread.save()
+
for tag in list(question.thread.tags.all()):
if tag.used_count == 1:
tag.deleted = True
@@ -1563,7 +1649,8 @@ def user_post_question(
group_id = None,
timestamp = None,
by_email = False,
- email_address = None
+ email_address = None,
+ language = None
):
"""makes an assertion whether user can post the question
then posts it and returns the question object"""
@@ -1580,20 +1667,21 @@ def user_post_question(
if timestamp is None:
timestamp = datetime.datetime.now()
- #todo: split this into "create thread" + "add queston", if text exists
+ #todo: split this into "create thread" + "add question", if text exists
#or maybe just add a blank question post anyway
thread = Thread.objects.create_new(
- author = self,
- title = title,
- text = body_text,
- tagnames = tags,
- added_at = timestamp,
- wiki = wiki,
- is_anonymous = is_anonymous,
- is_private = is_private,
- group_id = group_id,
- by_email = by_email,
- email_address = email_address
+ author=self,
+ title=title,
+ text=body_text,
+ tagnames=tags,
+ added_at=timestamp,
+ wiki=wiki,
+ is_anonymous=is_anonymous,
+ is_private=is_private,
+ group_id=group_id,
+ by_email=by_email,
+ email_address=email_address,
+ language=language
)
question = thread._question_post()
if question.author != self:
@@ -1606,9 +1694,10 @@ def user_post_question(
def user_edit_comment(
self,
comment_post=None,
- body_text = None,
- timestamp = None,
- by_email = False
+ body_text=None,
+ timestamp=None,
+ by_email=False,
+ suppress_email=False
):
"""apply edit to a comment, the method does not
change the comments timestamp and no signals are sent
@@ -1617,20 +1706,22 @@ def user_edit_comment(
"""
self.assert_can_edit_comment(comment_post)
comment_post.apply_edit(
- text = body_text,
- edited_at = timestamp,
- edited_by = self,
- by_email = by_email
+ text=body_text,
+ edited_at=timestamp,
+ edited_by=self,
+ by_email=by_email,
+ suppress_email=suppress_email
)
comment_post.thread.invalidate_cached_data()
def user_edit_post(self,
- post = None,
- body_text = None,
- revision_comment = None,
- timestamp = None,
- by_email = False,
- is_private = False
+ post=None,
+ body_text=None,
+ revision_comment=None,
+ timestamp=None,
+ by_email=False,
+ is_private=False,
+ suppress_email=False,
):
"""a simple method that edits post body
todo: unify it in the style of just a generic post
@@ -1639,36 +1730,39 @@ def user_edit_post(self,
"""
if post.post_type == 'comment':
self.edit_comment(
- comment_post = post,
- body_text = body_text,
- by_email = by_email
+ comment_post=post,
+ body_text=body_text,
+ by_email=by_email,
+ suppress_email=suppress_email
)
elif post.post_type == 'answer':
self.edit_answer(
- answer = post,
- body_text = body_text,
- timestamp = timestamp,
- revision_comment = revision_comment,
- by_email = by_email
+ answer=post,
+ body_text=body_text,
+ timestamp=timestamp,
+ revision_comment=revision_comment,
+ by_email=by_email,
+ suppress_email=suppress_email
)
elif post.post_type == 'question':
self.edit_question(
- question = post,
- body_text = body_text,
- timestamp = timestamp,
- revision_comment = revision_comment,
- by_email = by_email,
- is_private = is_private
+ question=post,
+ body_text=body_text,
+ timestamp=timestamp,
+ revision_comment=revision_comment,
+ by_email=by_email,
+ is_private=is_private,
+ suppress_email=suppress_email,
)
elif post.post_type == 'tag_wiki':
post.apply_edit(
- edited_at = timestamp,
- edited_by = self,
- text = body_text,
+ edited_at=timestamp,
+ edited_by=self,
+ text=body_text,
#todo: summary name clash in question and question revision
- comment = revision_comment,
- wiki = True,
- by_email = False
+ comment=revision_comment,
+ wiki=True,
+ by_email=False
)
else:
raise NotImplementedError()
@@ -1676,17 +1770,18 @@ def user_edit_post(self,
@auto_now_timestamp
def user_edit_question(
self,
- question = None,
- title = None,
- body_text = None,
- revision_comment = None,
- tags = None,
- wiki = False,
- edit_anonymously = False,
- is_private = False,
- timestamp = None,
- force = False,#if True - bypass the assert
- by_email = False
+ question=None,
+ title=None,
+ body_text=None,
+ revision_comment=None,
+ tags=None,
+ wiki=False,
+ edit_anonymously=False,
+ is_private=False,
+ timestamp=None,
+ force=False,#if True - bypass the assert
+ by_email=False,
+ suppress_email=False
):
if force == False:
self.assert_can_edit_question(question)
@@ -1702,7 +1797,8 @@ def user_edit_question(
wiki = wiki,
edit_anonymously = edit_anonymously,
is_private = is_private,
- by_email = by_email
+ by_email = by_email,
+ suppress_email=suppress_email
)
question.thread.invalidate_cached_data()
@@ -1717,14 +1813,15 @@ def user_edit_question(
@auto_now_timestamp
def user_edit_answer(
self,
- answer = None,
- body_text = None,
- revision_comment = None,
- wiki = False,
- is_private = False,
- timestamp = None,
- force = False,#if True - bypass the assert
- by_email = False
+ answer=None,
+ body_text=None,
+ revision_comment=None,
+ wiki=False,
+ is_private=False,
+ timestamp=None,
+ force=False,#if True - bypass the assert
+ by_email=False,
+ suppress_email=False,
):
if force == False:
self.assert_can_edit_answer(answer)
@@ -1736,7 +1833,8 @@ def user_edit_answer(
comment=revision_comment,
wiki=wiki,
is_private=is_private,
- by_email=by_email
+ by_email=by_email,
+ suppress_email=suppress_email
)
answer.thread.invalidate_cached_data()
@@ -1770,7 +1868,7 @@ def user_create_post_reject_reason(
author = self,
revised_at = timestamp,
text = details,
- comment = const.POST_STATUS['default_version']
+ comment = unicode(const.POST_STATUS['default_version'])
)
reason.details = details
@@ -2232,7 +2330,7 @@ def delete_messages(self):
self.message_set.all().delete()
#todo: find where this is used and replace with get_absolute_url
-def get_profile_url(self):
+def user_get_profile_url(self):
"""Returns the URL for this User's profile."""
return reverse(
'user_profile',
@@ -2804,7 +2902,7 @@ User.add_to_class(
user_get_flag_count_posted_today
)
User.add_to_class('get_flags_for_post', user_get_flags_for_post)
-User.add_to_class('get_profile_url', get_profile_url)
+User.add_to_class('get_profile_url', user_get_profile_url)
User.add_to_class('get_profile_link', get_profile_link)
User.add_to_class('get_tag_filtered_questions', user_get_tag_filtered_questions)
User.add_to_class('get_messages', get_messages)
@@ -2867,6 +2965,7 @@ User.add_to_class('assert_can_upload_file', user_assert_can_upload_file)
User.add_to_class('assert_can_post_question', user_assert_can_post_question)
User.add_to_class('assert_can_post_answer', user_assert_can_post_answer)
User.add_to_class('assert_can_post_comment', user_assert_can_post_comment)
+User.add_to_class('assert_can_post_text', user_assert_can_post_text)
User.add_to_class('assert_can_edit_post', user_assert_can_edit_post)
User.add_to_class('assert_can_edit_deleted_post', user_assert_can_edit_deleted_post)
User.add_to_class('assert_can_see_deleted_post', user_assert_can_see_deleted_post)
@@ -2987,8 +3086,9 @@ def format_instant_notification_email(
else:
raise ValueError('unrecognized post type')
- post_url = strip_path(site_url) + post.get_absolute_url()
- user_url = strip_path(site_url) + from_user.get_absolute_url()
+ base_url = strip_path(site_url)
+ post_url = base_url + post.get_absolute_url()
+ user_url = base_url + from_user.get_absolute_url()
user_action = user_action % {
'user': '<a href="%s">%s</a>' % (user_url, from_user.username),
'post_link': '<a href="%s">%s</a>' % (post_url, _(post.post_type))
@@ -3104,11 +3204,12 @@ def calculate_gravatar_hash(instance, **kwargs):
def record_post_update_activity(
post,
- newly_mentioned_users = None,
- updated_by = None,
- timestamp = None,
- created = False,
- diff = None,
+ newly_mentioned_users=None,
+ updated_by=None,
+ suppress_email=False,
+ timestamp=None,
+ created=False,
+ diff=None,
**kwargs
):
"""called upon signal askbot.models.signals.post_updated
@@ -3130,13 +3231,14 @@ def record_post_update_activity(
from askbot import tasks
tasks.record_post_update_celery_task.delay(
- post_id = post.id,
- post_content_type_id = ContentType.objects.get_for_model(post).id,
- newly_mentioned_user_id_list = [u.id for u in newly_mentioned_users],
- updated_by_id = updated_by.id,
- timestamp = timestamp,
- created = created,
- diff = diff,
+ post_id=post.id,
+ post_content_type_id=ContentType.objects.get_for_model(post).id,
+ newly_mentioned_user_id_list=[u.id for u in newly_mentioned_users],
+ updated_by_id=updated_by.id,
+ suppress_email=suppress_email,
+ timestamp=timestamp,
+ created=created,
+ diff=diff,
)
@@ -3385,9 +3487,8 @@ def send_respondable_email_validation_message(
)
data['email_code'] = reply_address.address
- from askbot.skins.loaders import get_template
template = get_template(template_name)
- body_text = template.render(Context(data))
+ body_text = template.render(Context(data))#todo: set lang
reply_to_address = 'welcome-%s@%s' % (
reply_address.address,
@@ -3483,6 +3584,20 @@ def add_missing_subscriptions(sender, instance, created, **kwargs):
if created:
instance.add_missing_askbot_subscriptions()
+def add_missing_tag_subscriptions(sender, instance, created, **kwargs):
+ '''``sender` is instance of `User``. When the user is created
+ it add the tag subscriptions to the user via BulkTagSubscription
+ and MarkedTags.
+ '''
+ if created:
+ if askbot_settings.SUBSCRIBED_TAG_SELECTOR_ENABLED and \
+ askbot_settings.GROUPS_ENABLED:
+ user_groups = instance.get_groups()
+ for subscription in BulkTagSubscription.objects.filter(groups__in = user_groups):
+ tag_list = subscription.tag_list()
+ instance.mark_tags(tagnames = tag_list,
+ reason='subscribed', action='add')
+
def post_anonymous_askbot_content(
sender,
request,
@@ -3529,13 +3644,13 @@ def moderate_group_joining(sender, instance=None, created=False, **kwargs):
content_object = group
)
-
#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)
django_signals.post_save.connect(add_user_to_personal_group, sender=User)
+django_signals.post_save.connect(add_missing_tag_subscriptions, sender=User)
django_signals.post_save.connect(record_award_event, sender=Award)
django_signals.post_save.connect(notify_award_message, sender=Award)
django_signals.post_save.connect(record_answer_accepted, sender=Post)
diff --git a/askbot/models/base.py b/askbot/models/base.py
index 74b8c2dd..5822d3a6 100644
--- a/askbot/models/base.py
+++ b/askbot/models/base.py
@@ -49,7 +49,6 @@ class DraftContent(models.Model):
ip_addr = models.IPAddressField(max_length=21) #allow high port numbers
author = models.ForeignKey(User,null=True)
text = models.TextField()
- summary = models.CharField(max_length=180)
class Meta:
abstract = True
diff --git a/askbot/models/message.py b/askbot/models/message.py
new file mode 100644
index 00000000..a2da9c51
--- /dev/null
+++ b/askbot/models/message.py
@@ -0,0 +1,28 @@
+'''Copied from Django 1.3.1 source code, it will use this model to'''
+from django.db import models
+from django.contrib.auth.models import User
+from django.utils.translation import ugettext_lazy
+
+class Message(models.Model):
+ """
+ The message system is a lightweight way to queue messages for given
+ users. A message is associated with a User instance (so it is only
+ applicable for registered users). There's no concept of expiration or
+ timestamps. Messages are created by the Django admin after successful
+ actions. For example, "The poll Foo was created successfully." is a
+ message.
+ """
+ user = models.ForeignKey(User, related_name='_message_set')
+ message = models.TextField(ugettext_lazy('message'))
+
+ class Meta:
+ '''Added for backwards compatibility with databases
+ migrated from django 1.3'''
+ app_label = 'auth'
+ db_table = 'auth_message'
+
+ def __unicode__(self):
+ return self.message
+
+ def __str__(self):
+ return self.message.encode('utf-8')
diff --git a/askbot/models/post.py b/askbot/models/post.py
index da25f2fc..65ea535d 100644
--- a/askbot/models/post.py
+++ b/askbot/models/post.py
@@ -7,13 +7,14 @@ import logging
from django.utils.html import strip_tags
from django.contrib.sitemaps import ping_google
from django.utils import html
-from django.conf import settings
+from django.conf import settings as django_settings
from django.contrib.auth.models import User
from django.core import urlresolvers
from django.db import models
from django.utils import html as html_utils
+from django.utils.translation import activate as activate_language
+from django.utils.translation import get_language
from django.utils.translation import ugettext as _
-from django.utils.translation import ungettext
from django.utils.http import urlquote as django_urlquote
from django.core import exceptions as django_exceptions
from django.core import cache
@@ -79,11 +80,11 @@ class PostQuerySet(models.query.QuerySet):
| models.Q(thread__posts__text__icontains = search_query, thread__posts__post_type='answer')
)
# #todo - goes to thread - we search whole threads
-# if getattr(settings, 'USE_SPHINX_SEARCH', False):
+# if getattr(django_settings, 'USE_SPHINX_SEARCH', False):
# matching_questions = Question.sphinx_search.query(search_query)
# question_ids = [q.id for q in matching_questions]
# return Question.objects.filter(deleted = False, id__in = question_ids)
-# if settings.DATABASE_ENGINE == 'mysql' and mysql.supports_full_text_search():
+# if django_settings.DATABASE_ENGINE == 'mysql' and mysql.supports_full_text_search():
# return self.filter(
# models.Q(thread__title__search = search_query)\
# | models.Q(text__search = search_query)\
@@ -205,14 +206,20 @@ class PostManager(BaseQuerySetManager):
assert(post_type in const.POST_TYPES)
+ if thread:
+ language_code = thread.language_code
+ else:
+ language_code = get_language()
+
post = Post(
- post_type = post_type,
- thread = thread,
- parent = parent,
- author = author,
- added_at = added_at,
- wiki = wiki,
- text = text,
+ post_type=post_type,
+ thread=thread,
+ parent=parent,
+ author=author,
+ added_at=added_at,
+ wiki=wiki,
+ text=text,
+ language_code=language_code
#.html field is denormalized by the save() call
)
@@ -243,7 +250,7 @@ class PostManager(BaseQuerySetManager):
author = author,
revised_at = added_at,
text = text,
- comment = const.POST_STATUS['default_version'],
+ comment = unicode(const.POST_STATUS['default_version']),
by_email = by_email
)
@@ -370,6 +377,7 @@ class Post(models.Model):
html = models.TextField(null=True)#html rendition of the latest revision
text = models.TextField(null=True)#denormalized copy of latest revision
+ language_code = models.CharField(max_length=16, default=django_settings.LANGUAGE_CODE)
# Denormalised data
summary = models.TextField(null=True)
@@ -416,11 +424,11 @@ class Post(models.Model):
if self.post_type in ('question', 'answer', 'tag_wiki', 'reject_reason'):
_urlize = False
- _use_markdown = True
+ _use_markdown = (askbot_settings.EDITOR_TYPE == 'markdown')
_escape_html = False #markdow does the escaping
elif self.is_comment():
_urlize = True
- _use_markdown = True
+ _use_markdown = (askbot_settings.EDITOR_TYPE == 'markdown')
_escape_html = True
else:
raise NotImplementedError
@@ -573,6 +581,11 @@ class Post(models.Model):
def is_reject_reason(self):
return self.post_type == 'reject_reason'
+ def get_last_edited_date(self):
+ """returns date of last edit or date of creation
+ if there were no edits"""
+ return self.last_edited_at or self.added_at
+
def get_moderators(self):
"""returns query set of users who are site administrators
and moderators"""
@@ -581,6 +594,28 @@ class Post(models.Model):
user_filter = user_filter & models.Q(groups__in=self.groups.all())
return User.objects.filter(user_filter)
+ def get_previous_answer(self, user=None):
+ """returns a previous answer to a given answer;
+ only works on the "answer" post types"""
+ assert(self.post_type == 'answer')
+ all_answers = self.thread.get_answers(user=user)
+
+ matching_answers = all_answers.filter(
+ added_at__lt=self.added_at,
+ ).order_by('-added_at')
+
+ if len(matching_answers) == 0:
+ return None
+
+ answer = matching_answers[0]
+
+ if answer.id == self.id:
+ return None
+ if answer.added_at > self.added_at:
+ return None
+
+ return answer
+
def has_group(self, group):
"""true if post belongs to the group"""
return self.groups.filter(id=group.id).exists()
@@ -616,6 +651,7 @@ class Post(models.Model):
updated_by=None,
notify_sets=None,
activity_type=None,
+ suppress_email=False,
timestamp=None,
diff=None
):
@@ -659,7 +695,7 @@ class Post(models.Model):
user.update_response_counts()
#shortcircuit if the email alerts are disabled
- if askbot_settings.ENABLE_EMAIL_ALERTS == False:
+ if suppress_email == True or askbot_settings.ENABLE_EMAIL_ALERTS == False:
return
#todo: fix this temporary spam protection plug
if askbot_settings.MIN_REP_TO_TRIGGER_EMAIL:
@@ -668,18 +704,18 @@ class Post(models.Model):
notify_sets['for_email'] = \
[u for u in notify_sets['for_email'] if u.is_administrator()]
- if not settings.CELERY_ALWAYS_EAGER:
+ if not django_settings.CELERY_ALWAYS_EAGER:
cache_key = 'instant-notification-%d-%d' % (self.thread.id, updated_by.id)
if cache.cache.get(cache_key):
return
- cache.cache.set(cache_key, True, settings.NOTIFICATION_DELAY_TIME)
+ cache.cache.set(cache_key, True, django_settings.NOTIFICATION_DELAY_TIME)
from askbot.tasks import send_instant_notifications_about_activity_in_post
send_instant_notifications_about_activity_in_post.apply_async((
update_activity,
self,
notify_sets['for_email']),
- countdown = settings.NOTIFICATION_DELAY_TIME
+ countdown = django_settings.NOTIFICATION_DELAY_TIME
)
def make_private(self, user, group_id=None):
@@ -742,10 +778,16 @@ class Post(models.Model):
#the trailing slash is entered in three places here + in urls.py
if not hasattr(self, '_thread_cache') and thread:
self._thread_cache = thread
+
+ is_multilingual = getattr(django_settings, 'ASKBOT_MULTILINGUAL', False)
+ if is_multilingual:
+ request_language = get_language()
+ activate_language(self.thread.language_code)
+
if self.is_answer():
if not question_post:
question_post = self.thread._question_post()
- return u'%(base)s%(slug)s/?answer=%(id)d#post-id-%(id)d' % {
+ url = u'%(base)s%(slug)s/?answer=%(id)d#post-id-%(id)d' % {
'base': urlresolvers.reverse('question', args=[question_post.id]),
'slug': django_urlquote(slugify(self.thread.title)),
'id': self.id
@@ -756,13 +798,17 @@ class Post(models.Model):
url += django_urlquote(slugify(thread.title)) + '/'
elif no_slug is False:
url += django_urlquote(self.slug) + '/'
- return url
elif self.is_comment():
origin_post = self.get_origin_post()
- return '%(url)s?comment=%(id)d#comment-%(id)d' % \
+ url = '%(url)s?comment=%(id)d#comment-%(id)d' % \
{'url': origin_post.get_absolute_url(thread=thread), 'id':self.id}
+ else:
+ raise NotImplementedError
- raise NotImplementedError
+ if is_multilingual:
+ activate_language(request_language)
+
+ return url
def delete(self, **kwargs):
"""deletes comment and concomitant response activity
@@ -862,8 +908,8 @@ class Post(models.Model):
if quote_level > 0, the post will be indented that number of times
todo: move to views?
"""
- from askbot.skins.loaders import get_template
from django.template import Context
+ from django.template.loader import get_template
template = get_template('email/quoted_post.html')
data = {
'post': self,
@@ -871,7 +917,7 @@ class Post(models.Model):
'is_leaf_post': is_leaf_post,
'format': format
}
- return template.render(Context(data))
+ return template.render(Context(data))#todo: set lang
def format_for_email_as_parent_thread_summary(self):
"""format for email as summary of parent posts
@@ -895,10 +941,10 @@ class Post(models.Model):
"""outputs question or answer and all it's comments
returns empty string for all other post types
"""
- from askbot.skins.loaders import get_template
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}))
+ return template.render(Context({'post': self}))#todo: set lang
def set_cached_comments(self, comments):
"""caches comments in the lifetime of the object
@@ -972,6 +1018,9 @@ class Post(models.Model):
elif tag_mark_reason == 'bad':
email_tag_filter_strategy = const.EXCLUDE_IGNORED
user_set_getter = User.objects.exclude
+ elif tag_mark_reason == 'subscribed':
+ email_tag_filter_strategy = const.INCLUDE_SUBSCRIBED
+ user_set_getter = User.objects.filter
else:
raise ValueError('Uknown value of tag mark reason %s' % tag_mark_reason)
@@ -1005,6 +1054,10 @@ class Post(models.Model):
empty_wildcard_filter = {'ignored_tags__exact': ''}
wildcard_tags_attribute = 'ignored_tags'
update_subscribers = lambda the_set, item: the_set.discard(item)
+ elif tag_mark_reason == 'subscribed':
+ empty_wildcard_filter = {'subscribed_tags__exact': ''}
+ wildcard_tags_attribute = 'subscribed_tags'
+ update_subscribers = lambda the_set, item: the_set.add(item)
potential_wildcard_subscribers = User.objects.filter(
notification_subscriptions__in = subscription_records
@@ -1043,15 +1096,23 @@ class Post(models.Model):
#segment of users who have tag filter turned off
global_subscribers = User.objects.filter(
- email_tag_filter_strategy = const.INCLUDE_ALL
+ models.Q(email_tag_filter_strategy=const.INCLUDE_ALL)
+ & models.Q(
+ notification_subscriptions__feed_type='q_all',
+ notification_subscriptions__frequency='i'
+ )
)
subscriber_set.update(global_subscribers)
#segment of users who want emails on selected questions only
+ if askbot_settings.SUBSCRIBED_TAG_SELECTOR_ENABLED:
+ good_mark_reason = 'subscribed'
+ else:
+ good_mark_reason = 'good'
subscriber_set.update(
self.get_global_tag_based_subscribers(
subscription_records = global_subscriptions,
- tag_mark_reason = 'good'
+ tag_mark_reason = good_mark_reason
)
)
@@ -1253,10 +1314,22 @@ class Post(models.Model):
#if askbot_settings.GROUPS_ENABLED and self.is_effectively_private():
# for subscriber in subscribers:
- return self.filter_authorized_users(subscribers)
+ subscribers = self.filter_authorized_users(subscribers)
+
+ #filter subscribers by language
+ if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False):
+ language = self.thread.language_code
+ filtered_subscribers = list()
+ for subscriber in subscribers:
+ subscriber_languages = subscriber.languages.split()
+ if language in subscriber_languages:
+ filtered_subscribers.append(subscriber)
+ return filtered_subscribers
+ else:
+ return subscribers
def get_notify_sets(self, mentioned_users=None, exclude_list=None):
- """returns three lists in a dictionary with keys:
+ """returns three lists of users in a dictionary with keys:
* 'for_inbox' - users for which to add inbox items
* 'for_mentions' - for whom mentions are added
* 'for_email' - to whom email notifications should be sent
@@ -1609,7 +1682,8 @@ class Post(models.Model):
wiki=False,
edit_anonymously=False,
is_private=False,
- by_email=False
+ by_email=False,
+ suppress_email=False
):
if text is None:
text = self.get_latest_revision().text
@@ -1644,6 +1718,7 @@ class Post(models.Model):
post=self,
updated_by=edited_by,
newly_mentioned_users=parse_results['newly_mentioned_users'],
+ suppress_email=suppress_email,
timestamp=edited_at,
created=False,
diff=parse_results['diff'],
@@ -1653,13 +1728,14 @@ class Post(models.Model):
def _answer__apply_edit(
self,
- edited_at = None,
- edited_by = None,
- text = None,
- comment = None,
- wiki = False,
- is_private = False,
- by_email = False
+ edited_at=None,
+ edited_by=None,
+ text=None,
+ comment=None,
+ wiki=False,
+ is_private=False,
+ by_email=False,
+ suppress_email=False,
):
##it is important to do this before __apply_edit b/c of signals!!!
@@ -1676,7 +1752,8 @@ class Post(models.Model):
comment=comment,
wiki=wiki,
by_email=by_email,
- is_private=is_private
+ is_private=is_private,
+ suppress_email=suppress_email
)
if edited_at is None:
@@ -1685,8 +1762,8 @@ class Post(models.Model):
def _question__apply_edit(self, edited_at=None, edited_by=None, title=None,\
text=None, comment=None, tags=None, wiki=False,\
- edit_anonymously = False, is_private = False,
- by_email = False
+ edit_anonymously=False, is_private=False,\
+ by_email=False, suppress_email=False
):
#todo: the thread editing should happen outside of this
@@ -1727,7 +1804,8 @@ class Post(models.Model):
wiki=wiki,
edit_anonymously=edit_anonymously,
is_private=is_private,
- by_email=by_email
+ by_email=by_email,
+ suppress_email=suppress_email
)
self.thread.set_last_activity(last_activity_at=edited_at, last_activity_by=edited_by)
@@ -1759,7 +1837,7 @@ class Post(models.Model):
rev_no = self.revisions.all().count() + 1
if comment in (None, ''):
if rev_no == 1:
- comment = const.POST_STATUS['default_version']
+ comment = unicode(const.POST_STATUS['default_version'])
else:
comment = 'No.%s Revision' % rev_no
return PostRevision.objects.create(
@@ -1787,22 +1865,22 @@ class Post(models.Model):
rev_no = self.revisions.all().count() + 1
if comment in (None, ''):
if rev_no == 1:
- comment = const.POST_STATUS['default_version']
+ comment = unicode(const.POST_STATUS['default_version'])
else:
comment = 'No.%s Revision' % rev_no
return PostRevision.objects.create(
- post = self,
- revision = rev_no,
- title = self.thread.title,
- author = author,
- is_anonymous = is_anonymous,
- revised_at = revised_at,
- tagnames = self.thread.tagnames,
- summary = comment,
- text = text,
- by_email = by_email,
- email_address = email_address
+ post=self,
+ revision=rev_no,
+ title=self.thread.title,
+ author=author,
+ is_anonymous=is_anonymous,
+ revised_at=revised_at,
+ tagnames=self.thread.tagnames,
+ summary=unicode(comment),
+ text=text,
+ by_email=by_email,
+ email_address=email_address
)
def add_revision(self, *kargs, **kwargs):
@@ -1901,7 +1979,7 @@ class Post(models.Model):
else:
attr = None
if attr is not None:
- return u'%s %s' % (self.thread.title, attr)
+ return u'%s %s' % (self.thread.title, unicode(attr))
else:
return self.thread.title
raise NotImplementedError
@@ -2133,12 +2211,24 @@ class PostRevision(models.Model):
super(PostRevision, self).save(**kwargs)
def get_absolute_url(self):
+
+ is_multilingual = getattr(django_settings, 'ASKBOT_MULTILINGUAL', False)
+
+ if is_multilingual:
+ request_language = get_language()
+ activate_language(self.post.thread.language_code)
+
if self.post.is_question():
- return reverse('question_revisions', args = (self.post.id,))
+ url = reverse('question_revisions', args = (self.post.id,))
elif self.post.is_answer():
- return reverse('answer_revisions', kwargs = {'id':self.post.id})
+ url = reverse('answer_revisions', kwargs = {'id':self.post.id})
else:
- return self.post.get_absolute_url()
+ url = self.post.get_absolute_url()
+
+ if is_multilingual:
+ activate_language(request_language)
+
+ return url
def get_question_title(self):
#INFO: ack-grepping shows that it's only used for Questions, so there's no code for Answers
@@ -2201,4 +2291,5 @@ class AnonymousAnswer(DraftContent):
wiki=self.wiki,
text=self.text
)
+ self.question.thread.invalidate_cached_data()
self.delete()
diff --git a/askbot/models/question.py b/askbot/models/question.py
index 43844c82..51a7c24b 100644
--- a/askbot/models/question.py
+++ b/askbot/models/question.py
@@ -8,9 +8,12 @@ from django.contrib.auth.models import User
from django.core import cache # import cache, not from cache import cache, to be able to monkey-patch cache.cache in test cases
from django.core import exceptions as django_exceptions
from django.core.urlresolvers import reverse
+from django.template.loader import get_template
from django.utils.hashcompat import md5_constructor
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
import askbot
from askbot.conf import settings as askbot_settings
@@ -19,7 +22,7 @@ from askbot.mail import messages
from askbot.models.tag import Tag
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 delete_tags, separate_unused_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
@@ -29,7 +32,6 @@ from askbot import const
from askbot.utils.lists import LazyList
from askbot.search import mysql
from askbot.utils.slug import slugify
-from askbot.skins.loaders import get_template #jinja2 template loading enviroment
from askbot.search.state_manager import DummySearchState
class ThreadQuerySet(models.query.QuerySet):
@@ -41,6 +43,31 @@ class ThreadQuerySet(models.query.QuerySet):
groups = [Group.objects.get_global_group()]
return self.filter(groups__in=groups).distinct()
+ def get_for_title_query(self, search_query):
+ """returns threads matching title query
+ todo: possibly add tags
+ todo: implement full text search on relevant fields
+ """
+ db_engine_name = askbot.get_database_engine_name()
+ filter_parameters = {'deleted': False}
+ if 'postgresql_psycopg2' in db_engine_name:
+ from askbot.search import postgresql
+ return postgresql.run_title_search(
+ self, search_query
+ ).filter(
+ **filter_parameters
+ ).order_by('-relevance')
+ elif 'mysql' in db_engine_name and mysql.supports_full_text_search():
+ filter_parameters['title__search'] = search_query
+ else:
+ filter_parameters['title__icontains'] = search_query
+
+ if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False):
+ filter_parameters['language_code'] = get_language()
+
+ return self.filter(**filter_parameters)
+
+
class ThreadManager(BaseQuerySetManager):
def get_query_set(self):
@@ -77,7 +104,7 @@ class ThreadManager(BaseQuerySetManager):
tag_list = tag_list[:5]
last_topic = _('" and more')
- return '"' + '", "'.join(tag_list) + last_topic
+ return '"' + '", "'.join(tag_list) + unicode(last_topic)
def create(self, *args, **kwargs):
raise NotImplementedError
@@ -89,16 +116,19 @@ class ThreadManager(BaseQuerySetManager):
added_at,
wiki,
text,
- tagnames = None,
- is_anonymous = False,
- is_private = False,
- group_id = None,
- by_email = False,
- email_address = None
+ tagnames=None,
+ is_anonymous=False,
+ is_private=False,
+ group_id=None,
+ by_email=False,
+ email_address=None,
+ language=None,
):
"""creates new thread"""
# TODO: Some of this code will go to Post.objects.create_new
+ language = language or get_language()
+
thread = super(
ThreadManager,
self
@@ -106,7 +136,8 @@ class ThreadManager(BaseQuerySetManager):
title=title,
tagnames=tagnames,
last_activity_at=added_at,
- last_activity_by=author
+ last_activity_by=author,
+ language_code=language
)
#todo: code below looks like ``Post.objects.create_new()``
@@ -138,7 +169,7 @@ class ThreadManager(BaseQuerySetManager):
author=author,
is_anonymous=is_anonymous,
text=text,
- comment=const.POST_STATUS['default_version'],
+ comment=unicode(const.POST_STATUS['default_version']),
revised_at=added_at,
by_email=by_email,
email_address=email_address
@@ -173,6 +204,7 @@ class ThreadManager(BaseQuerySetManager):
def get_for_query(self, search_query, qs=None):
"""returns a query set of questions,
matching the full text query
+ todo: move to query set
"""
if getattr(django_settings, 'ENABLE_HAYSTACK_SEARCH', False):
from askbot.search.haystack import AskbotSearchQuerySet
@@ -194,7 +226,7 @@ class ThreadManager(BaseQuerySetManager):
)
elif 'postgresql_psycopg2' in askbot.get_database_engine_name():
from askbot.search import postgresql
- return postgresql.run_full_text_search(qs, search_query)
+ return postgresql.run_thread_search(qs, search_query)
else:
return qs.filter(
models.Q(title__icontains=search_query) |
@@ -212,11 +244,16 @@ class ThreadManager(BaseQuerySetManager):
"""
from askbot.conf import settings as askbot_settings # Avoid circular import
+ primary_filter = {
+ 'posts__post_type': 'question',
+ 'posts__deleted': False
+ }
+
+ if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False):
+ primary_filter['language_code'] = get_language()
+
# TODO: add a possibility to see deleted questions
- qs = self.filter(
- posts__post_type='question',
- posts__deleted=False,
- ) # (***) brings `askbot_post` into the SQL query, see the ordering section below
+ qs = self.filter(**primary_filter)
if askbot_settings.ENABLE_CONTENT_MODERATION:
qs = qs.filter(approved = True)
@@ -503,6 +540,7 @@ class Thread(models.Model):
answer_count = models.PositiveIntegerField(default=0)
last_activity_at = models.DateTimeField(default=datetime.datetime.now)
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)
followed_by = models.ManyToManyField(User, related_name='followed_threads')
favorited_by = models.ManyToManyField(User, through='FavoriteQuestion', related_name='unused_favorite_threads')
@@ -515,6 +553,7 @@ class Thread(models.Model):
null=True,
blank=True
)
+ deleted = models.BooleanField(default=False, db_index=True)
#denormalized data: the core approval of the posts is made
#in the revisions. In the revisions there is more data about
@@ -565,6 +604,13 @@ class Thread(models.Model):
else:
return self.get_answers(user).count()
+ def get_oldest_answer_id(self, user=None):
+ """give oldest visible answer id for the user"""
+ answers = self.get_answers(user=user).order_by('added_at')
+ if len(answers) > 0:
+ return answers[0].id
+ return None
+
def get_sharing_info(self, visitor=None):
"""returns a dictionary with abbreviated thread sharing info:
* users - up to a certain number of users, excluding the visitor
@@ -696,7 +742,7 @@ class Thread(models.Model):
else:
attr = None
if attr is not None:
- return u'%s %s' % (self.title, attr)
+ return u'%s %s' % (self.title, unicode(attr))
else:
return self.title
@@ -1132,8 +1178,6 @@ class Thread(models.Model):
"""
Updates Tag associations for a thread to match the given
tagname string.
- When tags are removed and their use count hits 0 - the tag is
- automatically deleted.
When an added tag does not exist - it is created
If tag moderation is on - new tags are placed on the queue
@@ -1185,10 +1229,6 @@ class Thread(models.Model):
else:
added_tags = Tag.objects.none()
- #this is odd: in sqlite you have to delete after creating new tags
- #somehow sqlite does not continue the id sequence, like postgrjs&mysql do
- delete_tags(unused_tags)#tags with used_count == 0 are deleted
-
#Save denormalized tag names on thread. Preserve order from user input.
accepted_added_tags = filter_accepted_tags(added_tags)
added_tagnames = set([tag.name for tag in accepted_added_tags])
@@ -1223,7 +1263,7 @@ class Thread(models.Model):
self.update_summary_html() # regenerate question/thread summary html
####################################################################
#if there are any modified tags, update their use counts
- modified_tags = set(modified_tags) - set(unused_tags)
+ modified_tags = set(modified_tags)
if modified_tags:
Tag.objects.update_use_counts(modified_tags)
signals.tags_updated.send(None,
@@ -1246,10 +1286,10 @@ class Thread(models.Model):
tag_names.append(tag_name)
self.retag(
- retagged_by = user,
- retagged_at = timestamp,
- tagnames = ' '.join(tag_names),
- silent = silent
+ retagged_by=user,
+ retagged_at=timestamp,
+ tagnames=' '.join(tag_names),
+ silent=silent
)
def retag(self, retagged_by=None, retagged_at=None, tagnames=None, silent=False):
@@ -1279,13 +1319,13 @@ class Thread(models.Model):
# Create a new revision
latest_revision = thread_question.get_latest_revision()
PostRevision.objects.create(
- post = thread_question,
- title = latest_revision.title,
- author = retagged_by,
- revised_at = retagged_at,
- tagnames = tagnames,
- summary = const.POST_STATUS['retagged'],
- text = latest_revision.text
+ post=thread_question,
+ title=latest_revision.title,
+ author=retagged_by,
+ revised_at=retagged_at,
+ tagnames=tagnames,
+ summary=unicode(const.POST_STATUS['retagged']),
+ text=latest_revision.text
)
def has_favorite_by_user(self, user):
@@ -1349,7 +1389,7 @@ class Thread(models.Model):
#because we do not include any visitor-related info in the cache key
#ideally cache should be shareable between users, so straight up
#using the user id for cache is wrong, we could use group
- #memberships, but in that case we'd need to be more careful with
+ #memberships, but in that case we'd need to be more careful with
#cache invalidation
context = {
'thread': self,
@@ -1418,16 +1458,35 @@ class AnonymousQuestion(DraftContent):
tagnames = models.CharField(max_length=125)
is_anonymous = models.BooleanField(default=False)
- def publish(self,user):
+ def publish(self, user):
added_at = datetime.datetime.now()
#todo: wrong - use User.post_question() instead
- Thread.objects.create_new(
- title = self.title,
- added_at = added_at,
- author = user,
- wiki = self.wiki,
- is_anonymous = self.is_anonymous,
- tagnames = self.tagnames,
- text = self.text,
- )
- self.delete()
+ try:
+ user.assert_can_post_text(self.text)
+ Thread.objects.create_new(
+ title = self.title,
+ added_at = added_at,
+ author = user,
+ wiki = self.wiki,
+ is_anonymous = self.is_anonymous,
+ tagnames = self.tagnames,
+ text = self.text,
+ )
+ self.delete()
+ except django_exceptions.PermissionDenied, error:
+ #delete previous draft questions (only one is allowed anyway)
+ prev_drafts = DraftQuestion.objects.filter(author=user)
+ prev_drafts.delete()
+ #convert this question to draft
+ DraftQuestion.objects.create(
+ author=user,
+ title=self.title,
+ 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 0db7244c..983edc8f 100644
--- a/askbot/models/reply_by_email.py
+++ b/askbot/models/reply_by_email.py
@@ -5,6 +5,7 @@ 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
@@ -34,12 +35,12 @@ class ReplyAddressManager(BaseQuerySetManager):
REPLY_ACTION_CHOICES = (
- ('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')),
+ ('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')),
)
class ReplyAddress(models.Model):
"""Stores a reply address for the post
diff --git a/askbot/models/repute.py b/askbot/models/repute.py
index a6e9d7d1..e48773e6 100644
--- a/askbot/models/repute.py
+++ b/askbot/models/repute.py
@@ -223,7 +223,7 @@ class Repute(models.Model):
return _('<em>Changed by moderator. Reason:</em> %(reason)s') \
% {'reason':self.comment}
else:
- delta = self.positive - self.negative
+ delta = self.positive + self.negative#.negative is < 0 so we add!
link_title_data = {
'points': abs(delta),
'username': self.user.username,
diff --git a/askbot/models/tag.py b/askbot/models/tag.py
index e4c4540a..455995e0 100644
--- a/askbot/models/tag.py
+++ b/askbot/models/tag.py
@@ -2,6 +2,7 @@ import re
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 django.conf import settings
from askbot.models.base import BaseQuerySetManager
from askbot import const
@@ -176,7 +177,7 @@ class TagManager(BaseQuerySetManager):
"""temporary function that filters out the group tags"""
return self.all()
- def create(self, name = None, created_by = None, **kwargs):
+ def create(self, name=None, created_by=None, **kwargs):
"""Creates a new tag"""
if created_by.can_create_tags() or is_preapproved_tag_name(name):
status = Tag.STATUS_ACCEPTED
@@ -307,9 +308,9 @@ class Tag(models.Model):
class MarkedTag(models.Model):
TAG_MARK_REASONS = (
- ('good', _('interesting')),
- ('bad', _('ignored')),
- ('subscribed', _('subscribed')),
+ ('good', ugettext_lazy('interesting')),
+ ('bad', ugettext_lazy('ignored')),
+ ('subscribed', ugettext_lazy('subscribed')),
)
tag = models.ForeignKey('Tag', related_name='user_selections')
user = models.ForeignKey(User, related_name='tag_selections')
diff --git a/askbot/models/user.py b/askbot/models/user.py
index 00e9428a..cff24b18 100644
--- a/askbot/models/user.py
+++ b/askbot/models/user.py
@@ -10,6 +10,7 @@ from django.contrib.auth.models import Group as AuthGroup
from django.core import exceptions
from django.forms import EmailField, URLField
from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy
from django.utils.html import strip_tags
from askbot import const
from askbot.conf import settings as askbot_settings
@@ -17,6 +18,7 @@ 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
@@ -55,7 +57,7 @@ class ActivityManager(models.Manager):
mentioned_at = None,
mentioned_in = None,
reported = None
- ):
+ ):
#todo: automate this using python inspect module
kwargs = dict()
@@ -94,7 +96,7 @@ class ActivityManager(models.Manager):
return mention_activity
def get_mentions(
- self,
+ self,
mentioned_by = None,
mentioned_whom = None,
mentioned_at = None,
@@ -279,17 +281,17 @@ class EmailFeedSetting(models.Model):
'm_and_c': 'i'
}
FEED_TYPE_CHOICES = (
- ('q_all',_('Entire forum')),
- ('q_ask',_('Questions that I asked')),
- ('q_ans',_('Questions that I answered')),
- ('q_sel',_('Individually selected questions')),
- ('m_and_c',_('Mentions and comment responses')),
+ ('q_all', ugettext_lazy('Entire forum')),
+ ('q_ask', ugettext_lazy('Questions that I asked')),
+ ('q_ans', ugettext_lazy('Questions that I answered')),
+ ('q_sel', ugettext_lazy('Individually selected questions')),
+ ('m_and_c', ugettext_lazy('Mentions and comment responses')),
)
UPDATE_FREQUENCY = (
- ('i',_('Instantly')),
- ('d',_('Daily')),
- ('w',_('Weekly')),
- ('n',_('No email')),
+ ('i', ugettext_lazy('Instantly')),
+ ('d', ugettext_lazy('Daily')),
+ ('w', ugettext_lazy('Weekly')),
+ ('n', ugettext_lazy('No email')),
)
@@ -316,8 +318,8 @@ class EmailFeedSetting(models.Model):
else:
reported_at = '%s' % self.reported_at.strftime('%d/%m/%y %H:%M')
return 'Email feed for %s type=%s, frequency=%s, reported_at=%s' % (
- self.subscriber,
- self.feed_type,
+ self.subscriber,
+ self.feed_type,
self.frequency,
reported_at
)
@@ -424,7 +426,7 @@ class GroupQuerySet(models.query.QuerySet):
class GroupManager(BaseQuerySetManager):
"""model manager for askbot groups"""
-
+
def get_query_set(self):
return GroupQuerySet(self.model)
@@ -591,3 +593,71 @@ class Group(AuthGroup):
def save(self, *args, **kwargs):
self.clean()
super(Group, self).save(*args, **kwargs)
+
+class BulkTagSubscriptionManager(BaseQuerySetManager):
+
+ def create(
+ self, tag_names=None,
+ user_list=None, group_list=None,
+ tag_author=None, **kwargs
+ ):
+
+ tag_names = tag_names or []
+ user_list = user_list or []
+ group_list = group_list or []
+
+ new_object = super(BulkTagSubscriptionManager, self).create(**kwargs)
+ tag_name_list = []
+
+ if tag_names:
+ tags, new_tag_names = get_tags_by_names(tag_names)
+ if new_tag_names:
+ assert(tag_author)
+
+ tags_id_list= [tag.id for tag in tags]
+ tag_name_list = [tag.name for tag in tags]
+
+ new_tags = Tag.objects.create_in_bulk(
+ tag_names=new_tag_names,
+ user=tag_author
+ )
+
+ tags_id_list.extend([tag.id for tag in new_tags])
+ tag_name_list.extend([tag.name for tag in new_tags])
+
+ new_object.tags.add(*tags_id_list)
+
+ if user_list:
+ user_ids = []
+ for user in user_list:
+ user_ids.append(user.id)
+ user.mark_tags(tagnames=tag_name_list,
+ reason='subscribed',
+ action='add')
+
+ new_object.users.add(*user_ids)
+
+ if group_list:
+ group_ids = []
+ for group in group_list:
+ #TODO: do the group marked tag thing here
+ group_ids.append(group.id)
+ new_object.groups.add(*group_ids)
+
+ return new_object
+
+
+class BulkTagSubscription(models.Model):
+ date_added = models.DateField(auto_now_add=True)
+ tags = models.ManyToManyField(Tag)
+ users = models.ManyToManyField(User)
+ groups = models.ManyToManyField(Group)
+
+ objects = BulkTagSubscriptionManager()
+
+ def tag_list(self):
+ return [tag.name for tag in self.tags.all()]
+
+ class Meta:
+ app_label = 'askbot'
+ ordering = ['-date_added']
diff --git a/askbot/models/widgets.py b/askbot/models/widgets.py
index 27fc3d84..bdec5eb2 100644
--- a/askbot/models/widgets.py
+++ b/askbot/models/widgets.py
@@ -1,5 +1,5 @@
from django.db import models
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy
from askbot.models import Tag, Group
from askbot.const import DEFAULT_QUESTION_WIDGET_STYLE, SEARCH_ORDER_BY
@@ -24,14 +24,14 @@ class AskWidget(models.Model):
class QuestionWidget(models.Model):
title = models.CharField(max_length=100)
question_number = models.PositiveIntegerField(default=7)
- tagnames = models.CharField(_('tags'), max_length=50)
+ tagnames = models.CharField(ugettext_lazy('tags'), max_length=50)
group = models.ForeignKey(Group, null=True, blank=True)
search_query = models.CharField(
max_length=50, null=True, blank=True, default=''
)
order_by = models.CharField(max_length=18,
choices=SEARCH_ORDER_BY, default='-added_at')
- style = models.TextField(_('css for the widget'),
+ style = models.TextField(ugettext_lazy('css for the widget'),
default=DEFAULT_QUESTION_WIDGET_STYLE, blank=True)
class Meta:
diff --git a/askbot/patches/__init__.py b/askbot/patches/__init__.py
index ebaeabac..6145097c 100644
--- a/askbot/patches/__init__.py
+++ b/askbot/patches/__init__.py
@@ -17,6 +17,9 @@ def patch_django():
django_patches.add_csrf_protection()
django_patches.add_available_attrs_decorator()
+ if major == 1 and minor <=2:
+ django_patches.add_render_shortcut()
+
def patch_coffin():
"""coffin before version 0.3.4
does not have csrf_token template tag.
diff --git a/askbot/patches/django_patches.py b/askbot/patches/django_patches.py
index e28c88ba..fe0e2fe7 100644
--- a/askbot/patches/django_patches.py
+++ b/askbot/patches/django_patches.py
@@ -339,3 +339,16 @@ def add_available_attrs_decorator():
return tuple(a for a in WRAPPER_ASSIGNMENTS if hasattr(fn, a))
import django.utils.decorators
django.utils.decorators.available_attrs = available_attrs
+
+def add_render_shortcut():
+ """adds `render` shortcut, introduced with django 1.3"""
+ try:
+ from django.shortcuts import render
+ except ImportError:
+ def render(request, template, data=None):
+ from django.shortcuts import render_to_response
+ from django.template import RequestContext
+ return render_to_response(template, RequestContext(request, data))
+
+ import django.shortcuts
+ django.shortcuts.render = render
diff --git a/askbot/search/mysql.py b/askbot/search/mysql.py
index 055b30ca..e6d2e21e 100644
--- a/askbot/search/mysql.py
+++ b/askbot/search/mysql.py
@@ -26,14 +26,3 @@ def supports_full_text_search():
else:
SUPPORTS_FTS = False
return SUPPORTS_FTS
-
-def get_create_full_text_index_sql(index_name, table_name, column_list):
- cursor = connection.cursor()
- column_sql = '(%s)' % ','.join(column_list)
- sql = 'CREATE FULLTEXT INDEX %s on %s %s' % (index_name, table_name, column_sql)
- cursor.execute(sql)
- return sql
-
-def get_drop_index_sql(index_name, table_name):
- return 'ALTER TABLE %s DROP INDEX %s' % (table_name, index_name)
-
diff --git a/askbot/search/postgresql/__init__.py b/askbot/search/postgresql/__init__.py
index 5b893129..e42190a8 100644
--- a/askbot/search/postgresql/__init__.py
+++ b/askbot/search/postgresql/__init__.py
@@ -1,5 +1,27 @@
"""Procedures to initialize the full text search in PostgresQL"""
from django.db import connection
+from django.conf import settings as django_settings
+from django.utils.translation import get_language
+
+#mapping of "django" language names to postgres
+LANGUAGE_NAMES = {
+ 'da': 'danish',
+ 'nl': 'dutch',
+ 'en': 'english',
+ 'fi': 'finnish',
+ 'fr': 'french',
+ 'de': 'german',
+ 'hu': 'hungarian',
+ 'it': 'italian',
+ 'ja': 'japanese',
+ 'nb': 'norwegian',
+ 'pt': 'portugese',
+ 'ro': 'romanian',
+ 'ru': 'russian',
+ 'es': 'spanish',
+ 'sv': 'swedish',
+ 'tr': 'turkish'
+}
def setup_full_text_search(script_path):
"""using postgresql database connection,
@@ -20,7 +42,7 @@ def setup_full_text_search(script_path):
finally:
cursor.close()
-def run_full_text_search(query_set, query_text):
+def run_full_text_search(query_set, query_text, text_search_vector_name):
"""runs full text search against the query set and
the search text. All words in the query text are
added to the search with the & operator - i.e.
@@ -29,17 +51,29 @@ def run_full_text_search(query_set, query_text):
It is also assumed that we ar searching in the same
table as the query set was built against, also
it is assumed that the table has text search vector
- stored in the column called `text_search_vector`.
+ stored in the column called with value of`text_search_vector_name`.
"""
table_name = query_set.model._meta.db_table
-
+
rank_clause = 'ts_rank(' + table_name + \
- '.text_search_vector, plainto_tsquery(%s))'
+ '.' + text_search_vector_name + \
+ ', plainto_tsquery(%s, %s))'
+
+ where_clause = table_name + '.' + \
+ text_search_vector_name + \
+ ' @@ plainto_tsquery(%s, %s)'
+
+ language_code = get_language()
- where_clause = table_name + '.text_search_vector @@ plainto_tsquery(%s)'
+ #the table name is a hack, because user does not have the language code
+ is_multilingual = getattr(django_settings, 'ASKBOT_MULTILINGUAL', True)
+ if is_multilingual and table_name == 'askbot_thread':
+ where_clause += " AND " + table_name + \
+ '.' + "language_code='" + language_code + "'"
search_query = '&'.join(query_text.split())#apply "AND" operator
- extra_params = (search_query,)
+ language_name = LANGUAGE_NAMES.get(language_code, 'english')
+ extra_params = (language_name, search_query,)
extra_kwargs = {
'select': {'relevance': rank_clause},
'where': [where_clause,],
@@ -48,3 +82,13 @@ def run_full_text_search(query_set, query_text):
}
return query_set.extra(**extra_kwargs)
+
+def run_thread_search(query_set, query):
+ """runs search for full thread content"""
+ return run_full_text_search(query_set, query, 'text_search_vector');
+
+run_user_search = run_thread_search #an alias
+
+def run_title_search(query_set, query):
+ """runs search for title and tags"""
+ return run_full_text_search(query_set, query, 'title_search_vector')
diff --git a/askbot/search/postgresql/thread_and_post_models_01022013.plsql b/askbot/search/postgresql/thread_and_post_models_01022013.plsql
new file mode 100644
index 00000000..2a50924a
--- /dev/null
+++ b/askbot/search/postgresql/thread_and_post_models_01022013.plsql
@@ -0,0 +1,298 @@
+/* function testing for existence of a column in a table
+ if table does not exists, function will return "false" */
+CREATE OR REPLACE FUNCTION column_exists(colname text, tablename text)
+RETURNS boolean AS
+$$
+DECLARE
+ q text;
+ onerow record;
+BEGIN
+
+ q = 'SELECT attname FROM pg_attribute WHERE attrelid = ( SELECT oid FROM pg_class WHERE relname = '''||tablename||''') AND attname = '''||colname||'''';
+
+ FOR onerow IN EXECUTE q LOOP
+ RETURN true;
+ END LOOP;
+
+ RETURN false;
+END;
+$$ LANGUAGE plpgsql;
+
+/* function adding tsvector column to table if it does not exists */
+CREATE OR REPLACE FUNCTION add_tsvector_column(colname text, tablename text)
+RETURNS boolean AS
+$$
+DECLARE
+ q text;
+BEGIN
+ IF NOT column_exists(colname, tablename) THEN
+ q = 'ALTER TABLE ' || tablename || ' ADD COLUMN ' || colname || ' tsvector';
+ EXECUTE q;
+ RETURN true;
+ ELSE
+ q = 'UPDATE ' || tablename || ' SET ' || colname || '=NULL';
+ EXECUTE q;
+ RETURN false;
+ END IF;
+END;
+$$ LANGUAGE plpgsql;
+
+/* aggregate function that concatenates tsvectors */
+CREATE OR REPLACE FUNCTION tsv_add(tsv1 tsvector, tsv2 tsvector)
+RETURNS tsvector AS
+$$
+BEGIN
+ RETURN tsv1 || tsv2;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION setup_aggregates() RETURNS boolean AS
+$$
+DECLARE
+ onerow record;
+BEGIN
+ FOR onerow IN SELECT * FROM pg_proc WHERE proname = 'concat_tsvectors' AND proisagg LOOP
+ DROP AGGREGATE concat_tsvectors(tsvector);
+ END LOOP;
+ CREATE AGGREGATE concat_tsvectors (
+ BASETYPE = tsvector,
+ SFUNC = tsv_add,
+ STYPE = tsvector,
+ INITCOND = ''
+ );
+ RETURN true;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT setup_aggregates();
+
+/* language name resolution function. todo: move languace conv to python code */
+DROP FUNCTION IF EXISTS get_language_name_from_code(lang_code text);
+CREATE OR REPLACE FUNCTION get_language_name_from_code(lang_code text)
+RETURNS regconfig AS
+$$
+BEGIN
+ IF lang_code = 'en' THEN
+ RETURN 'english';
+ ELSIF lang_code = 'da' THEN
+ RETURN 'danish';
+ ELSIF lang_code = 'nl' THEN
+ RETURN 'danish';
+ ELSIF lang_code = 'fi' THEN
+ RETURN 'finnish';
+ ELSIF lang_code = 'fr' THEN
+ RETURN 'french';
+ ELSIF lang_code = 'de' THEN
+ RETURN 'german';
+ ELSIF lang_code = 'hu' THEN
+ RETURN 'hungarian';
+ ELSIF lang_code = 'it' THEN
+ RETURN 'italian';
+ ELSIF lang_code = 'nb' THEN
+ RETURN 'norwegian';
+ ELSIF lang_code = 'pt' THEN
+ RETURN 'portugese';
+ ELSIF lang_code = 'ro' THEN
+ RETURN 'romanian';
+ ELSIF lang_code = 'ru' THEN
+ RETURN 'russian';
+ ELSIF lang_code = 'es' THEN
+ RETURN 'spanish';
+ ELSIF lang_code = 'sv' THEN
+ RETURN 'swedish';
+ ELSIF lang_code = 'tr' THEN
+ RETURN 'turkish';
+ ELSIF lang_code = 'ja' THEN
+ RETURN 'japanese';
+ END IF;
+ RETURN 'english';
+END;
+$$ LANGUAGE plpgsql;
+
+/* calculates text search vector for the individual thread row
+DOES not include question body post, answers or comments */
+DROP FUNCTION IF EXISTS get_thread_tsv(title text, tagnames text);
+CREATE OR REPLACE FUNCTION get_thread_tsv(title text, tagnames text, lang_code text)
+RETURNS tsvector AS
+$$
+DECLARE
+ lang_name regconfig;
+BEGIN
+ lang_name = get_language_name_from_code(lang_code);
+ /* todo add weight depending on votes */
+ RETURN setweight(to_tsvector(lang_name, coalesce(title, '')), 'A') ||
+ setweight(to_tsvector(lang_name, coalesce(tagnames, '')), 'A');
+END;
+$$ LANGUAGE plpgsql;
+
+/* calculates text seanch vector for the individual question row */
+DROP FUNCTION IF EXISTS get_post_tsv(text text, post_type text);
+CREATE OR REPLACE FUNCTION get_post_tsv(text text, post_type text, lang_code text)
+RETURNS tsvector AS
+$$
+DECLARE
+ lang_name regconfig;
+BEGIN
+ /* todo adjust weights to reflect votes */
+ lang_name = get_language_name_from_code(lang_code);
+ IF post_type='question' THEN
+ RETURN setweight(to_tsvector(lang_name, coalesce(text, '')), 'B');
+ ELSIF post_type='answer' THEN
+ /* todo reflect whether the answer acepted or has many points */
+ RETURN setweight(to_tsvector(lang_name, coalesce(text, '')), 'C');
+ ELSIF post_type='comment' THEN
+ RETURN setweight(to_tsvector(lang_name, coalesce(text, '')), 'D');
+ ELSE
+ RETURN to_tsvector('');
+ END IF;
+END;
+$$ LANGUAGE plpgsql;
+
+/* calculates text search vector for the question body part by thread id
+here we extract question title and the text by thread_id and then
+calculate the text search vector. In the future question
+title will be moved to the askbot_thread table and this function
+will be simpler.
+*/
+CREATE OR REPLACE FUNCTION get_thread_question_tsv(thread_id integer, language_code text)
+RETURNS tsvector AS
+$$
+DECLARE
+ query text;
+ onerow record;
+BEGIN
+ query = 'SELECT text FROM askbot_post WHERE thread_id=' || thread_id ||
+ ' AND post_type=''question'' AND deleted=false';
+ FOR onerow in EXECUTE query LOOP
+ RETURN get_post_tsv(onerow.text, 'question', language_code);
+ END LOOP;
+ RETURN to_tsvector('');
+END;
+$$ LANGUAGE plpgsql;
+
+DROP FUNCTION IF EXISTS get_dependent_comments_tsv(object_id integer, tablename text);
+CREATE OR REPLACE FUNCTION get_dependent_comments_tsv(parent_id integer)
+RETURNS tsvector AS
+$$
+DECLARE
+ query text;
+ onerow record;
+BEGIN
+ query = 'SELECT concat_tsvectors(text_search_vector), count(*) FROM askbot_post' ||
+ ' WHERE parent_id=' || parent_id ||
+ ' AND post_type=''comment'' AND deleted=false';
+ FOR onerow IN EXECUTE query LOOP
+ IF onerow.count = 0 THEN
+ RETURN to_tsvector('');
+ ELSE
+ RETURN onerow.concat_tsvectors;
+ END IF;
+ END LOOP;
+END;
+$$ LANGUAGE plpgsql;
+
+DROP FUNCTION IF EXISTS get_dependent_answers_tsv(question_id integer);
+CREATE OR REPLACE FUNCTION get_dependent_answers_tsv(thread_id integer, language_code text)
+RETURNS tsvector AS
+$$
+DECLARE
+ query text;
+ onerow record;
+BEGIN
+ query = 'SELECT concat_tsvectors(text_search_vector), count(*)' ||
+ 'FROM askbot_post WHERE post_type = ''answer'' AND thread_id = ' || thread_id ||
+ ' AND deleted=false';
+ FOR onerow IN EXECUTE query LOOP
+ IF onerow.count = 0 THEN
+ RETURN to_tsvector('');
+ ELSE
+ RETURN onerow.concat_tsvectors;
+ END IF;
+ END LOOP;
+END;
+$$ LANGUAGE plpgsql;
+
+DROP TRIGGER IF EXISTS thread_search_vector_update_trigger on askbot_thread;
+DROP TRIGGER IF EXISTS thread_search_vector_insert_trigger on askbot_thread;
+DROP TRIGGER IF EXISTS post_search_vector_update_trigger on askbot_post;
+
+/* create tsvector columns in the content tables
+ need to isolate these into own transactions, b/c of a weird mix
+ of triggers/update and alter table statements
+*/
+SELECT add_tsvector_column('text_search_vector', 'askbot_thread');
+COMMIT;
+BEGIN;
+SELECT add_tsvector_column('text_search_vector', 'askbot_post');
+COMMIT;
+BEGIN;
+SELECT add_tsvector_column('title_search_vector', 'askbot_thread');
+COMMIT;
+BEGIN;
+
+/* populate tsvectors with data */
+-- post tsvectors
+UPDATE askbot_post set text_search_vector = get_post_tsv(text, post_type, language_code) WHERE post_type IN ('answer', 'comment', 'question');
+UPDATE askbot_post as q SET text_search_vector = text_search_vector ||
+ get_dependent_comments_tsv(q.id) WHERE post_type IN ('question', 'answer');
+--thread tsvector
+UPDATE askbot_thread SET text_search_vector = get_thread_tsv(title, tagnames, language_code);
+UPDATE askbot_thread as t SET text_search_vector = text_search_vector ||
+ get_dependent_answers_tsv(t.id, t.language_code) ||
+ get_thread_question_tsv(t.id, t.language_code);
+UPDATE askbot_thread SET title_search_vector = get_thread_tsv(title, tagnames, language_code);
+
+/* one trigger per table for tsv updates */
+
+/* set up update triggers */
+CREATE OR REPLACE FUNCTION thread_update_trigger() RETURNS trigger AS
+$$
+DECLARE
+ title_tsv tsvector;
+BEGIN
+ title_tsv = get_thread_tsv(new.title, new.tagnames, new.language_code);
+ new.title_search_vector = title_tsv;
+ new.text_search_vector = title_tsv ||
+ get_thread_question_tsv(new.id, new.language_code) ||
+ get_dependent_answers_tsv(new.id, new.language_code);
+ RETURN new;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER thread_search_vector_update_trigger
+BEFORE UPDATE ON askbot_thread FOR EACH ROW EXECUTE PROCEDURE thread_update_trigger();
+
+CREATE OR REPLACE FUNCTION thread_insert_trigger() RETURNS trigger AS
+$$
+BEGIN
+ new.text_search_vector = get_thread_tsv(new.title, new.tagnames, new.language_code);
+ RETURN new;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER thread_search_vector_insert_trigger
+BEFORE INSERT ON askbot_thread FOR EACH ROW EXECUTE PROCEDURE thread_insert_trigger();
+
+/* post trigger */
+CREATE OR REPLACE FUNCTION post_trigger() RETURNS trigger AS
+$$
+BEGIN
+ IF new.post_type = 'question' THEN
+ new.text_search_vector = get_post_tsv(new.text, 'question', new.language_code) ||
+ get_dependent_comments_tsv(new.id);
+ ELSIF new.post_type = 'answer' THEN
+ new.text_search_vector = get_post_tsv(new.text, 'answer', new.language_code) ||
+ get_dependent_comments_tsv(new.id);
+ ELSIF new.post_type = 'comment' THEN
+ new.text_search_vector = get_post_tsv(new.text, 'comment', new.language_code);
+ END IF;
+ UPDATE askbot_thread SET id=new.thread_id WHERE id=new.thread_id;
+ return new;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER post_search_vector_update_trigger
+AFTER INSERT OR UPDATE ON askbot_post FOR EACH ROW EXECUTE PROCEDURE post_trigger();
+
+COMMIT;
+BEGIN;
+
+DROP INDEX IF EXISTS askbot_search_idx;
+CREATE INDEX askbot_search_idx ON askbot_thread USING gin(text_search_vector);
diff --git a/askbot/search/postgresql/thread_and_post_models_10032013.plsql b/askbot/search/postgresql/thread_and_post_models_10032013.plsql
new file mode 100644
index 00000000..72f17fea
--- /dev/null
+++ b/askbot/search/postgresql/thread_and_post_models_10032013.plsql
@@ -0,0 +1,304 @@
+/* function testing for existence of a column in a table
+ if table does not exists, function will return "false" */
+CREATE OR REPLACE FUNCTION column_exists(colname text, tablename text)
+RETURNS boolean AS
+$$
+DECLARE
+ q text;
+ onerow record;
+BEGIN
+
+ q = 'SELECT attname FROM pg_attribute WHERE attrelid = ( SELECT oid FROM pg_class WHERE relname = '''||tablename||''') AND attname = '''||colname||'''';
+
+ FOR onerow IN EXECUTE q LOOP
+ RETURN true;
+ END LOOP;
+
+ RETURN false;
+END;
+$$ LANGUAGE plpgsql;
+
+/* function adding tsvector column to table if it does not exists */
+CREATE OR REPLACE FUNCTION add_tsvector_column(colname text, tablename text)
+RETURNS boolean AS
+$$
+DECLARE
+ q text;
+BEGIN
+ IF NOT column_exists(colname, tablename) THEN
+ q = 'ALTER TABLE ' || tablename || ' ADD COLUMN ' || colname || ' tsvector';
+ EXECUTE q;
+ RETURN true;
+ ELSE
+ q = 'UPDATE ' || tablename || ' SET ' || colname || '=NULL';
+ EXECUTE q;
+ RETURN false;
+ END IF;
+END;
+$$ LANGUAGE plpgsql;
+
+/* aggregate function that concatenates tsvectors */
+CREATE OR REPLACE FUNCTION tsv_add(tsv1 tsvector, tsv2 tsvector)
+RETURNS tsvector AS
+$$
+BEGIN
+ RETURN tsv1 || tsv2;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION setup_aggregates() RETURNS boolean AS
+$$
+DECLARE
+ onerow record;
+BEGIN
+ FOR onerow IN SELECT * FROM pg_proc WHERE proname = 'concat_tsvectors' AND proisagg LOOP
+ DROP AGGREGATE concat_tsvectors(tsvector);
+ END LOOP;
+ CREATE AGGREGATE concat_tsvectors (
+ BASETYPE = tsvector,
+ SFUNC = tsv_add,
+ STYPE = tsvector,
+ INITCOND = ''
+ );
+ RETURN true;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT setup_aggregates();
+
+/* language name resolution function. todo: move languace conv to python code */
+DROP FUNCTION IF EXISTS get_language_name_from_code(lang_code text);
+CREATE OR REPLACE FUNCTION get_language_name_from_code(lang_code text)
+RETURNS regconfig AS
+$$
+BEGIN
+ IF lang_code = 'en' THEN
+ RETURN 'english';
+ ELSIF lang_code = 'da' THEN
+ RETURN 'danish';
+ ELSIF lang_code = 'nl' THEN
+ RETURN 'danish';
+ ELSIF lang_code = 'fi' THEN
+ RETURN 'finnish';
+ ELSIF lang_code = 'fr' THEN
+ RETURN 'french';
+ ELSIF lang_code = 'de' THEN
+ RETURN 'german';
+ ELSIF lang_code = 'hu' THEN
+ RETURN 'hungarian';
+ ELSIF lang_code = 'it' THEN
+ RETURN 'italian';
+ ELSIF lang_code = 'nb' THEN
+ RETURN 'norwegian';
+ ELSIF lang_code = 'pt' THEN
+ RETURN 'portugese';
+ ELSIF lang_code = 'ro' THEN
+ RETURN 'romanian';
+ ELSIF lang_code = 'ru' THEN
+ RETURN 'russian';
+ ELSIF lang_code = 'es' THEN
+ RETURN 'spanish';
+ ELSIF lang_code = 'sv' THEN
+ RETURN 'swedish';
+ ELSIF lang_code = 'tr' THEN
+ RETURN 'turkish';
+ ELSIF lang_code = 'ja' THEN
+ RETURN 'japanese';
+ END IF;
+ RETURN 'english';
+END;
+$$ LANGUAGE plpgsql;
+
+/* calculates text search vector for the individual thread row
+DOES not include question body post, answers or comments */
+DROP FUNCTION IF EXISTS get_thread_tsv(title text, tagnames text);
+CREATE OR REPLACE FUNCTION get_thread_tsv(title text, tagnames text, lang_code text)
+RETURNS tsvector AS
+$$
+DECLARE
+ lang_name regconfig;
+BEGIN
+ lang_name = get_language_name_from_code(lang_code);
+ /* todo add weight depending on votes */
+ RETURN setweight(to_tsvector(lang_name, coalesce(title, '')), 'A') ||
+ setweight(to_tsvector(lang_name, coalesce(tagnames, '')), 'A');
+END;
+$$ LANGUAGE plpgsql;
+
+/* calculates text seanch vector for the individual question row */
+DROP FUNCTION IF EXISTS get_post_tsv(text text, post_type text);
+CREATE OR REPLACE FUNCTION get_post_tsv(text text, post_type text, lang_code text)
+RETURNS tsvector AS
+$$
+DECLARE
+ lang_name regconfig;
+BEGIN
+ /* todo adjust weights to reflect votes */
+ lang_name = get_language_name_from_code(lang_code);
+ IF post_type='question' THEN
+ RETURN setweight(to_tsvector(lang_name, coalesce(text, '')), 'B');
+ ELSIF post_type='answer' THEN
+ /* todo reflect whether the answer acepted or has many points */
+ RETURN setweight(to_tsvector(lang_name, coalesce(text, '')), 'C');
+ ELSIF post_type='comment' THEN
+ RETURN setweight(to_tsvector(lang_name, coalesce(text, '')), 'D');
+ ELSE
+ RETURN to_tsvector('');
+ END IF;
+END;
+$$ LANGUAGE plpgsql;
+
+/* calculates text search vector for the question body part by thread id
+here we extract question title and the text by thread_id and then
+calculate the text search vector. In the future question
+title will be moved to the askbot_thread table and this function
+will be simpler.
+*/
+CREATE OR REPLACE FUNCTION get_thread_question_tsv(thread_id integer, language_code text)
+RETURNS tsvector AS
+$$
+DECLARE
+ query text;
+ onerow record;
+BEGIN
+ query = 'SELECT text FROM askbot_post WHERE thread_id=' || thread_id ||
+ ' AND post_type=''question'' AND deleted=false';
+ FOR onerow in EXECUTE query LOOP
+ RETURN get_post_tsv(onerow.text, 'question', language_code);
+ END LOOP;
+ RETURN to_tsvector('');
+END;
+$$ LANGUAGE plpgsql;
+
+DROP FUNCTION IF EXISTS get_dependent_comments_tsv(object_id integer, tablename text);
+CREATE OR REPLACE FUNCTION get_dependent_comments_tsv(parent_id integer)
+RETURNS tsvector AS
+$$
+DECLARE
+ query text;
+ onerow record;
+BEGIN
+ query = 'SELECT concat_tsvectors(text_search_vector), count(*) FROM askbot_post' ||
+ ' WHERE parent_id=' || parent_id ||
+ ' AND post_type=''comment'' AND deleted=false';
+ FOR onerow IN EXECUTE query LOOP
+ IF onerow.count = 0 THEN
+ RETURN to_tsvector('');
+ ELSE
+ RETURN onerow.concat_tsvectors;
+ END IF;
+ END LOOP;
+END;
+$$ LANGUAGE plpgsql;
+
+DROP FUNCTION IF EXISTS get_dependent_answers_tsv(question_id integer);
+CREATE OR REPLACE FUNCTION get_dependent_answers_tsv(thread_id integer, language_code text)
+RETURNS tsvector AS
+$$
+DECLARE
+ query text;
+ onerow record;
+BEGIN
+ query = 'SELECT concat_tsvectors(text_search_vector), count(*)' ||
+ 'FROM askbot_post WHERE post_type = ''answer'' AND thread_id = ' || thread_id ||
+ ' AND deleted=false';
+ FOR onerow IN EXECUTE query LOOP
+ IF onerow.count = 0 THEN
+ RETURN to_tsvector('');
+ ELSE
+ RETURN onerow.concat_tsvectors;
+ END IF;
+ END LOOP;
+END;
+$$ LANGUAGE plpgsql;
+
+DROP TRIGGER IF EXISTS thread_search_vector_update_trigger on askbot_thread;
+DROP TRIGGER IF EXISTS thread_search_vector_insert_trigger on askbot_thread;
+DROP TRIGGER IF EXISTS post_search_vector_update_trigger on askbot_post;
+
+/* create tsvector columns in the content tables
+ need to isolate these into own transactions, b/c of a weird mix
+ of triggers/update and alter table statements
+*/
+SELECT add_tsvector_column('text_search_vector', 'askbot_thread');
+COMMIT;
+BEGIN;
+SELECT add_tsvector_column('text_search_vector', 'askbot_post');
+COMMIT;
+BEGIN;
+SELECT add_tsvector_column('title_search_vector', 'askbot_thread');
+COMMIT;
+BEGIN;
+
+/* populate tsvectors with data */
+-- post tsvectors
+UPDATE askbot_post set text_search_vector = get_post_tsv(text, post_type, language_code) WHERE post_type IN ('answer', 'comment', 'question');
+UPDATE askbot_post as q SET text_search_vector = text_search_vector ||
+ get_dependent_comments_tsv(q.id) WHERE post_type IN ('question', 'answer');
+--thread tsvector
+UPDATE askbot_thread SET text_search_vector = get_thread_tsv(title, tagnames, language_code);
+UPDATE askbot_thread as t SET text_search_vector = text_search_vector ||
+ get_dependent_answers_tsv(t.id, t.language_code) ||
+ get_thread_question_tsv(t.id, t.language_code);
+UPDATE askbot_thread SET title_search_vector = get_thread_tsv(title, tagnames, language_code);
+
+/* one trigger per table for tsv updates */
+
+/* set up update triggers */
+CREATE OR REPLACE FUNCTION thread_update_trigger() RETURNS trigger AS
+$$
+DECLARE
+ title_tsv tsvector;
+BEGIN
+ title_tsv = get_thread_tsv(new.title, new.tagnames, new.language_code);
+ new.title_search_vector = title_tsv;
+ new.text_search_vector = new.text_search_vector || title_tsv;
+ RETURN new;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER thread_search_vector_update_trigger
+BEFORE UPDATE ON askbot_thread FOR EACH ROW EXECUTE PROCEDURE thread_update_trigger();
+
+CREATE OR REPLACE FUNCTION thread_insert_trigger() RETURNS trigger AS
+$$
+BEGIN
+ new.text_search_vector = get_thread_tsv(new.title, new.tagnames, new.language_code);
+ new.title_search_vector = new.text_search_vector;
+ RETURN new;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER thread_search_vector_insert_trigger
+BEFORE INSERT ON askbot_thread FOR EACH ROW EXECUTE PROCEDURE thread_insert_trigger();
+
+/* post trigger */
+CREATE OR REPLACE FUNCTION post_trigger() RETURNS trigger AS
+$$
+BEGIN
+ IF new.post_type = 'question' OR new.post_type = 'answer' THEN
+ new.text_search_vector = get_post_tsv(
+ new.text,
+ new.post_type,
+ new.language_code
+ );
+ UPDATE askbot_thread SET text_search_vector=text_search_vector ||
+ new.text_search_vector WHERE id=new.thread_id;
+ ELSIF new.post_type = 'comment' THEN
+ new.text_search_vector = get_post_tsv(
+ new.text,
+ 'comment',
+ new.language_code
+ );
+ UPDATE askbot_post SET text_search_vector=text_search_vector ||
+ new.text_search_vector WHERE id=new.parent_id;
+ END IF;
+ return new;
+END;
+$$ LANGUAGE plpgsql;
+CREATE TRIGGER post_search_vector_update_trigger
+BEFORE INSERT OR UPDATE ON askbot_post FOR EACH ROW EXECUTE PROCEDURE post_trigger();
+
+COMMIT;
+BEGIN;
+
+DROP INDEX IF EXISTS askbot_search_idx;
+CREATE INDEX askbot_search_idx ON askbot_thread USING gin(text_search_vector);
diff --git a/askbot/search/postgresql/thread_and_post_models_27112012.plsql b/askbot/search/postgresql/thread_and_post_models_27112012.plsql
new file mode 100644
index 00000000..9c328670
--- /dev/null
+++ b/askbot/search/postgresql/thread_and_post_models_27112012.plsql
@@ -0,0 +1,240 @@
+/* function testing for existence of a column in a table
+ if table does not exists, function will return "false" */
+CREATE OR REPLACE FUNCTION column_exists(colname text, tablename text)
+RETURNS boolean AS
+$$
+DECLARE
+ q text;
+ onerow record;
+BEGIN
+
+ q = 'SELECT attname FROM pg_attribute WHERE attrelid = ( SELECT oid FROM pg_class WHERE relname = '''||tablename||''') AND attname = '''||colname||'''';
+
+ FOR onerow IN EXECUTE q LOOP
+ RETURN true;
+ END LOOP;
+
+ RETURN false;
+END;
+$$ LANGUAGE plpgsql;
+
+/* function adding tsvector column to table if it does not exists */
+CREATE OR REPLACE FUNCTION add_tsvector_column(colname text, tablename text)
+RETURNS boolean AS
+$$
+DECLARE
+ q text;
+BEGIN
+ IF NOT column_exists(colname, tablename) THEN
+ q = 'ALTER TABLE ' || tablename || ' ADD COLUMN ' || colname || ' tsvector';
+ EXECUTE q;
+ RETURN true;
+ ELSE
+ q = 'UPDATE ' || tablename || ' SET ' || colname || '=NULL';
+ EXECUTE q;
+ RETURN false;
+ END IF;
+END;
+$$ LANGUAGE plpgsql;
+
+/* aggregate function that concatenates tsvectors */
+CREATE OR REPLACE FUNCTION tsv_add(tsv1 tsvector, tsv2 tsvector)
+RETURNS tsvector AS
+$$
+BEGIN
+ RETURN tsv1 || tsv2;
+END;
+$$ LANGUAGE plpgsql;
+
+CREATE OR REPLACE FUNCTION setup_aggregates() RETURNS boolean AS
+$$
+DECLARE
+ onerow record;
+BEGIN
+ FOR onerow IN SELECT * FROM pg_proc WHERE proname = 'concat_tsvectors' AND proisagg LOOP
+ DROP AGGREGATE concat_tsvectors(tsvector);
+ END LOOP;
+ CREATE AGGREGATE concat_tsvectors (
+ BASETYPE = tsvector,
+ SFUNC = tsv_add,
+ STYPE = tsvector,
+ INITCOND = ''
+ );
+ RETURN true;
+END;
+$$ LANGUAGE plpgsql;
+
+SELECT setup_aggregates();
+
+/* calculates text search vector for the individual thread row
+DOES not include question body post, answers or comments */
+CREATE OR REPLACE FUNCTION get_thread_tsv(title text, tagnames text)
+RETURNS tsvector AS
+$$
+BEGIN
+ /* todo add weight depending on votes */
+ RETURN setweight(to_tsvector('english', coalesce(title, '')), 'A') ||
+ setweight(to_tsvector('english', coalesce(tagnames, '')), 'A');
+END;
+$$ LANGUAGE plpgsql;
+
+/* calculates text seanch vector for the individual question row */
+CREATE OR REPLACE FUNCTION get_post_tsv(text text, post_type text)
+RETURNS tsvector AS
+$$
+BEGIN
+ /* todo adjust weights to reflect votes */
+ IF post_type='question' THEN
+ RETURN setweight(to_tsvector('english', coalesce(text, '')), 'B');
+ ELSIF post_type='answer' THEN
+ /* todo reflect whether the answer acepted or has many points */
+ RETURN setweight(to_tsvector('english', coalesce(text, '')), 'C');
+ ELSIF post_type='comment' THEN
+ RETURN setweight(to_tsvector('english', coalesce(text, '')), 'D');
+ ELSE
+ RETURN to_tsvector('');
+ END IF;
+END;
+$$ LANGUAGE plpgsql;
+
+/* calculates text search vector for the question body part by thread id
+here we extract question title and the text by thread_id and then
+calculate the text search vector. In the future question
+title will be moved to the askbot_thread table and this function
+will be simpler.
+*/
+CREATE OR REPLACE FUNCTION get_thread_question_tsv(thread_id integer)
+RETURNS tsvector AS
+$$
+DECLARE
+ query text;
+ onerow record;
+BEGIN
+ query = 'SELECT text FROM askbot_post WHERE thread_id=' || thread_id ||
+ ' AND post_type=''question'' AND deleted=false';
+ FOR onerow in EXECUTE query LOOP
+ RETURN get_post_tsv(onerow.text, 'question');
+ END LOOP;
+ RETURN to_tsvector('');
+END;
+$$ LANGUAGE plpgsql;
+
+DROP FUNCTION IF EXISTS get_dependent_comments_tsv(object_id integer, tablename text);
+CREATE OR REPLACE FUNCTION get_dependent_comments_tsv(parent_id integer)
+RETURNS tsvector AS
+$$
+DECLARE
+ query text;
+ onerow record;
+BEGIN
+ query = 'SELECT concat_tsvectors(text_search_vector) FROM askbot_post' ||
+ ' WHERE parent_id=' || parent_id ||
+ ' AND post_type=''comment'' AND deleted=false';
+ FOR onerow IN EXECUTE query LOOP
+ RETURN onerow.concat_tsvectors;
+ END LOOP;
+ RETURN to_tsvector('');
+END;
+$$ LANGUAGE plpgsql;
+
+DROP FUNCTION IF EXISTS get_dependent_answers_tsv(question_id integer);
+CREATE OR REPLACE FUNCTION get_dependent_answers_tsv(thread_id integer)
+RETURNS tsvector AS
+$$
+DECLARE
+ query text;
+ onerow record;
+BEGIN
+ query = 'SELECT concat_tsvectors(text_search_vector) ' ||
+ 'FROM askbot_post WHERE thread_id = ' || thread_id ||
+ ' AND deleted=false';
+ FOR onerow IN EXECUTE query LOOP
+ RETURN onerow.concat_tsvectors;
+ END LOOP;
+ RETURN to_tsvector('');
+END;
+$$ LANGUAGE plpgsql;
+
+/* create tsvector columns in the content tables
+ need to isolate these into own transactions, b/c of a weird mix
+ of triggers/update and alter table statements
+*/
+SELECT add_tsvector_column('text_search_vector', 'askbot_thread');
+COMMIT;
+BEGIN;
+SELECT add_tsvector_column('text_search_vector', 'askbot_post');
+COMMIT;
+BEGIN;
+SELECT add_tsvector_column('title_search_vector', 'askbot_thread');
+COMMIT;
+BEGIN;
+
+/* populate tsvectors with data */
+-- post tsvectors
+UPDATE askbot_post set text_search_vector = get_post_tsv(text, 'comment') WHERE post_type='comment';
+UPDATE askbot_post SET text_search_vector = get_post_tsv(text, 'answer') WHERE post_type='answer';
+UPDATE askbot_post SET text_search_vector = get_post_tsv(text, 'question') WHERE post_type='question';
+UPDATE askbot_post as q SET text_search_vector = text_search_vector ||
+ get_dependent_comments_tsv(q.id) WHERE post_type IN ('question', 'answer');
+
+--thread tsvector
+UPDATE askbot_thread SET text_search_vector = get_thread_tsv(title, tagnames);
+UPDATE askbot_thread as t SET text_search_vector = text_search_vector ||
+ get_dependent_answers_tsv(t.id) ||
+ get_thread_question_tsv(t.id);
+UPDATE askbot_thread SET title_search_vector = get_thread_tsv(title, tagnames);
+
+/* one trigger per table for tsv updates */
+
+/* set up update triggers */
+CREATE OR REPLACE FUNCTION thread_update_trigger() RETURNS trigger AS
+$$
+DECLARE
+ title_tsv tsvector;
+BEGIN
+ title_tsv = get_thread_tsv(new.title, new.tagnames);
+ new.title_search_vector = title_tsv;
+ new.text_search_vector = title_tsv ||
+ get_thread_question_tsv(new.id) ||
+ get_dependent_answers_tsv(new.id);
+ RETURN new;
+END;
+$$ LANGUAGE plpgsql;
+DROP TRIGGER IF EXISTS thread_search_vector_update_trigger on askbot_thread;
+CREATE TRIGGER thread_search_vector_update_trigger
+BEFORE UPDATE ON askbot_thread FOR EACH ROW EXECUTE PROCEDURE thread_update_trigger();
+
+CREATE OR REPLACE FUNCTION thread_insert_trigger() RETURNS trigger AS
+$$
+BEGIN
+ new.text_search_vector = get_thread_tsv(new.title, new.tagnames);
+ RETURN new;
+END;
+$$ LANGUAGE plpgsql;
+DROP TRIGGER IF EXISTS thread_search_vector_insert_trigger on askbot_thread;
+CREATE TRIGGER thread_search_vector_insert_trigger
+BEFORE INSERT ON askbot_thread FOR EACH ROW EXECUTE PROCEDURE thread_insert_trigger();
+
+/* post trigger */
+CREATE OR REPLACE FUNCTION post_trigger() RETURNS trigger AS
+$$
+BEGIN
+ IF new.post_type = 'question' THEN
+ new.text_search_vector = get_post_tsv(new.text, 'question') ||
+ get_dependent_comments_tsv(new.id);
+ ELSIF new.post_type = 'answer' THEN
+ new.text_search_vector = get_post_tsv(new.text, 'answer') ||
+ get_dependent_comments_tsv(new.id);
+ ELSIF new.post_type = 'comment' THEN
+ new.text_search_vector = get_post_tsv(new.text, 'comment');
+ END IF;
+ UPDATE askbot_thread SET id=new.thread_id WHERE id=new.thread_id;
+ return new;
+END;
+$$ LANGUAGE plpgsql;
+DROP TRIGGER IF EXISTS post_search_vector_update_trigger on askbot_post;
+CREATE TRIGGER post_search_vector_update_trigger
+BEFORE INSERT OR UPDATE ON askbot_post FOR EACH ROW EXECUTE PROCEDURE post_trigger();
+
+DROP INDEX IF EXISTS askbot_search_idx;
+CREATE INDEX askbot_search_idx ON askbot_thread USING gin(text_search_vector);
diff --git a/askbot/search/postgresql/user_profile_search_02262013.plsql b/askbot/search/postgresql/user_profile_search_02262013.plsql
new file mode 100644
index 00000000..fc4e7509
--- /dev/null
+++ b/askbot/search/postgresql/user_profile_search_02262013.plsql
@@ -0,0 +1,102 @@
+/*
+Script depends on functions defined for general askbot full text search.
+to_tsvector(), add_tsvector_column()
+
+calculates text search vector for the user profile
+the searched fields are:
+1) user name
+2) user profile
+3) group names - for groups to which user belongs
+*/
+CREATE OR REPLACE FUNCTION get_auth_user_tsv(user_id integer)
+RETURNS tsvector AS
+$$
+DECLARE
+ group_query text;
+ user_query text;
+ onerow record;
+ tsv tsvector;
+BEGIN
+ group_query =
+ 'SELECT user_group.name as group_name ' ||
+ 'FROM auth_group AS user_group ' ||
+ 'INNER JOIN auth_user_groups AS gm ' ||
+ 'ON gm.user_id= ' || user_id || ' AND gm.group_id=user_group.id';
+
+ tsv = to_tsvector('');
+ FOR onerow in EXECUTE group_query LOOP
+ tsv = tsv || to_tsvector(onerow.group_name);
+ END LOOP;
+
+ user_query = 'SELECT about, username, real_name, email FROM auth_user WHERE id=' || user_id;
+ FOR onerow in EXECUTE user_query LOOP
+ tsv = tsv ||
+ to_tsvector(onerow.username) ||
+ to_tsvector(onerow.real_name) ||
+ to_tsvector(onerow.email) ||
+ to_tsvector(onerow.about);
+ END LOOP;
+ RETURN tsv;
+END;
+$$ LANGUAGE plpgsql;
+
+/* create tsvector columns in the content tables */
+SELECT add_tsvector_column('text_search_vector', 'auth_user');
+
+/* populate tsvectors with data */
+UPDATE auth_user SET text_search_vector = get_auth_user_tsv(id);
+
+/* one trigger per table for tsv updates */
+
+/* set up auth_user triggers */
+CREATE OR REPLACE FUNCTION auth_user_tsv_update_handler()
+RETURNS trigger AS
+$$
+BEGIN
+ new.text_search_vector = get_auth_user_tsv(new.id);
+ RETURN new;
+END;
+$$ LANGUAGE plpgsql;
+DROP TRIGGER IF EXISTS auth_user_tsv_update_trigger ON auth_user;
+
+CREATE TRIGGER auth_user_tsv_update_trigger
+BEFORE INSERT OR UPDATE ON auth_user
+FOR EACH ROW EXECUTE PROCEDURE auth_user_tsv_update_handler();
+
+/* group membership trigger - reindex users when group membership
+ * changes */
+CREATE OR REPLACE FUNCTION group_membership_tsv_update_handler()
+RETURNS trigger AS
+$$
+DECLARE
+ tsv tsvector;
+ user_query text;
+BEGIN
+ IF (TG_OP = 'INSERT') THEN
+ user_query = 'UPDATE auth_user SET username=username WHERE ' ||
+ 'id=' || new.user_id;
+ ELSE
+ user_query = 'UPDATE auth_user SET username=username WHERE ' ||
+ 'id=' || old.user_id;
+ END IF;
+ /* just trigger the tsv update on user */
+ EXECUTE user_query;
+ RETURN NULL;
+END;
+$$ LANGUAGE plpgsql;
+
+DROP TRIGGER IF EXISTS group_membership_tsv_update_trigger
+ON auth_user_groups;
+
+CREATE TRIGGER group_membership_tsv_update_trigger
+AFTER INSERT OR DELETE
+ON auth_user_groups
+FOR EACH ROW EXECUTE PROCEDURE group_membership_tsv_update_handler();
+
+/* todo: whenever group name changes - also
+ * reindex users belonging to the group */
+
+DROP INDEX IF EXISTS auth_user_search_idx;
+
+CREATE INDEX auth_user_search_idx ON auth_user
+USING gin(text_search_vector);
diff --git a/askbot/search/state_manager.py b/askbot/search/state_manager.py
index a02f1577..7b6b746c 100644
--- a/askbot/search/state_manager.py
+++ b/askbot/search/state_manager.py
@@ -170,10 +170,16 @@ class SearchState(object):
SAFE_CHARS = const.TAG_SEP + '_+.-'
def query_string(self):
+ """returns part of the url to the main page,
+ responsible to display the full text search results,
+ taking into account sort method, selected scope
+ and search tags"""
+
lst = [
'scope:' + self.scope,
'sort:' + self.sort
]
+
if self.query:
lst.append('query:' + urllib.quote(smart_str(self.query), safe=self.SAFE_CHARS))
if self.tags:
diff --git a/askbot/setup_templates/settings.py b/askbot/setup_templates/settings.py
index b43b2b50..237a1280 100644
--- a/askbot/setup_templates/settings.py
+++ b/askbot/setup_templates/settings.py
@@ -87,8 +87,8 @@ SECRET_KEY = 'sdljdfjkldsflsdjkhsjkldgjlsdgfs s '
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
- 'django.template.loaders.filesystem.load_template_source',
- 'django.template.loaders.app_directories.load_template_source',
+ 'django.template.loaders.filesystem.Loader',
+ 'django.template.loaders.app_directories.Loader',
#below is askbot stuff for this tuple
#'askbot.skins.loaders.load_template_source', #changed due to bug 97
'askbot.skins.loaders.filesystem_load_template_source',
@@ -144,7 +144,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'askbot.context.application_settings',
#'django.core.context_processors.i18n',
'askbot.user_messages.context_processors.user_messages',#must be before auth
- 'django.core.context_processors.auth', #this is required for admin
+ 'django.contrib.auth.context_processors.auth', #this is required for admin
'django.core.context_processors.csrf', #necessary for csrf protection
)
diff --git a/askbot/setup_templates/settings.py.mustache b/askbot/setup_templates/settings.py.mustache
index aa153435..bd77e82e 100644
--- a/askbot/setup_templates/settings.py.mustache
+++ b/askbot/setup_templates/settings.py.mustache
@@ -19,12 +19,16 @@ ADMINS = (
MANAGERS = ADMINS
-DATABASE_ENGINE = 'postgresql_psycopg2' # only postgres (>8.3) and mysql are supported so far others have not been tested yet
-DATABASE_NAME = '{{database_name}}' # Or path to database file if using sqlite3.
-DATABASE_USER = '{{database_user}}' # Not used with sqlite3.
-DATABASE_PASSWORD = '{{database_password}}' # Not used with sqlite3.
-DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
-DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.{{database_engine}}', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+ 'NAME': '{{database_name}}', # Or path to database file if using sqlite3.
+ 'USER': '{{database_user}}', # Not used with sqlite3.
+ 'PASSWORD': '{{database_password}}', # Not used with sqlite3.
+ 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
+ 'PORT': '', # Set to empty string for default. Not used with sqlite3.
+ }
+}
#outgoing mail server settings
SERVER_EMAIL = ''
@@ -83,14 +87,13 @@ STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static')
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'
# Make up some unique string, and don't share it with anybody.
-SECRET_KEY = 'sdljdfjkldsflsdjkhsjkldgjlsdgfs s '
+SECRET_KEY = '{{secret_key}}'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
- 'django.template.loaders.filesystem.load_template_source',
- 'django.template.loaders.app_directories.load_template_source',
- #below is askbot stuff for this tuple
- 'askbot.skins.loaders.filesystem_load_template_source',
+ 'askbot.skins.loaders.Loader',
+ 'django.template.loaders.app_directories.Loader',
+ 'django.template.loaders.filesystem.Loader',
#'django.template.loaders.eggs.load_template_source',
)
@@ -143,7 +146,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
'askbot.context.application_settings',
#'django.core.context_processors.i18n',
'askbot.user_messages.context_processors.user_messages',#must be before auth
- 'django.core.context_processors.auth', #this is required for admin
+ '{{ auth_context_processor }}', #this is required for the admin app
'django.core.context_processors.csrf', #necessary for csrf protection
)
@@ -175,6 +178,7 @@ INSTALLED_APPS = (
'djkombu',
'followit',
'tinymce',
+ 'group_messaging',
#'avatar',#experimental use git clone git://github.com/ericflo/django-avatar.git$
)
@@ -276,3 +280,8 @@ TINYMCE_DEFAULT_CONFIG = {
#delayed notifications, time in seconds, 15 mins by default
NOTIFICATION_DELAY_TIME = 60 * 15
+
+GROUP_MESSAGING = {
+ 'BASE_URL_GETTER_FUNCTION': 'askbot.models.user_get_profile_url',
+ 'BASE_URL_PARAMS': {'section': 'messages', 'sort': 'inbox'}
+}
diff --git a/askbot/setup_templates/urls.py b/askbot/setup_templates/urls.py
index 8c92f6d1..35f1c5b3 100644
--- a/askbot/setup_templates/urls.py
+++ b/askbot/setup_templates/urls.py
@@ -1,18 +1,33 @@
"""
main url configuration file for the askbot site
"""
-from django.conf.urls.defaults import patterns, include, handler404, handler500, url
from django.conf import settings
-
+from django.conf.urls.defaults import handler404
+from django.conf.urls.defaults import handler500
+from django.conf.urls.defaults import include
+from django.conf.urls.defaults import patterns
+from django.conf.urls.defaults import url
+from django.conf import settings
from django.contrib import admin
+
admin.autodiscover()
-urlpatterns = patterns('',
- (r'%s' % settings.ASKBOT_URL, include('askbot.urls')),
+if getattr(settings, 'ASKBOT_MULTILINGUAL', False) == True:
+ from django.conf.urls.i18n import i18n_patterns
+ urlpatterns = i18n_patterns('',
+ (r'%s' % settings.ASKBOT_URL, include('askbot.urls'))
+ )
+else:
+ urlpatterns = patterns('',
+ (r'%s' % settings.ASKBOT_URL, include('askbot.urls'))
+ )
+
+urlpatterns += patterns('',
(r'^admin/', include(admin.site.urls)),
#(r'^cache/', include('keyedcache.urls')), - broken views disable for now
(r'^settings/', include('askbot.deps.livesettings.urls')),
(r'^followit/', include('followit.urls')),
+ (r'^tinymce/', include('tinymce.urls')),
(r'^robots.txt$', include('robots.urls')),
url( # TODO: replace with django.conf.urls.static ?
r'^%s(?P<path>.*)$' % settings.MEDIA_URL[1:],
diff --git a/askbot/skins/loaders.py b/askbot/skins/loaders.py
index fc680f00..50276f34 100644
--- a/askbot/skins/loaders.py
+++ b/askbot/skins/loaders.py
@@ -1,6 +1,7 @@
import os.path
-from django.template.loaders import filesystem
+from django.template.loader import BaseLoader
from django.template import RequestContext
+from django.template import TemplateDoesNotExist
from django.http import HttpResponse
from django.utils import translation
from django.conf import settings as django_settings
@@ -22,27 +23,6 @@ template.add_to_builtins('askbot.templatetags.extra_filters_jinja')
#here it is ignored because it is assumed that we won't use unicode paths
ASKBOT_SKIN_COLLECTION_DIR = os.path.dirname(__file__)
-#changed the name from load_template_source
-def filesystem_load_template_source(name, dirs=None):
- """Django template loader
- """
-
- if dirs is None:
- dirs = (ASKBOT_SKIN_COLLECTION_DIR, )
- else:
- dirs += (ASKBOT_SKIN_COLLECTION_DIR, )
-
- try:
- #todo: move this to top after splitting out get_skin_dirs()
- tname = os.path.join(askbot_settings.ASKBOT_DEFAULT_SKIN, 'templates', name)
- return filesystem.load_template_source(tname, dirs)
- except:
- tname = os.path.join('default', 'templates', name)
- return filesystem.load_template_source(tname, dirs)
-filesystem_load_template_source.is_usable = True
-#added this for backward compatbility
-load_template_source = filesystem_load_template_source
-
class SkinEnvironment(CoffinEnvironment):
"""Jinja template environment
that loads templates from askbot skins
@@ -103,8 +83,9 @@ def get_skin(request = None):
for a given request (request var is not used at this time)"""
return SKINS[askbot_settings.ASKBOT_DEFAULT_SKIN]
-def get_template(template, request = None):
- """retreives template for the skin
+def get_askbot_template(template, request = None):
+ """
+ retreives template for the skin
request variable will be used in the future to set
template according to the user preference or admins preference
@@ -117,21 +98,22 @@ def get_template(template, request = None):
def render_into_skin_as_string(template, data, request):
context = RequestContext(request, data)
- template = get_template(template, request)
+ template = get_askbot_template(template, request)
return template.render(context)
-def render_into_skin(template, data, request, mimetype = 'text/html'):
- """in the future this function will be able to
- switch skin depending on the site administrator/user selection
- right now only admins can switch
- """
- return HttpResponse(
- render_into_skin_as_string(template, data, request),
- mimetype=mimetype
- )
-
def render_text_into_skin(text, data, request):
context = RequestContext(request, data)
skin = get_skin(request)
template = skin.from_string(text)
return template.render(context)
+
+class Loader(BaseLoader):
+ """skins template loader for Django > 1.2
+ todo: verify that this actually follows django's convention correctly
+ """
+ is_usable = True
+ def load_template(self, template_name, template_dirs = None):
+ try:
+ return get_askbot_template(template_name), template_name
+ except TemplateNotFound:
+ raise TemplateDoesNotExist
diff --git a/askbot/skins/utils.py b/askbot/skins/utils.py
index f0e149d0..b04f9bda 100644
--- a/askbot/skins/utils.py
+++ b/askbot/skins/utils.py
@@ -169,20 +169,20 @@ def get_media_url(url, ignore_missing = False):
#print after - before
return url
-def update_media_revision(skin = None):
+def update_media_revision(skin=None):
"""update skin media revision number based on the contents
of the skin media directory"""
from askbot.conf import settings as askbot_settings
resource_revision = askbot_settings.MEDIA_RESOURCE_REVISION
- if skin:
- if skin in get_skin_choices():
- skin_path = get_path_to_skin(skin)
- else:
- raise MediaNotFound('Skin %s not found' % skin)
+ skin = skin or askbot_settings.ASKBOT_DEFAULT_SKIN
+
+ if skin in get_available_skins().keys():
+ skin_path = get_path_to_skin(skin)
else:
- skin = 'default'
- skin_path = get_path_to_skin(askbot_settings.ASKBOT_DEFAULT_SKIN)
+ assert(skin != 'default')
+ msg = 'Skin "%s" not found. Please check ASKBOT_EXTRA_SKINS_DIR setting'
+ raise MediaNotFound(msg % skin)
media_dirs = [
os.path.join(skin_path, 'media'),
diff --git a/askbot/startup_procedures.py b/askbot/startup_procedures.py
index 706e19ad..f3597820 100644
--- a/askbot/startup_procedures.py
+++ b/askbot/startup_procedures.py
@@ -7,12 +7,13 @@ question: why not run these from askbot/__init__.py?
the main function is run_startup_tests
"""
-import sys
+import askbot
+import django
import os
import re
-import urllib
-import askbot
import south
+import sys
+import urllib
from django.db import transaction, connection
from django.conf import settings as django_settings
from django.core.exceptions import ImproperlyConfigured
@@ -44,7 +45,7 @@ class AskbotConfigError(ImproperlyConfigured):
def askbot_warning(line):
"""prints a warning with the nice header, but does not quit"""
- print >> sys.stderr, PREAMBLE + '\n' + line
+ print >> sys.stderr, line
def print_errors(error_messages, header = None, footer = None):
"""if there is one or more error messages,
@@ -210,14 +211,28 @@ def test_encoding():
def test_template_loader():
"""Sends a warning if you have an old style template
loader that used to send a warning"""
- old_template_loader = 'askbot.skins.loaders.load_template_source'
- if old_template_loader in django_settings.TEMPLATE_LOADERS:
- raise AskbotConfigError(
- "\nPlease change: \n"
- "'askbot.skins.loaders.load_template_source', to\n"
- "'askbot.skins.loaders.filesystem_load_template_source',\n"
- "in the TEMPLATE_LOADERS of your settings.py file"
+ old_loaders = (
+ 'askbot.skins.loaders.load_template_source',
+ 'askbot.skins.loaders.filesystem_load_template_source',
+ )
+ errors = list()
+ for loader in old_loaders:
+ if loader in django_settings.TEMPLATE_LOADERS:
+ errors.append(
+ 'remove "%s" from the TEMPLATE_LOADERS setting' % loader
+ )
+
+ current_loader = 'askbot.skins.loaders.Loader'
+ if current_loader not in django_settings.TEMPLATE_LOADERS:
+ errors.append(
+ 'add "%s" to the beginning of the TEMPLATE_LOADERS' % current_loader
+ )
+ elif django_settings.TEMPLATE_LOADERS[0] != current_loader:
+ errors.append(
+ '"%s" must be the first element of TEMPLATE_LOADERS' % current_loader
)
+
+ print_errors(errors)
def test_celery():
"""Tests celery settings
@@ -348,7 +363,6 @@ def test_new_skins():
def test_staticfiles():
"""tests configuration of the staticfiles app"""
errors = list()
- import django
django_version = django.VERSION
if django_version[0] == 1 and django_version[1] < 3:
staticfiles_app_name = 'staticfiles'
@@ -458,7 +472,6 @@ def test_staticfiles():
' python manage.py collectstatic\n'
)
-
print_errors(errors)
if django_settings.STATICFILES_STORAGE == \
'django.contrib.staticfiles.storage.StaticFilesStorage':
@@ -686,6 +699,143 @@ def test_longerusername():
errors.append('run "python manage.py migrate longerusername"')
print_errors(errors)
+def test_template_context_processors():
+ """makes sure that all necessary template context processors
+ are in the settings.py"""
+
+ required_processors = [
+ 'django.core.context_processors.request',
+ 'askbot.context.application_settings',
+ 'askbot.user_messages.context_processors.user_messages',
+ 'django.core.context_processors.csrf',
+ ]
+ old_auth_processor = 'django.core.context_processors.auth'
+ new_auth_processor = 'django.contrib.auth.context_processors.auth'
+
+ invalid_processors = list()
+ if django.VERSION[1] <= 3:
+ required_processors.append(old_auth_processor)
+ if new_auth_processor in django_settings.TEMPLATE_CONTEXT_PROCESSORS:
+ invalid_processors.append(new_auth_processor)
+ elif django.VERSION[1] > 3:
+ required_processors.append(new_auth_processor)
+ if old_auth_processor in django_settings.TEMPLATE_CONTEXT_PROCESSORS:
+ invalid_processors.append(old_auth_processor)
+
+ missing_processors = list()
+ for processor in required_processors:
+ if processor not in django_settings.TEMPLATE_CONTEXT_PROCESSORS:
+ missing_processors.append(processor)
+
+ errors = list()
+ if invalid_processors:
+ message = 'remove from TEMPLATE_CONTEXT_PROCESSORS in settings.py:\n'
+ message += format_as_text_tuple_entries(invalid_processors)
+ errors.append(message)
+
+ if missing_processors:
+ message = 'add to TEMPLATE_CONTEXT_PROCESSORS in settings.py:\n'
+ message += format_as_text_tuple_entries(missing_processors)
+ errors.append(message)
+
+ print_errors(errors)
+
+
+def test_cache_backend():
+ """prints a warning if cache backend is disabled or per-process"""
+ if django.VERSION[1] > 2:
+ backend = django_settings.CACHES['default']['BACKEND']
+ else:
+ backend = django_settings.CACHE_BACKEND
+
+ errors = list()
+ if backend.strip() == '' or 'dummy' in backend:
+ message = """Please enable at least a "locmem" cache (for a single process server).
+If you need to run > 1 server process, set up some production caching system,
+such as redis or memcached"""
+ errors.append(message)
+
+ if 'locmem' in backend:
+ message = """WARNING!!! You are using a 'locmem' (local memory) caching backend,
+which is OK for a low volume site running on a single-process server.
+For a multi-process configuration it is neccessary to have a production
+cache system, such as redis or memcached.
+
+With local memory caching and multi-process setup you might intermittently
+see outdated content on your site.
+"""
+ askbot_warning(message)
+
+
+def test_group_messaging():
+ """tests correctness of the "group_messaging" app configuration"""
+ errors = list()
+ if 'group_messaging' not in django_settings.INSTALLED_APPS:
+ errors.append("add to the INSTALLED_APPS:\n'group_messaging'")
+
+ settings_sample = ("GROUP_MESSAGING = {\n"
+ " 'BASE_URL_GETTER_FUNCTION': 'askbot.models.user_get_profile_url',\n"
+ " 'BASE_URL_PARAMS': {'section': 'messages', 'sort': 'inbox'}\n"
+ "}")
+
+ settings = getattr(django_settings, 'GROUP_MESSAGING', {})
+ if settings:
+ url_params = settings.get('BASE_URL_PARAMS', {})
+ have_wrong_params = not (
+ url_params.get('section', None) == 'messages' and \
+ url_params.get('sort', None) == 'inbox'
+ )
+ url_getter = settings.get('BASE_URL_GETTER_FUNCTION', None)
+ if url_getter != 'askbot.models.user_get_profile_url' or have_wrong_params:
+ errors.append(
+ "make setting 'GROUP_MESSAGING to be exactly:\n" + settings_sample
+ )
+
+ url_params = settings.get('BASE_URL_PARAMS', None)
+ else:
+ errors.append('add this to your settings.py:\n' + settings_sample)
+
+ if errors:
+ print_errors(errors)
+
+
+def test_secret_key():
+ key = django_settings.SECRET_KEY
+ if key.strip() == '':
+ print_errors(['please create a random SECRET_KEY setting',])
+ elif key == 'sdljdfjkldsflsdjkhsjkldgjlsdgfs s ':
+ print_errors([
+ 'Please change your SECRET_KEY setting, the current is not secure'
+ ])
+
+
+def test_multilingual():
+ is_multilang = getattr(django_settings, 'ASKBOT_MULTILINGUAL', False)
+
+ errors = list()
+
+ django_version = django.VERSION
+ if is_multilang and django_version[0] == 1 and django_version[1] < 4:
+ errors.append('ASKBOT_MULTILINGUAL=True works only with django >= 1.4')
+
+ if is_multilang:
+ middleware = 'django.middleware.locale.LocaleMiddleware'
+ if middleware not in django_settings.MIDDLEWARE_CLASSES:
+ errors.append(
+ "add 'django.middleware.locale.LocaleMiddleware' to your MIDDLEWARE_CLASSES "
+ "if you want a multilingual setup"
+ )
+
+ trans_url = getattr(django_settings, 'ASKBOT_TRANSLATE_URL', False)
+ if is_multilang and trans_url:
+ errors.append(
+ 'Please set ASKBOT_TRANSLATE_URL to False, the "True" option '
+ 'is currently not supported due to a bug in django'
+ )
+
+ print_errors(errors)
+
+
def run_startup_tests():
"""function that runs
all startup tests, mainly checking settings config so far
@@ -700,12 +850,17 @@ def run_startup_tests():
test_middleware()
test_celery()
#test_csrf_cookie_domain()
+ test_template_context_processors()
test_tinymce()
test_staticfiles()
test_new_skins()
test_longerusername()
test_avatar()
+ test_group_messaging()
+ test_multilingual()
test_haystack()
+ test_cache_backend()
+ test_secret_key()
settings_tester = SettingsTester({
'CACHE_MIDDLEWARE_ANONYMOUS_ONLY': {
'value': True,
diff --git a/askbot/tasks.py b/askbot/tasks.py
index 5cdd59b7..92cd9a1d 100644
--- a/askbot/tasks.py
+++ b/askbot/tasks.py
@@ -24,6 +24,7 @@ import uuid
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 celery.decorators import task
from askbot.conf import settings as askbot_settings
@@ -80,7 +81,6 @@ def notify_author_of_published_revision_celery_task(revision):
}
#load the template
- from askbot.skins.loaders import get_template
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}
@@ -98,11 +98,12 @@ def notify_author_of_published_revision_celery_task(revision):
def record_post_update_celery_task(
post_id,
post_content_type_id,
- newly_mentioned_user_id_list = None,
- updated_by_id = None,
- timestamp = None,
- created = False,
- diff = None,
+ newly_mentioned_user_id_list=None,
+ updated_by_id=None,
+ suppress_email=False,
+ timestamp=None,
+ created=False,
+ diff=None,
):
#reconstitute objects from the database
updated_by = User.objects.get(id=updated_by_id)
@@ -124,6 +125,7 @@ def record_post_update_celery_task(
updated_by=updated_by,
notify_sets=notify_sets,
activity_type=activity_type,
+ suppress_email=suppress_email,
timestamp=timestamp,
diff=diff
)
@@ -152,11 +154,12 @@ def record_question_visit(
if update_view_count:
question_post.thread.increase_view_count()
- user = User.objects.get(id=user_id)
-
- if user.is_anonymous():
+ #we do not track visits per anon user
+ if user_id is None:
return
+ user = User.objects.get(id=user_id)
+
#2) question view count per user and clear response displays
#user = User.objects.get(id = user_id)
if user.is_authenticated():
@@ -191,7 +194,6 @@ def send_instant_notifications_about_activity_in_post(
return
#calculate some variables used in the loop below
- from askbot.skins.loaders import get_template
update_type_map = const.RESPONSE_ACTIVITY_TYPE_MAP_FOR_TEMPLATES
update_type = update_type_map[update_activity.activity_type]
origin_post = post.get_origin_post()
diff --git a/askbot/templates/404.html b/askbot/templates/404.html
index 158bfb94..565ff164 100644
--- a/askbot/templates/404.html
+++ b/askbot/templates/404.html
@@ -1,5 +1,44 @@
-{% load extra_tags %}
-{% include_jinja "404.jinja.html" request %}
-{% comment %}
-this one has to be a django template because of use of default hander404
-{% endcomment %}
+{% extends "one_column_body.html" %}
+<!-- template 404.jinja.html -->
+{% block title %}{% spaceless %}{% trans %}Page not found{% endtrans %}{% endspaceless %}{% endblock %}
+{% block forestyle%}
+<style type="text/css">
+ form input { margin-right: 5px; }
+</style>
+{% endblock %}
+{% block content %}
+<h1>{% trans %}Page not found{% endtrans %}</h1>
+<div id="main-body">
+ <div style="padding:5px 0px 10px 0;line-height:25px;">
+ <h2>{% trans %}Sorry, could not find the page you requested.{% endtrans %}</h2>
+ <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 %}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 %}
+ <a href="{{feedback_site_url}}" target="_blank">{% trans %}report this problem{% endtrans %}</a></li>
+ </u>
+ </div>
+ <script type="text/javascript">
+ var GOOG_FIXURL_LANG = '{{ language_code }}';
+ 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 %}
+{% block endjs %}
+ <script type="text/javascript">
+ $().ready(function(){
+ $("#linkPrevious").bind("click", back=function(){history.go(-1);})
+ });
+ </script>
+{% endblock %}
+<!-- end template 404.jinja.html -->
diff --git a/askbot/templates/404.jinja.html b/askbot/templates/404.jinja.html
deleted file mode 100644
index 2da99646..00000000
--- a/askbot/templates/404.jinja.html
+++ /dev/null
@@ -1,44 +0,0 @@
-{% extends "one_column_body.html" %}
-<!-- template 404.jinja.html -->
-{% block title %}{% spaceless %}{% trans %}Page not found{% endtrans %}{% endspaceless %}{% endblock %}
-{% block forestyle%}
-<style type="text/css">
- form input { margin-right: 5px; }
-</style>
-{% endblock %}
-{% block content %}
-<h1>{% trans %}Page not found{% endtrans %}</h1>
-<div id="main-body">
- <div style="padding:5px 0px 10px 0;line-height:25px;">
- <h2>{% trans %}Sorry, could not find the page you requested.{% endtrans %}</h2>
- <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 %}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 %}
- <a href="{{feedback_site_url}}" target="_blank">{% trans %}report this problem{% endtrans %}</a></li>
- </u>
- </div>
- <script type="text/javascript">
- var GOOG_FIXURL_LANG = '{{settings.LANGUAGE_CODE}}';
- 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 %}
-{% block endjs %}
- <script type="text/javascript">
- $().ready(function(){
- $("#linkPrevious").bind("click", back=function(){history.go(-1);})
- });
- </script>
-{% endblock %}
-<!-- end template 404.jinja.html -->
diff --git a/askbot/templates/500.jinja.html b/askbot/templates/500.html
index 297ae736..297ae736 100644
--- a/askbot/templates/500.jinja.html
+++ b/askbot/templates/500.html
diff --git a/askbot/templates/answer_edit.html b/askbot/templates/answer_edit.html
index 20c0684d..f80715ec 100644
--- a/askbot/templates/answer_edit.html
+++ b/askbot/templates/answer_edit.html
@@ -25,15 +25,20 @@
editor_type = settings.EDITOR_TYPE
)
}}
+ <div class="answer-options">
{% if settings.WIKI_ON and answer.wiki == False %}
{{ macros.checkbox_in_div(form.wiki) }}
{% endif %}
+ {% if settings.ENABLE_EMAIL_ALERTS %}
+ {{ macros.checkbox_in_div(form.suppress_email) }}
+ {% endif %}
{% if settings.GROUPS_ENABLED and
request.user.is_authenticated() and
request.user.can_make_group_private_posts()
%}
{{ macros.checkbox_in_div(form.post_privately) }}
{% endif %}
+ </div>
<div class="after-editor">
<input id="edit_post_form_submit_button" type="submit" value="{% trans %}Save edit{% endtrans %}" class="submit" />&nbsp;
<input type="button" value="{% trans %}Cancel{% endtrans %}" class="submit" onclick="history.back(-1);" />
diff --git a/askbot/templates/ask.html b/askbot/templates/ask.html
index 27434f83..831b3a91 100644
--- a/askbot/templates/ask.html
+++ b/askbot/templates/ask.html
@@ -7,10 +7,37 @@
{% endblock %}
{# main contents of ask form is in the template input_bar #}
{% block sidebar %}
-{% include "widgets/question_edit_tips.html" %}
+ {% if settings.EDITOR_TYPE == 'markdown' %}
+ {% include "/widgets/markdown_help.html" %}
+ {% endif %}
{% endblock %}
{% block content %}
- {% include "widgets/ask_form.html" %}
+ <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 %}YYour email, %(email)s has not yet been validated. To post messages you must verify your email, please see <a href='%(email_validation_faq_url)s'>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>
+ </div>
+ {% include "widgets/ask_form.html" %}
{% endblock %}
{% block endjs %}
<script type='text/javascript' src='{{"/js/editor.js"|media}}'></script>
@@ -20,11 +47,6 @@
<script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script>
<script type='text/javascript' src='{{"/js/wmd/wmd.js"|media}}'></script>
{% endif %}
- <script type='text/javascript'>
- var sortMethod = undefined;//need for live_search
- var minSearchWordLength = {{settings.MIN_SEARCH_WORD_LENGTH}};
- </script>
- <script type='text/javascript' src='{{"/js/live_search_new_thread.js"|media}}'></script>
{% include "meta/editor_data.html" %}
{% if mandatory_tags %}
{% include "meta/mandatory_tags_js.html" %}
@@ -33,7 +55,6 @@
{% include "meta/category_tree_js.html" %}
{% endif %}
<script type='text/javascript'>
- askbot['urls']['api_get_questions'] = '{% url api_get_questions %}';
askbot['urls']['saveDraftQuestion'] = '{% url save_draft_question %}';
{% if settings.ENABLE_MATHJAX or settings.MARKUP_CODE_FRIENDLY %}
var codeFriendlyMarkdown = true;
@@ -41,7 +62,6 @@
var codeFriendlyMarkdown = false;
{% endif %}
$().ready(function(){
- liveSearchNewThreadInit();
//set current module button style
$('#editor').TextAreaResizer();
//highlight code synctax when editor has new text
diff --git a/askbot/templates/authopenid/complete.html b/askbot/templates/authopenid/complete.html
index c9afedee..835fd72f 100644
--- a/askbot/templates/authopenid/complete.html
+++ b/askbot/templates/authopenid/complete.html
@@ -1,4 +1,5 @@
{% extends "one_column_body.html" %}
+{% import "macros.html" as macros %}
<!-- complete.html -->
{#
views calling this template:
@@ -28,13 +29,18 @@ parameters:
</ul>
{% endif %}
<div class="login">
- {% if login_type=='openid' %}
- <form name="fregister" action="{% url user_register %}" method="POST">{% csrf_token %}
- {% elif login_type=='facebook' %}
- <form name="fregister" action="" method="POST">{% csrf_token %}
- {% else %}
- <form name="fregister" action="{{ default_form_action }}" method="POST">{% csrf_token %}
- {% endif %}
+ <form
+ id="register-form"
+ name="fregister"
+ {% if login_type=='openid' %}
+ action="{% url user_register %}"
+ {% elif login_type=='facebook' %}
+ action=""
+ {% else %}
+ action="{{ default_form_action }}"
+ {% endif %}
+ method="POST"
+ >{% csrf_token %}
{{ openid_register_form.next }}
<div class="form-row-vertical">
<label for="id_username">
@@ -56,8 +62,19 @@ anyone, must be valid</i>)
{% endif %}
{{ openid_register_form.email }}
</div>
- <div class="submit-row"><input type="submit" class="submit" name="bnewaccount" value="{% trans %}Signup{% endtrans %}"/></div>
+ <div class="submit-row">
+ <input
+ id="register-button"
+ type="submit"
+ class="submit"
+ name="bnewaccount"
+ value="{% trans %}Signup{% endtrans %}"
+ />
+ </div>
</form>
</div>
{% endblock %}
<!-- end complete.html -->
+{% block endjs %}
+ {{ macros.one_shot_form_js(form='#register-form', submit_button='#register-button') }}
+{% endblock %}
diff --git a/askbot/templates/authopenid/logout.html b/askbot/templates/authopenid/logout.html
index 1ac6705c..47579679 100644
--- a/askbot/templates/authopenid/logout.html
+++ b/askbot/templates/authopenid/logout.html
@@ -5,27 +5,6 @@
<h1 class="section-title">{% trans %}You have successfully logged out{% endtrans %}</h1>
{% if have_federated_login_methods %}
<p>{% trans %}However, you still may be logged in to your OpenID provider. Please logout of your provider if you wish to do so.{% endtrans %}</p>
- {% if settings.FACEBOOK_KEY and settings.FACEBOOK_SECRET %}
- <div id="fb-root"></div>
- <script src="http://connect.facebook.net/en_US/all.js"></script>
- <script>
- FB.init({appId: '{{settings.FACEBOOK_KEY}}', status: true, cookie: true, xfbml: true});
- </script>
- {% endif %}
{% endif %}
{% endblock %}
-{% block endjs %}
- <script type="text/javascript">
- $(document).ready(function(){
- //logout user from facebook
- if (typeof FB != 'undefined'){
- FB.getLoginStatus(function(response){
- if (response.session){
- FB.logout();
- }
- });
- }
- });
- </script>
-{% endblock %}
<!-- end logout.html -->
diff --git a/askbot/templates/authopenid/providers_javascript.html b/askbot/templates/authopenid/providers_javascript.html
index cd9f56b6..bf9f2542 100644
--- a/askbot/templates/authopenid/providers_javascript.html
+++ b/askbot/templates/authopenid/providers_javascript.html
@@ -37,19 +37,3 @@
askbot['settings']['signin_always_show_local_login'] = {% if settings.SIGNIN_ALWAYS_SHOW_LOCAL_LOGIN %}true{% else %}false{% endif %};
$("body").authenticator();
</script>
-{% if settings.FACEBOOK_KEY and settings.FACEBOOK_SECRET %}
-<div id="fb-root"></div>
-<script src="http://connect.facebook.net/en_US/all.js"></script>
-<script>
- $(document).ready(function(){
- if (typeof FB != 'undefined'){
- var ret = FB.init({appId: '{{settings.FACEBOOK_KEY}}', status: true, cookie: true, xfbml: true, oauth: true});
- FB.Event.subscribe('auth.authResponseChange', function(response){
- if (response.authResponse) {
- $('#signin-form').submit();
- }
- });
- };
- });
-</script>
-{% endif %}
diff --git a/askbot/templates/authopenid/signup_with_password.html b/askbot/templates/authopenid/signup_with_password.html
index e5a8f633..32bf781b 100644
--- a/askbot/templates/authopenid/signup_with_password.html
+++ b/askbot/templates/authopenid/signup_with_password.html
@@ -1,5 +1,6 @@
{% extends "one_column_body.html" %}
{% import "authopenid/authopenid_macros.html" as login_macros %}
+{% import "macros.html" as main_macros %}
<!--signup.html-->
{% block title %}{% spaceless %}{% trans %}Signup{% endtrans %}{% endspaceless %}{% endblock %}
{% block forestyle %}
@@ -29,7 +30,7 @@ password here. However</span>, please keep in mind that we also support
simply reuse your external login (e.g. Gmail or AOL) without ever sharing
your login details with anyone and having to remember yet another password.{% endtrans %}</p-->
{%endif%}
-<form action="{% url user_signup_with_password %}" method="post" accept-charset="utf-8">{% csrf_token %}
+<form id="signup-form" action="{% url user_signup_with_password %}" method="post" accept-charset="utf-8">{% csrf_token %}
{{form.login_provider}}
<ul class="form-horizontal-rows">
<li><label for="usename_id">{{form.username.label}}</label>{{form.username}}{{form.username.errors}}</li>
@@ -41,7 +42,7 @@ your login details with anyone and having to remember yet another password.{% en
<p class="signup_p">{% trans %}Please read and type in the two words below to help us prevent automated account creation.{% endtrans %}</p>
{{form.recaptcha}}
{% endif %}
- <div class="submit-row"><input type="submit" class="submit" value="{% trans %}Signup{% endtrans %}" />
+ <div class="submit-row"><input id="signup-button" type="submit" class="submit" value="{% trans %}Signup{% endtrans %}" />
{% if settings.PASSWORD_REGISTER_SHOW_PROVIDER_BUTTONS == False %}
<strong>{% trans %}or{% endtrans %}
<a href="{{ settings.LOGIN_URL }}">{% trans %}return to OpenID login{% endtrans %}</a></strong>
@@ -49,7 +50,8 @@ your login details with anyone and having to remember yet another password.{% en
</div>
</form>
{% endblock %}
-{%block endjs%}
-{%include "authopenid/providers_javascript.html" %}
-{%endblock%}
+{% block endjs %}
+ {% include "authopenid/providers_javascript.html" %}
+ {{ main_macros.one_shot_form_js(form="#signup-form", submit_button="#signup_button") }}
+{% endblock %}
<!--end signup.html-->
diff --git a/askbot/templates/badges.html b/askbot/templates/badges.html
index ce76e76b..e669b7d4 100644
--- a/askbot/templates/badges.html
+++ b/askbot/templates/badges.html
@@ -5,21 +5,16 @@
<h1 class="section-title">{% trans %}Badges{% endtrans %}</h1>
<p>
{% trans %}Community gives you awards for your questions, answers and votes.{% endtrans %}<br/>
-{% trans %}Below is the list of available badges and number
- of times each type of badge has been awarded. Have ideas about fun
-badges? Please, give us your <a href='{{feedback_faq_url}}'>feedback</a>
-{% endtrans %}
+{% trans %}Below is the list of available badges and number of times each type of badge has been awarded.{% endtrans %}
</p>
<div id="medalList">
{% for badge in badges %}
<div style="clear:both;line-height:30px">
- <div style="float:left;min-width:30px;text-align:right;height:30px">
- {% for a in mybadges %}
- {% if a.badge_id == badge.id %}
- <span style="font-size:175%; padding-right:5px; color:#5B9058;">&#10004;</span>
- {% endif %}
- {% endfor %}
- </div>
+ {% if badge.id in my_badge_ids %}
+ <div style="float:left;min-width:30px;text-align:right;height:30px">
+ <span style="font-size:175%; padding-right:5px; color:#5B9058;">&#10004;</span>
+ </div>
+ {% endif %}
<div style="float:left;width:230px;">
<a href="{{badge.get_absolute_url()}}"
title="{{badge.get_type_display()}} : {{badge.description}}"
diff --git a/askbot/templates/base.html b/askbot/templates/base.html
index 63d7115f..6c162057 100644
--- a/askbot/templates/base.html
+++ b/askbot/templates/base.html
@@ -10,9 +10,17 @@
{% if settings.GOOGLE_SITEMAP_CODE %}
<meta name="google-site-verification" content="{{settings.GOOGLE_SITEMAP_CODE}}" />
{% endif %}
+ <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
<link rel="shortcut icon" href="{{ settings.SITE_FAVICON|media }}" />
+ <link
+ rel="alternate"
+ type="application/rss+xml"
+ title="{% trans site_title=settings.APP_SHORT_NAME %}RSS feed from {{ site_title }}{% endtrans %}"
+ href="{{ settings.APP_URL }}{% url "latest_questions_feed" %}"
+ />
{% block before_css %}{% endblock %}
{% include "meta/html_head_stylesheets.html" %}
+ {% include "meta/fonts.html" %}
{% block forestyle %}{% endblock %}
{% include "meta/html_head_javascript.html" %}
{% block forejs %}{% endblock %}
@@ -20,9 +28,14 @@
{{ settings.CUSTOM_HTML_HEAD }}
{% endif %}
</head>
- <body class="{% block body_class %}{% endblock %}{% if user_messages %} user-messages{% endif %}{% if page_class %} {{page_class}}{% endif %}{% if request.user.is_anonymous() %} anon{% endif %} lang-{{settings.LANGUAGE_CODE}}">
+ <body class="{% block body_class %}{% endblock %}{% if user_messages %} user-messages{% endif %}{% if page_class %} {{page_class}}{% endif %}{% if request.user.is_anonymous() %} anon{% endif %} lang-{{ language_code }}">
{% include "widgets/system_messages.html" %}
{% include "debug_header.html" %}
+ {% if settings.MULTILINGUAL %}
+ <div class="content-wrapper">
+ {% include "widgets/language_nav.html" %}
+ </div>
+ {% endif %}
{% include "custom_header.html" ignore missing %}
{% if settings.CUSTOM_HEADER|trim != '' %}
<div id="custom-header">
diff --git a/askbot/templates/debug_header.html b/askbot/templates/debug_header.html
index e1230265..824b7352 100644
--- a/askbot/templates/debug_header.html
+++ b/askbot/templates/debug_header.html
@@ -10,7 +10,8 @@
<pre>python manage.py collectstatic</pre>
</p>
<p>
- If you do not see page styling - set DEBUG_MODE = True.
+ If you do not see page styling - set DEBUG_MODE = True or
+ use --insecure flag with the runserver command.
</p>
</div>
{% endif %}
diff --git a/askbot/templates/email/base_mail.html b/askbot/templates/email/base_mail.html
index eacbf87d..2487e804 100644
--- a/askbot/templates/email/base_mail.html
+++ b/askbot/templates/email/base_mail.html
@@ -133,10 +133,10 @@
<![endif]-->
</head>
<body>
-<table cellpadding="0" cellspacing="0" border="0" id="backgroundTable">
+<table cellpadding="0" cellspacing="0" border="0" id="backgroundTable" style="width: 100%">
<tr>
<td>
- <table border="0" align="center" cellspacing="0" cellpadding="0" style="background-color:#E7E8E8;">
+ <table border="0" align="center" cellspacing="0" cellpadding="0" style="background-color:#E7E8E8; width: 100%">
<tr height="20">
<td valign="top">
</td>
@@ -154,15 +154,15 @@
</tr>
<tr>
<td valign="top">
- {%block content%}
- {%endblock%}
+ {% block content %}
+ {% endblock %}
</td>
</tr>
<tr>
<td valign="top" class="footer">
<hr>
- {%block footer%}
- {%endblock%}
+ {% block footer %}
+ {% endblock %}
</td>
</tr>
</table>
diff --git a/askbot/templates/email/macros.html b/askbot/templates/email/macros.html
index 125705e2..77345a45 100644
--- a/askbot/templates/email/macros.html
+++ b/askbot/templates/email/macros.html
@@ -9,7 +9,11 @@
{{ 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;">
+ {% else %}
+ <p style="font-size:20px; font-weight: bold; margin: 10px 0">
+ {% endif %}
{% if format == 'parent_subthread' %}
{% if is_leaf_post %}
{% trans %}Question by {{ author }}:{% endtrans %}
@@ -23,18 +27,20 @@
{% 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>
- {% 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 %}
+ {% 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' %}
diff --git a/askbot/templates/embed/ask_by_widget.html b/askbot/templates/embed/ask_by_widget.html
index 4cec5f6d..dc3db806 100644
--- a/askbot/templates/embed/ask_by_widget.html
+++ b/askbot/templates/embed/ask_by_widget.html
@@ -6,11 +6,7 @@
{%else %}
<link href="{{'/bootstrap/css/bootstrap.css'|media}}" rel="stylesheet" type="text/css" />
{%endif%}
- {% if settings.USE_LOCAL_FONTS %}
- {% include "meta/fonts.html" %}
- {% else %}
- <link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:400,700&amp;subset=latin,cyrillic-ext,latin-ext' rel='stylesheet' type='text/css' />
- {% endif %}
+ {% include "meta/fonts.html" %}
<style type="text/css" media="screen">
body{
font-family: Verdana, Arial, Helvetica, sans-serif;
@@ -213,13 +209,15 @@
<script type="text/javascript" src='{{"/js/live_search_new_thread.js"|media}}'></script>
<script type="text/javascript" charset="utf-8">
- var minSearchWordLength = {{settings.MIN_SEARCH_WORD_LENGTH}};
- askbot['urls']['api_get_questions'] = '{% url api_get_questions %}';
+ askbot['settings']['minSearchWordLength'] = {{settings.MIN_SEARCH_WORD_LENGTH}};
+ askbot['urls']['titleSearch'] = '{% url title_search %}';
askbot['urls']['upload'] = '{% url upload %}';
$(document).ready(function(){
- $("#id_title").focus();
- $("#id_title").addClass('questionTitleInput');
- liveSearchNewThreadInit(true);
+ var searchInput = $('#id_title');
+ searchInput.addClass('questionTitleInput');
+ var search = new FullTextSearch();
+ search.decorate(searchInput);
+ searchInput.focus();
});
</script>
{% endblock %}
diff --git a/askbot/templates/embed/askbot_widget.js b/askbot/templates/embed/askbot_widget.js
index 8c358855..300d3dd8 100755
--- a/askbot/templates/embed/askbot_widget.js
+++ b/askbot/templates/embed/askbot_widget.js
@@ -10,8 +10,10 @@ var {{variable_name}} = {
toHtml: function() {
var html = {{variable_name}}.createButton();
var link = document.createElement('link');
+ var protocol = document.location.protocol;
+
link.setAttribute("rel", "stylesheet");
- link.setAttribute("href", 'http://{{host}}{%url render_ask_widget_css widget.id%}');
+ link.setAttribute("href", protocol + '//{{host}}{%url render_ask_widget_css widget.id%}');
//creating the div
var motherDiv = document.createElement('div');
@@ -36,7 +38,7 @@ var {{variable_name}} = {
containerDiv.appendChild(closeButton);
var iframe = document.createElement('iframe');
- iframe.setAttribute('src', 'http://{{host}}{% url ask_by_widget widget.id %}');
+ iframe.setAttribute('src', protocol + '//{{host}}{% url ask_by_widget widget.id %}');
containerDiv.appendChild(iframe);
diff --git a/askbot/templates/embed/delete_widget.html b/askbot/templates/embed/delete_widget.html
index ed80c537..7f4be5a3 100644
--- a/askbot/templates/embed/delete_widget.html
+++ b/askbot/templates/embed/delete_widget.html
@@ -5,7 +5,7 @@
<h1>Are you sure that you cant to delete this {{widget_name|capitalize}}Widget?</h1>
<br/>
<strong>Warning: This could break the widgets on sites that currently use this widget please make sure that you don't use the widget in other sites</strong>
-<form action="." method="POST">
+<form action="." method="POST">{% csrf_token %}
<p><input type='submit' value='Delete' /> <a href="{% url list_widgets widget_name %}">Go Back</a></p>
</form>
{% endblock %}
diff --git a/askbot/templates/embed/list_widgets.html b/askbot/templates/embed/list_widgets.html
index 83de5871..cdbcd219 100644
--- a/askbot/templates/embed/list_widgets.html
+++ b/askbot/templates/embed/list_widgets.html
@@ -10,19 +10,24 @@
<th>Code</th>
<th>Actions</th>
</tr>
+ {% if request.is_secure() %}
+ {% set protocol='https' %}
+ {% else %}
+ {% set protocol='http' %}
+ {% endif %}
{% if widget_name == 'ask' %}
- {%for widget in widgets%}
- <tr>
- <td>{{widget.title}}</td>
- <td> &lt;script type="text/javascript" src="http://{{request.get_host()}}{% url render_ask_widget widget.id%}" &gt;&lt;/script&gt;</td>
- <td><a href="{% url edit_widget widget_name, widget.id %}">Edit</a> | <a href="{% url delete_widget widget_name, widget.id %}">Delete</a></td>
- </tr>
- {%endfor%}
+ {%for widget in widgets%}
+ <tr>
+ <td>{{widget.title}}</td>
+ <td> &lt;script type="text/javascript" src="{{ protocol }}://{{request.get_host()}}{% url render_ask_widget widget.id%}" &gt;&lt;/script&gt;</td>
+ <td><a href="{% url edit_widget widget_name, widget.id %}">Edit</a> | <a href="{% url delete_widget widget_name, widget.id %}">Delete</a></td>
+ </tr>
+ {%endfor%}
{%else%}
{%for widget in widgets%}
<tr>
<td>{{widget.title}}</td>
- <td> &lt;iframe src="http://{{request.get_host()}}{% url question_widget widget.id%}" &gt; &lt;/iframe&gt;</td>
+ <td> &lt;iframe src="{{ protocol }}://{{request.get_host()}}{% url question_widget widget.id%}" &gt; &lt;/iframe&gt;</td>
<td><a href="{% url edit_widget widget_name, widget.id %}">Edit</a> | <a href="{% url delete_widget widget_name, widget.id %}">Delete</a></td>
</tr>
{%endfor%}
diff --git a/askbot/templates/embed/widget_form.html b/askbot/templates/embed/widget_form.html
index 65128d8e..ad1562aa 100644
--- a/askbot/templates/embed/widget_form.html
+++ b/askbot/templates/embed/widget_form.html
@@ -6,7 +6,7 @@
{#% if form.non_field_errors() %}
{{ form.non_field_errors() }}
{% endif %#}
-<form method="post">
+<form method="post">{% csrf_token %}
<table>
{{ form.as_table() }}
<tr>
diff --git a/askbot/templates/group_messaging/email_alert.html b/askbot/templates/group_messaging/email_alert.html
new file mode 100644
index 00000000..bb97f6f6
--- /dev/null
+++ b/askbot/templates/group_messaging/email_alert.html
@@ -0,0 +1,18 @@
+{% extends "email/base_mail.html"%}
+{% from "email/macros.html" import start_quote, end_quote %}
+{% block content %}
+ {% set level = 0 %}
+ {% for message in messages %}
+ {{ start_quote(level) }}
+ <p>{% trans author=message.sender %}{{ author }} wrote:{% endtrans %}</p>
+ {{ message.html|escape }}
+ {{ end_quote(level) }}
+ {% if loop.index == 1 %}
+ <p>{% trans %}To reply please <a class="thread-link" href="THREAD_URL_HOLE">visit your message inbox</a>{% endtrans %}</p>
+ {% endif %}
+ {% set level = level + 1 %}
+ {% endfor %}
+{% endblock %}
+{% block footer %}
+{% include "email/footer.html" %}
+{% endblock %}
diff --git a/askbot/templates/group_messaging/home_thread_details.html b/askbot/templates/group_messaging/home_thread_details.html
new file mode 100644
index 00000000..cde6b37c
--- /dev/null
+++ b/askbot/templates/group_messaging/home_thread_details.html
@@ -0,0 +1,16 @@
+<div class="group-messaging"
+ data-create-thread-url="{% url create_thread %}"
+ data-get-threads-url="{% url get_threads %}"
+ data-reply-url="{% url post_reply %}"
+>
+ <div class="first-col">
+ <button class="submit compose">{% trans %}compose{% endtrans %}</button>
+ {% include "group_messaging/senders_list.html" %}
+ </div>
+ <div class="second-col">
+ <div><div>{# need two nested divs to match dom of ThreadContainer #}
+ {% include "group_messaging/thread_details.html" %}
+ </div></div>
+ </div>
+ <div class="clear-fix"></div>
+</div>
diff --git a/askbot/templates/group_messaging/senders_list.html b/askbot/templates/group_messaging/senders_list.html
index 687cacd6..b33a28d8 100644
--- a/askbot/templates/group_messaging/senders_list.html
+++ b/askbot/templates/group_messaging/senders_list.html
@@ -1,14 +1,18 @@
-{#<ul class="mailboxes">
- <li><a class="inbox selected">{% trans %}Inbox{% endtrans %}</a></li>
- <li><a class="sent">{% trans %}Sent{% endtrans %}</a></li>
- <li><a class="trash">{% trans %}Trash{% endtrans %}</a></li>
-</ul>#}
{% if senders %}
<ul class="senders-list">
<li>{% trans %}Messages by sender:{% endtrans %}</li>
- <li><a class="selected" data-sender-id="-1">{% trans %}all users{% endtrans %}</a></li>
+ <li><a class="selected" data-sender-id="-1">
+ {% trans %}inbox{% endtrans %}
+ {% if inbox_threads_count %}({{ inbox_threads_count }}){% endif %}
+ </a>
+ </li>
+ <li><a data-sender-id="{{ request_user_id }}">{% trans %}sent{% endtrans %}</a></li>
{% for sender in senders %}
- <li><a data-sender-id="{{ sender.id }}">{{ sender.username|escape }}</a></li>
+ {% if sender.id != request_user_id %}
+ <li><a data-sender-id="{{ sender.id }}">{{ sender.username|escape }}</a></li>
+ {% endif %}
{% endfor %}
+ {# -2 is deleted messages #}
+ <li><a class="trash" data-sender-id="-2">{% trans %}trash{% endtrans %}</a></li>
</ul>
{% endif %}
diff --git a/askbot/templates/group_messaging/threads_list.html b/askbot/templates/group_messaging/threads_list.html
index bc0af802..335abcb9 100644
--- a/askbot/templates/group_messaging/threads_list.html
+++ b/askbot/templates/group_messaging/threads_list.html
@@ -1,12 +1,22 @@
-<table class="threads-list">
+<table class="threads-list {% if sender_id == -2 %}trash{% endif %}"
+ data-sender-id="{{ sender_id }}"
+>
{% if threads %}
{% for thread in threads %}
{% set thread_data = threads_data[thread.id] %}
<tr class="thread-heading {{ thread_data['status'] }}"
data-thread-id="{{ thread.id }}"
>
+ <td class="delete-or-restore"></td>
<td class="senders">{{ thread_data['senders_info']|escape }}</td>
- <td class="subject">{{ thread.headline|escape }}</td>
+ <td class="subject">
+ {{ thread.headline|escape }}
+ {% if thread_data['responses_count'] > 0 %}
+ <span class="messages-count">
+ ({{ thread_data['responses_count'] + 1 }})
+ </span>
+ {% endif %}
+ </td>
<td class="timestamp">{{ thread.last_active_at|timesince }}</td>
</tr>
{% endfor %}
diff --git a/askbot/templates/list_suggested_tags.html b/askbot/templates/list_suggested_tags.html
index 4eeb0004..31e48c09 100644
--- a/askbot/templates/list_suggested_tags.html
+++ b/askbot/templates/list_suggested_tags.html
@@ -28,19 +28,31 @@
</td>
<td colspan="2">
<table>{# inner table for the list of questions #}
- {% for thread in tag.threads.all() %}
- <tr class="thread-info" data-thread-id="{{ thread.id }}">
+ {% if tag.threads.count() == 0 %}
+ <tr class="thread-info" data-thread-id="0">
<td class="per-thread-controls">
<button class="btn accept">{% trans %}Accept{% endtrans %}</button>
<button class="btn reject">{% trans %}Reject{% endtrans %}</button>
</td>
<td class="thread-links-col">
- <a title="{{ thread._question_post().summary|escape }}"
- href="{{ thread.get_absolute_url() }}"
- >{{ thread.title|escape }}</a>
+ <span>{% trans %}There are no questions with this tag yet{% endtrans %}</span>
</td>
</tr>
- {% endfor %}
+ {% else %}
+ {% for thread in tag.threads.all() %}
+ <tr class="thread-info" data-thread-id="{{ thread.id }}">
+ <td class="per-thread-controls">
+ <button class="btn accept">{% trans %}Accept{% endtrans %}</button>
+ <button class="btn reject">{% trans %}Reject{% endtrans %}</button>
+ </td>
+ <td class="thread-links-col">
+ <a title="{{ thread._question_post().summary|escape }}"
+ href="{{ thread.get_absolute_url() }}"
+ >{{ thread.title|escape }}</a>
+ </td>
+ </tr>
+ {% endfor %}
+ {% endif %}
</table>
</td>
</tr>
diff --git a/askbot/templates/macros.html b/askbot/templates/macros.html
index 8e578dec..f94fc12d 100644
--- a/askbot/templates/macros.html
+++ b/askbot/templates/macros.html
@@ -12,20 +12,25 @@
<div class="face">
{{ gravatar(response.user, 48) }}
</div>
- <a style="font-size:12px" href="{{ response.user.get_absolute_url() }}">{{ response.user.username|escape }}</a>
- <a style="text-decoration:none;" href="{{ response.response_url }}">
- {{ response.response_type }}
- ({{ timeago(response.timestamp) }}):<br/>
- {% if inbox_section != 'flags' %}
- {{ response.response_snippet }}
- {% endif %}
- </a>
- {% if inbox_section == 'flags' %}
- <a class="re_expand" href="{{ response.response_url }}">
- <!--div class="re_snippet">{{ response.response_snippet|escape }}</div-->
- <div class="re_content">{{ response.response_content }}</div>
- </a>
- {% endif %}
+ <div class="content">
+ <a
+ style="font-size:12px"
+ href="{{ response.user.get_absolute_url() }}"
+ >{{ response.user.username|escape }}</a>
+ <a style="text-decoration:none;" href="{{ response.response_url }}">
+ {{ response.response_type }}
+ ({{ timeago(response.timestamp) }}):<br/>
+ {% if inbox_section != 'flags' %}
+ {{ response.response_snippet }}
+ {% endif %}
+ </a>
+ {% if inbox_section == 'flags' %}
+ <a class="re_expand" href="{{ response.response_url }}">
+ <!--div class="re_snippet">{{ response.response_snippet|escape }}</div-->
+ <div class="re_content">{{ response.response_content }}</div>
+ </a>
+ {% endif %}
+ </div>
</div>
{%- endmacro -%}
@@ -498,11 +503,11 @@ for the purposes of the AJAX comment editor #}
title="{{desc_tooltip}}"><span>{{label}}</span></a>
{% endif %}
<script type="text/javascript">{# need to pass on text translations to js #}
- var sortButtonData = sortButtonData || {};
- sortButtonData["{{key_name}}"] = {
- label: "{{label}}",
- asc_tooltip: "{{asc_tooltip}}",
- desc_tooltip: "{{desc_tooltip}}"
+ askbot['data']['sortButtonData'] = askbot['data']['sortButtonData'] || {};
+ askbot['data']['sortButtonData']['{{key_name}}'] = {
+ label: '{{label}}',
+ asc_tooltip: '{{asc_tooltip}}',
+ desc_tooltip: '{{desc_tooltip}}'
};
</script>
{%- endmacro %}
@@ -591,6 +596,14 @@ answer {% if answer.accepted() %}accepted-answer{% endif %} {% if answer.author_
{%- include "widgets/user_long_score_and_badge_summary.html" -%}
{%- endmacro -%}
+{%- macro country_flag(country_code, flag_label) -%}
+ <img
+ class="flag"
+ src="{{ ('/images/flags/' ~ country_code|lower ~ '.gif')|media }}"
+ alt="{{ flag_label }}"
+ />
+{%- endmacro -%}
+
{%- macro user_country_flag(user) -%}
{% if user.country and user.show_country %}
<img class="flag"
@@ -631,7 +644,7 @@ answer {% if answer.accepted() %}accepted-answer{% endif %} {% if answer.author_
{#todo: rename this to avatar #}
{%- macro gravatar(user, size) -%}
{% spaceless %}
-<a style="text-decoration:none"
+<a class="avatar-box"
href="{{ user.get_absolute_url() }}"
><img class="gravatar"
width="{{size}}" height="{{size}}"
@@ -780,3 +793,13 @@ answer {% if answer.accepted() %}accepted-answer{% endif %} {% if answer.author_
{{datetime_object.replace(microsecond=0)|add_tz_offset}}
</abbr>
{%- endmacro -%}
+
+{% macro one_shot_form_js(form=None, submit_button=None) %}
+ <script type="text/javascript">
+ (function() {
+ var form = new OneShotForm();
+ form.setSubmitButton($("{{submit_button}}"));
+ form.decorate($("{{form}}"));
+ })();
+ </script>
+{% endmacro %}
diff --git a/askbot/templates/main_page/javascript.html b/askbot/templates/main_page/javascript.html
index f1e0fb44..55b31d00 100644
--- a/askbot/templates/main_page/javascript.html
+++ b/askbot/templates/main_page/javascript.html
@@ -1,12 +1,9 @@
<script type="text/javascript">
/*<![CDATA[*/
- var sortMethod = '{{sort}}';
- var showSortByRelevance = {% if show_sort_by_relevance %}true{% else %}false{% endif %};
- var minSearchWordLength = {{settings.MIN_SEARCH_WORD_LENGTH}};
+ askbot['settings']['showSortByRelevance'] = {% if show_sort_by_relevance %}true{% else %}false{% endif %};
$(document).ready(function(){
/*var on_tab = '#nav_questions';
$(on_tab).attr('className','on');*/
- liveSearch('{{ search_state.query_string()|escapejs }}');
Hilite.exact = false;
Hilite.elementid = "question-list";
Hilite.debug_referrer = location.href;
@@ -21,8 +18,6 @@
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['urls']['questions'] = '{% url "questions" %}';
- askbot['urls']['question_url_template'] = scriptUrl + '{{'question/'|transurl}}{{ "{{QuestionID}}/" }}';
if (Modernizr.history) {
// history management works!
@@ -39,7 +34,7 @@
}
if (hash !== '' && hash !== undefined && url !== undefined){
{# was this causing strange redirects in IE??? #}
- window.location = 'http://' + window.location.host + url;
+ window.location = document.location.protocol + '//' + window.location.host + url;
}
}
/*]]>*/
@@ -48,4 +43,3 @@
{% if request.user.is_authenticated() %}
<script type='text/javascript' src='{{"/js/tag_selector.js"|media}}'></script>
{% endif %}
-<script type="text/javascript" src='{{"/js/live_search.js"|media}}'></script>
diff --git a/askbot/templates/main_page/tab_bar.html b/askbot/templates/main_page/tab_bar.html
index 17ab810e..c0b37955 100644
--- a/askbot/templates/main_page/tab_bar.html
+++ b/askbot/templates/main_page/tab_bar.html
@@ -1,6 +1,7 @@
{% import "macros.html" as macros %}
{% load extra_filters_jinja %}
{% cache 0 "scope_sort_tabs" search_tags request.user author_name scope sort query context.page language_code %}
+{% if settings.RSS_ENABLED %}
<a class="rss"
{% if feed_url %}
href="{{feed_url}}"
@@ -10,6 +11,7 @@
title="{% trans %}subscribe to the questions feed{% endtrans %}"
>{% trans %}RSS{% endtrans %}
</a>
+{% endif %}
<div class="tabBar">
<div id="sort_tabs" class="tabsA">
<span class="label">{% trans %}Sort by &raquo;{% endtrans %}</span>
@@ -31,8 +33,8 @@
</a>
{% endif %}
<script type="text/javascript">
- var sortButtonData = sortButtonData || {};
- sortButtonData['relevance'] = {
+ askbot['data']['sortButtonData'] = askbot['data']['sortButtonData'] || {};
+ askbot['data']['sortButtonData']['relevance'] = {
asc_tooltip: "{{asc_relevance_tooltip}}",
desc_tooltip: "{{desc_relevance_tooltip}}",
label: "{{relevance_label}}"
diff --git a/askbot/templates/meta/bottom_scripts.html b/askbot/templates/meta/bottom_scripts.html
index b3fcd815..1a910672 100644
--- a/askbot/templates/meta/bottom_scripts.html
+++ b/askbot/templates/meta/bottom_scripts.html
@@ -14,7 +14,7 @@
</script>
</div>
<script type="text/javascript">
- var i18nLang = '{{settings.LANGUAGE_CODE}}';
+ var i18nLang = '{{ language_code }}';
var scriptUrl = '/{{settings.ASKBOT_URL}}'
var askbotSkin = '{{settings.ASKBOT_DEFAULT_SKIN}}';
var enableMathJax = {% if settings.ENABLE_MATHJAX %}true{% else %}false{% endif %};
@@ -24,21 +24,27 @@
askbot['urls']['follow_user'] = '/followit/follow/user/{{'{{'}}userId{{'}}'}}/';
askbot['urls']['unfollow_user'] = '/followit/unfollow/user/{{'{{'}}userId{{'}}'}}/';
askbot['urls']['user_signin'] = '{{ settings.LOGIN_URL }}';
- askbot['settings']['static_url'] = '{{ settings.STATIC_URL }}';
askbot['urls']['getEditor'] = '{% url "get_editor" %}';
+ askbot['urls']['titleSearch'] = '{% url "title_search" %}';
+ askbot['urls']['ask'] = '{% url "ask" %}';
+ askbot['urls']['questions'] = '{% url "questions" %}';
+ askbot['settings']['static_url'] = '{{ settings.STATIC_URL }}';
+ askbot['settings']['minSearchWordLength'] = {{ settings.MIN_SEARCH_WORD_LENGTH }};
+ askbot['settings']['sharingSuffixText'] = '{{ settings.SHARING_SUFFIX_TEXT|escape }}';
</script>
<script
type="text/javascript"
{% if settings.DEBUG %}
src="{{"/js/jquery-1.7.2.min.js"|media}}"
{% else %}
- src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"
+ src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"
{% endif %}
></script>
<script type="text/javascript" src='{{"/bootstrap/js/bootstrap.js"|media}}'></script>
<!-- History.js -->
<script type='text/javascript' src="{{"/js/jquery.history.js"|media }}"></script>
<script type='text/javascript' src="{{"/js/utils.js"|media }}"></script>
+<script type="text/javascript" src="{{'/js/live_search.js'|media}}"></script>
{% if settings.ENABLE_MATHJAX %}
<script type='text/javascript' src="{{settings.MATHJAX_BASE_URL}}/MathJax.js">
MathJax.Hub.Config({
@@ -52,13 +58,37 @@
/*<![CDATA[*/
$(document).ready(function(){
// focus input on the search bar endcomment
- {% if active_tab in ('users', 'questions', 'tags') %}
- $('#keywords').focus();
+ {% if active_tab in ('users', 'questions', 'tags', 'badges') %}
+ var searchInput = $('#keywords');
{% elif active_tab == 'ask' %}
- $('#id_title').focus();
+ var searchInput = $('#id_title');
{% else %}
+ var searchInput = undefined;
animateHashes();
{% endif %}
+
+ if (searchInput) {
+ searchInput.focus();
+ putCursorAtEnd(searchInput);
+ }
+
+ {% if active_tab in ('questions', 'badges', 'ask') %}
+ if (searchInput) {
+ var search = new FullTextSearch();
+ askbot['controllers'] = askbot['controllers'] || {};
+ askbot['controllers']['fullTextSearch'] = search;
+ {% if search_state %}
+ search.setSearchUrl('{{ search_state.query_string()|escapejs }}');
+ {% else %}
+ search.setSearchUrl('');
+ {% endif %}
+ {% if active_tab == 'ask' %}
+ search.setAskButtonEnabled(false);
+ {% endif %}
+ search.decorate(searchInput);
+ }
+ {% endif %}
+
if (askbot['data']['userIsAdminOrMod']) {
$('body').addClass('admin');
}
diff --git a/askbot/templates/meta/fonts.html b/askbot/templates/meta/fonts.html
index e8e54a8f..1e0fe707 100644
--- a/askbot/templates/meta/fonts.html
+++ b/askbot/templates/meta/fonts.html
@@ -1,8 +1,15 @@
-<style type="text/css">
-@font-face {
- font-family: 'Open Sans Condensed';
- font-style: normal;
- font-weight: 700;
- src: url('{{"/images/OpenSans-CondBold.ttf"|media}}');
-}
-</style>
+{% if settings.USE_LOCAL_FONTS %}
+ {# this version is for serving fonts locally - e.g. for intranet sites #}
+ <style type="text/css">
+ @font-face {
+ font-family: 'Open Sans Condensed';
+ font-style: normal;
+ font-weight: 700;
+ src: url('{{"/images/OpenSans-CondBold.ttf"|media}}');
+ }
+ </style>
+{% else %}
+ {# note: for IE8 we ask for fonts separately #}
+ <link href='//fonts.googleapis.com/css?family=Open+Sans+Condensed:700&amp;subset=latin-ext' rel='stylesheet' type='text/css'>
+ <link href='//fonts.googleapis.com/css?family=Open+Sans+Condensed:700&amp;subset=cyrillic-ext' rel='stylesheet' type='text/css'>
+{% endif %}
diff --git a/askbot/templates/meta/html_head_javascript.html b/askbot/templates/meta/html_head_javascript.html
index 09362baa..306f325a 100644
--- a/askbot/templates/meta/html_head_javascript.html
+++ b/askbot/templates/meta/html_head_javascript.html
@@ -19,6 +19,7 @@
askbot['data']['userIsAuthenticated'] = false;
askbot['data']['userReputation'] = 0;
{% endif %}
+ askbot['data']['maxCommentLength'] = {{settings.MAX_COMMENT_LENGTH}};
askbot['urls'] = {};
askbot['settings'] = {};
askbot['settings']['editorType'] = '{{ settings.EDITOR_TYPE }}';
diff --git a/askbot/templates/meta/html_head_stylesheets.html b/askbot/templates/meta/html_head_stylesheets.html
index 85bb489c..23750239 100644
--- a/askbot/templates/meta/html_head_stylesheets.html
+++ b/askbot/templates/meta/html_head_stylesheets.html
@@ -9,13 +9,6 @@
<script type="text/javascript" src="{{"/js/less.min.js"|media}}"></script>
{% endif %}
<link href="{{'/bootstrap/css/bootstrap.css'|media}}" rel="stylesheet" type="text/css" />
-{% if settings.USE_LOCAL_FONTS %}
- {% include "meta/fonts.html" %}
-{% else %}
- {# note: IE8 fix - a combined font link wont work so we have two #}
- <link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:700&amp;subset=latin-ext' rel='stylesheet' type='text/css'>
- <link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:700&amp;subset=cyrillic-ext' rel='stylesheet' type='text/css'>
-{% endif %}
{{ skin.get_extra_css_link() }}
{% if settings.USE_CUSTOM_CSS %}
<link
diff --git a/askbot/templates/question.html b/askbot/templates/question.html
index 57c71068..5fcea3a9 100644
--- a/askbot/templates/question.html
+++ b/askbot/templates/question.html
@@ -15,7 +15,43 @@
/*<![CDATA[*/
//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 %};
(function(){
+
+ var hasClass = function(node, selector) {
+ var classes = (" " + node.className + " ").split(' ');
+ for (var i = 0; i < classes.length; i++) {
+ if (classes[i] === selector) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ var findChildrenByClassName = function(node, className) {
+ var nodes = [];
+ var walk = function(node) {
+ if (hasClass(node, className)) {
+ nodes.push(node);
+ }
+ if (node.childNodes) {
+ for (var i=0; i < node.childNodes.length; i++) {
+ walk(node.childNodes[i]);
+ }
+ }
+ };
+ walk(node);
+ return nodes;
+ };
+
+ var removeNode = function(node) {
+ node.parentNode.removeChild(node);
+ };
+
+ var trim = function(text) {
+ return text.replace(/^\s+|\s+$/g, '');
+ };
+
var data = askbot['data'];
if (data['userIsAuthenticated']){
var votes = {};
@@ -57,17 +93,32 @@
}
function hide_convert_answer_links(post_id){
- var answer_convert_id = 'post-' + post_id + '-convert';
- var convert_answer = document.getElementById(answer_convert_id);
+ var id1 = 'post-' + post_id + '-convert';//for repost as Q comment
+ var repostAsQuestionComment = document.getElementById(id1);
+ var id2 = 'post-' + post_id + '-repost-as-comment-under-previous-answer';
+ var repostAsPrevAnsComment = document.getElementById(id2);
+ var extraOptsList = repostAsQuestionComment.parentNode;
+ var extraOpts = extraOptsList.parentNode;
if (data['userIsAdminOrMod']){
var answer_id = 'post-id-' + post_id;
var answer_container = document.getElementById(answer_id);
- var answer_element= answer_container.getElementsByClassName('answer-body')[0].children[1];
- if (answer_element.textContent.length > 300){
- convert_answer.parentNode.removeChild(convert_answer);
+ var answerBody = findChildrenByClassName(answer_container, 'answer-body')[0];
+ //todo: this is not reliable
+ var answerBodyNodes = answerBody.childNodes;
+ var answerElement = answerBodyNodes[answerBodyNodes.length - 1];
+ if (trim(answerElement.textContent).length > askbot['data']['maxCommentLength']) {
+ repostAsQuestionComment.parentNode.removeChild(repostAsQuestionComment);
+ repostAsPrevAnsComment.parentNode.removeChild(repostAsPrevAnsComment);
+ } else if (parseInt(post_id) === data['oldestAnswerId']) {
+ repostAsPrevAnsComment.parentNode.removeChild(repostAsPrevAnsComment);
}
} else{
- convert_answer.parentNode.removeChild(convert_answer);
+ repostAsQuestionComment.parentNode.removeChild(repostAsQuestionComment);
+ repostAsPrevAnsComment.parentNode.removeChild(repostAsPrevAnsComment);
+ }
+
+ if (extraOptsList.getElementsByTagName('li').length === 0) {
+ extraOpts.parentNode.removeChild(extraOpts);
}
}
@@ -84,21 +135,21 @@
if (data['userIsAdminOrMod']){
return;//all remaining functions stay on
}
- if (data['user_posts'] === undefined) {
- return;
- }
- if (post_id in data['user_posts']){
+ if (data['user_posts'] && post_id in data['user_posts']){
//todo: remove edit button from older comments
- return;//same here
+ return;
}
+ var deleteBtn = document.getElementById('post-' + post_id + '-delete');
+ var controls = deleteBtn.parentNode;
if (//maybe remove "delete" button
data['userReputation'] <
{{settings.MIN_REP_TO_DELETE_OTHERS_COMMENTS}}
) {
- var delete_btn = document.getElementById(
- 'post-' + post_id + '-delete'
- );
- delete_btn.parentNode.removeChild(delete_btn);
+ removeNode(deleteBtn);
+ }
+ var flags = findChildrenByClassName(controls, 'question-flag');
+ if (flags.length > 0) {
+ removeNode(flags[0]);
}
if (//maybe remove "edit" button
data['userReputation'] <
@@ -113,8 +164,10 @@
data['userReputation'] <
{{settings.MIN_REP_TO_RETAG_OTHERS_QUESTIONS}}
){
- var retag_btn = document.getElementById('retag');
- retag_btn.parentNode.removeChild(retag_btn);
+ var retagBtn = document.getElementById('retag');
+ if (retagBtn) {
+ retagBtn.parentNode.removeChild(retagBtn);
+ }
}
}
function render_add_comment_button(post_id, extra_comment_count){
@@ -185,7 +238,7 @@
function hide_convert_links(){
if (!askbot['data']['userIsAdminOrMod']){
- var links = document.getElementsByClassName('convert-comment');
+ var links = findChildrenByClassName(document, 'convert-comment');
for (i=0; i<links.length; i++){
links[i].setAttribute('style', 'display:none;');
}
@@ -206,7 +259,7 @@
{% endblock %}
{% block content %}
<div>
- {{ settings.QUESTION_PAGE_TOP_BANNER }}
+ {{ settings.QUESTION_PAGE_TOP_BANNER|safe }}
</div>
{% if is_cacheable %}
{% cache long_time "thread-content-html" thread.id %}
diff --git a/askbot/templates/question/answer_controls.html b/askbot/templates/question/answer_controls.html
index 4efc7247..c7d3c4d9 100644
--- a/askbot/templates/question/answer_controls.html
+++ b/askbot/templates/question/answer_controls.html
@@ -1,32 +1,8 @@
{#<span class="action-link swap-qa">
<a id="swap-question-with-answer-{{answer.id}}">{% trans %}swap with question{% endtrans %}</a>
</span>uncomment if needed#}
-<span class="action-link">
- <a class="permant-link"
- href="{{ answer.get_absolute_url(question_post=question) }}"
- title="{% trans %}permanent link{% endtrans %}">
- {% trans %}link{% endtrans %}
- </a>
-</span>
-<span
- id="post-{{answer.id}}-publish"
- class="action-link"
->
- {% if answer.id in published_answer_ids %}
- <a
- class="answer-unpublish"
- data-answer-id="{{ answer.id }}"
- >{% trans %}unpublish{% endtrans %}</a>
- {% else %}
- <a
- class="answer-publish"
- data-answer-id="{{ answer.id}}"
- >{% trans %}publish{% endtrans %}</a>
- {% endif %}
-</span>
-<span id='post-{{answer.id}}-delete' class="action-link delete-post">
- <a class="question-delete"
- >{% if answer.deleted %}{% trans %}undelete{% endtrans %}{% else %}{% trans %}delete{% endtrans %}{% endif %}</a>
+<span id='post-{{answer.id}}-edit' class="action-link">
+ <a class="question-edit" href="{% url edit_answer answer.id %}">{% trans %}edit{% endtrans %}</a>
</span>
{% if answer.offensive_flag_count > 0 %}
<span
@@ -52,15 +28,63 @@
<a class="question-flag">{% trans %}flag offensive{% endtrans %}</a>
</span>
{% endif %}
-<span id='post-{{answer.id}}-edit' class="action-link">
- <a class="question-edit" href="{% url edit_answer answer.id %}">{% trans %}edit{% endtrans %}</a>
+<span id='post-{{answer.id}}-delete' class="action-link delete-post">
+ <a class="question-delete"
+ >{% if answer.deleted %}{% trans %}undelete{% endtrans %}{% else %}{% trans %}delete{% endtrans %}{% endif %}</a>
+</span>
+<span
+ id="post-{{answer.id}}-publish"
+ class="action-link"
+>
+ {% if answer.id in published_answer_ids %}
+ <a
+ class="answer-unpublish"
+ data-answer-id="{{ answer.id }}"
+ >{% trans %}unpublish{% endtrans %}</a>
+ {% else %}
+ <a
+ class="answer-publish"
+ data-answer-id="{{ answer.id}}"
+ >{% trans %}publish{% endtrans %}</a>
+ {% endif %}
+</span>
+<span class="action-link">
+ <a class="permant-link"
+ href="{{ answer.get_absolute_url(question_post=question) }}"
+ title="{% trans %}permanent link{% endtrans %}">
+ {% trans %}link{% endtrans %}
+ </a>
</span>
-<span id='post-{{answer.id}}-convert' class="action-link">
- <form class="answer-convert" action="{% url answer_to_comment %}" method="POST">
- {% csrf_token %}
- <input type="hidden" name="answer_id" id="id_answer_id" value="{{answer.id}}"/>
- <input type="submit" name="" value="{% trans %}convert to comment{% endtrans %}"/>
- </form>
+<span class="action-link dropdown-toggle">{% trans %}more{% endtrans %}
+<ul class="dropdown-menu">
+ <li id='post-{{answer.id}}-convert'>
+ <form
+ class="answer-convert"
+ action="{% url repost_answer_as_comment_under_question %}"
+ method="post"
+ >
+ {% csrf_token %}
+ <input type="hidden" name="answer_id" id="id_answer_id" value="{{answer.id}}"/>
+ <input
+ type="submit"
+ value="{% trans %}repost as a question comment{% endtrans %}"
+ />
+ </form>
+ </li>
+ <li id='post-{{ answer.id }}-repost-as-comment-under-previous-answer'>
+ <form class="answer-convert repost-as-comment-under-previous-answer"
+ action="{% url repost_answer_as_comment_under_previous_answer %}"
+ method="post"
+ >
+ {% csrf_token %}
+ <input type="hidden" name="answer_id" value="{{ answer.id }}"/>
+ <input
+ type="submit"
+ value="{% trans %}repost as a comment under the older answer{% endtrans %}"
+ />
+ </form>
+ </li>
+</ul>
</span>
<script type="text/javascript">
askbot['functions']['hideConvertAnswerLinks']('{{ answer.id }}');
diff --git a/askbot/templates/question/content.html b/askbot/templates/question/content.html
index 66b3014b..7efc1d54 100644
--- a/askbot/templates/question/content.html
+++ b/askbot/templates/question/content.html
@@ -1,34 +1,29 @@
{% import "macros.html" as macros %}
-{# ==== BEGIN: question/question_card.html ==== #}
{% include "question/question_card.html" %}
-{# ==== END: question/question_card.html ==== #}
{% if answers %}
<div class="clean"></div>
- {# ==== START: question/answer_tab_bar.html ==== #}
{% include "question/answer_tab_bar.html" %}
- {# ==== END: question/answer_tab_bar.html ==== #}
<div class="clean"></div>
{{ macros.paginator(paginator_context, anchor='#sort-top') }}
<div class="clean"></div>
{% for answer in answers %}
- {# ==== START: question/answer_card.html ==== #}
+ {% if answers|length > 1 and loop.index == 2 %}
+ {{ settings.QUESTION_PAGE_ANSWER_BANNER|safe }}
+ {% endif %}
{% include "question/answer_card.html" %}
- {# ==== END: question/answer_card.html ==== #}
{% endfor %}
+
{{ macros.paginator(paginator_context, anchor='#sort-top') }}
<div class="clean"></div>
{% else %}
- {# ==== START: question/sharing_prompt_phrase.html ==== #}
{% include "question/sharing_prompt_phrase.html" %}
- {# ==== END: question/sharing_prompt_phrase.html ==== #}
{% endif %}
-{# ==== START: question/new_answer_form.html ==== #}
{# buttons below cannot be cached yet #}
{% if user_already_gave_answer %}
<a
diff --git a/askbot/templates/question/javascript.html b/askbot/templates/question/javascript.html
index 5dca2522..edd7ead7 100644
--- a/askbot/templates/question/javascript.html
+++ b/askbot/templates/question/javascript.html
@@ -10,11 +10,9 @@
askbot['urls']['editComment'] = '{% url edit_comment %}';
askbot['urls']['deleteComment'] = '{% url delete_comment %}';
askbot['urls']['convertComment'] = '{% url comment_to_answer %}';
- askbot['urls']['convertAnswer'] = '{% url answer_to_comment %}';
askbot['urls']['getComment'] = '{% url get_comment %}';
askbot['urls']['saveDraftAnswer'] = '{% url save_draft_answer %}';
- askbot['urls']['question_url_template'] = scriptUrl + '{{ 'question/'|transurl }}{{ "{{QuestionID}}/{{questionSlug}}" }}';{# yes it needs to be that whacky #}
- askbot['urls']['vote_url_template'] = scriptUrl + '{{ 'questions/'|transurl }}{{ "{{QuestionID}}/" }}{{ 'vote/'|transurl }}';
+ askbot['urls']['vote_url'] = '{% url vote question.id %}';
askbot['urls']['user_signin'] = '{{ settings.LOGIN_URL }}';
askbot['urls']['swap_question_with_answer'] = '{% url swap_question_with_answer %}';
askbot['urls']['upvote_comment'] = '{% url upvote_comment %}';
@@ -55,7 +53,7 @@
if (window.location.hash === 'fmanswer'){
$('#fmanswer textarea').focus();
}
- {% if settings.ENABLE_SHARING_GOOGLE %}$.getScript("http://apis.google.com/js/plusone.js"){% endif %}
+ {% if settings.ENABLE_SHARING_GOOGLE %}$.getScript("//apis.google.com/js/plusone.js"){% endif %}
{% if request.user.id == question.author_id %}
$("#fmanswer_button").click(function() {
diff --git a/askbot/templates/question/question_controls.html b/askbot/templates/question/question_controls.html
index c782d9ad..88ef42d8 100644
--- a/askbot/templates/question/question_controls.html
+++ b/askbot/templates/question/question_controls.html
@@ -1,12 +1,8 @@
-<a
- id="post-{{question.id}}-delete"
- class="question-delete"
->{% if question.deleted %}{% trans %}undelete{% endtrans %}{% else %}{% trans %}delete{% endtrans %}{% endif %}</a>
-{% if thread.closed %}
- <a class="question-close" href="{% url reopen question.id %}">{% trans %}reopen{% endtrans %}</a>
-{% else %}
- <a class="question-close" href="{% url close question.id %}">{% trans %}close{% endtrans %}</a>
-{% endif %}
+<a id="post-{{question.id}}-edit" class="question-edit" href="{% url edit_question question.id %}">{% trans %}edit{% endtrans %}</a>
+<script type="text/javascript">
+ var retagUrl = "{% url retag_question question.id %}";
+</script>
+<a id="retag" class="question-retag"href="{% url retag_question question.id %}">{% trans %}retag{% endtrans %}</a>
{% if question.offensive_flag_count > 0 %}
<span
id="question-offensive-remove-flag-{{ question.id }}"
@@ -29,11 +25,15 @@
<a class="question-flag">{% trans %}flag offensive{% endtrans %}</a>
</span>
{% endif %}
-<script type="text/javascript">
- var retagUrl = "{% url retag_question question.id %}";
-</script>
-<a id="retag" class="question-retag"href="{% url retag_question question.id %}">{% trans %}retag{% endtrans %}</a>
-<a id="post-{{question.id}}-edit" class="question-edit" href="{% url edit_question question.id %}">{% trans %}edit{% endtrans %}</a>
+{% if thread.closed %}
+ <a class="question-close" href="{% url reopen question.id %}">{% trans %}reopen{% endtrans %}</a>
+{% else %}
+ <a class="question-close" href="{% url close question.id %}">{% trans %}close{% endtrans %}</a>
+{% endif %}
+<a
+ id="post-{{question.id}}-delete"
+ class="question-delete"
+>{% if question.deleted %}{% trans %}undelete{% endtrans %}{% else %}{% trans %}delete{% endtrans %}{% endif %}</a>
<script type="text/javascript">
askbot['functions']['renderPostControls']('{{question.id}}');
</script>
diff --git a/askbot/templates/question/sidebar.html b/askbot/templates/question/sidebar.html
index 4d431ef2..17820096 100644
--- a/askbot/templates/question/sidebar.html
+++ b/askbot/templates/question/sidebar.html
@@ -39,12 +39,14 @@
<input type="checkbox" id="question-subscribe-sidebar"/>
<label for="question-subscribe-sidebar">{% trans %}<strong>Here</strong> (once you log in) you will be able to sign up for the periodic email updates about this question.{% endtrans %}</label>
{%endif%}
+ {% if settings.RSS_ENABLED %}
<p class="rss">
<a
href="{{settings.APP_URL}}/feeds/question/{{ question.id }}"
title="{% trans %}subscribe to this question rss feed{% endtrans %}"
>{% trans %}subscribe to rss feed{% endtrans %}</a>
</p>
+ {% endif %}
</div>
</div>
@@ -171,6 +173,8 @@
{#% endcache %#}
{% endif %}
-<div class="box">
- {{ settings.SIDEBAR_QUESTION_FOOTER }}
-</div>
+{% if settings.SIDEBAR_QUESTION_FOOTER %}
+ <div class="box">
+ {{ settings.SIDEBAR_QUESTION_FOOTER }}
+ </div>
+{% endif %}
diff --git a/askbot/templates/question_edit.html b/askbot/templates/question_edit.html
index 8b049e55..7cf1c143 100644
--- a/askbot/templates/question_edit.html
+++ b/askbot/templates/question_edit.html
@@ -35,6 +35,9 @@
{% if settings.WIKI_ON and question.wiki == False %}
{{ macros.checkbox_in_div(form.wiki) }}
{% endif %}
+ {% if settings.ENABLE_EMAIL_ALERTS %}
+ {{ macros.checkbox_in_div(form.suppress_email) }}
+ {% endif %}
{% if form.can_stay_anonymous() %}
{{ macros.checkbox_in_div(form.reveal_identity) }}
{% endif %}
@@ -44,6 +47,12 @@
%}
{{ macros.checkbox_in_div(form.post_privately) }}
{% endif %}
+ {% if settings.MULTILINGUAL %}
+ <div class="lang-selector">
+ <label for="id_language">{% trans %}Change language{% endtrans %}</label>
+ {{ form.language }}
+ </div>
+ {% endif %}
</div>
<input id="edit_post_form_submit_button" type="submit" value="{% trans %}Save edit{% endtrans %}" class="submit" />&nbsp;
<input type="button" value="{% trans %}Cancel{% endtrans %}" class="submit" onclick="history.back(-1);" />
diff --git a/askbot/templates/revisions.html b/askbot/templates/revisions.html
index a0531b80..1765b728 100644
--- a/askbot/templates/revisions.html
+++ b/askbot/templates/revisions.html
@@ -50,7 +50,7 @@
{% set contributor_type = "last_updater" %}
{% endif %}
{{ macros.post_contributor_info(
- revision.post,
+ revision,
contributor_type,
False,
0
diff --git a/askbot/templates/tags/form_bulk_tag_subscription.html b/askbot/templates/tags/form_bulk_tag_subscription.html
new file mode 100644
index 00000000..d588cfaf
--- /dev/null
+++ b/askbot/templates/tags/form_bulk_tag_subscription.html
@@ -0,0 +1,21 @@
+{% extends "one_column_body.html" %}
+{% import "macros.html" as macros %}
+<!-- template form_bulk_tag_subscription.html -->
+{% block title %}{% spaceless %}{{action}} {% trans %}Tag subscriptions{% endtrans %}{% endspaceless %}{% endblock %}
+{% block content %}
+<h1 class="section-title">{{action}} {% trans %}Tag Subscriptions{% endtrans %}</h1>
+<p>
+</p>
+<form action="." method="POST" accept-charset="utf-8">
+<table border="0">
+{{form.as_table()}}
+<tr><td colspan='2' style='text-align: right;'><input type="submit" class="submit" value="Save"></td></tr>
+</table>
+</form>
+{% endblock %}
+{%block endjs%}
+ <script type="text/javascript" charset="utf-8">
+ {{macros.tag_autocomplete_js()}}
+ </script>
+{%endblock%}
+<!-- end template form_bulk_tag_subscription.html -->
diff --git a/askbot/templates/tags/header.html b/askbot/templates/tags/header.html
index 9f1d73e4..0832300e 100644
--- a/askbot/templates/tags/header.html
+++ b/askbot/templates/tags/header.html
@@ -23,14 +23,23 @@
{% if tab_id == 'used' %}class="on"{% endif %}
title="{% trans %}sorted by frequency of tag use{% endtrans %}"
><span>{% trans %}by popularity{% endtrans %}</span></a>
- {% if settings.ENABLE_TAG_MODERATION %}
- {% if request.user.is_authenticated() and request.user.is_administrator_or_moderator() %}
- <a
- href="{% url list_suggested_tags %}"
- {% if tab_id == 'suggested' %}class="on"{% endif %}
- title="{% trans %}suggested{% endtrans %}"
- ><span>{% trans %}suggested{% endtrans %}</span></a>
- {% endif %}
+ {% if settings.ENABLE_TAG_MODERATION
+ and request.user.is_authenticated()
+ and request.user.is_administrator_or_moderator()
+ %}
+ <a
+ href="{% url list_suggested_tags %}"
+ {% if tab_id == 'suggested' %}class="on"{% endif %}
+ title="{% trans %}suggested{% endtrans %}"
+ ><span>{% trans %}suggested{% endtrans %}</span></a>
+ {% endif %}
+ {% if settings.SUBSCRIBED_TAG_SELECTOR_ENABLED
+ and request.user.is_authenticated()
+ and request.user.is_administrator()
+ %}
+ <a href="{% url list_bulk_tag_subscription %}"
+ title="{% trans %}manage subscriptions{% endtrans %}"
+ ><span>{% trans %}manage subscriptions{% endtrans %}</span></a>
{% endif %}
</div>
</div>
diff --git a/askbot/templates/tags/list_bulk_tag_subscription.html b/askbot/templates/tags/list_bulk_tag_subscription.html
new file mode 100644
index 00000000..5337154b
--- /dev/null
+++ b/askbot/templates/tags/list_bulk_tag_subscription.html
@@ -0,0 +1,62 @@
+{% extends "one_column_body.html" %}
+{% import "macros.html" as macros %}
+<!-- template list_bulk_tag_subscription.html -->
+{% block title %}{% spaceless %}{% trans %}Manage Tag subscriptions{% endtrans %}{% endspaceless %}{% endblock %}
+{% block content %}
+ <h1 class="section-title">{% trans %}Manage Tag subscription</a> {% endtrans %}(<a href="{% url create_bulk_tag_subscription %}">{%trans%}Create New{%endtrans%}</a>)</h1>
+<p>
+</p>
+<table class='tag-subscriptions'>
+ <thead>
+ <th>{% trans %}Date{%endtrans%} </th>
+ <th>{% trans %}Tags{%endtrans%} </th>
+ <th>{% trans %}Users{%endtrans%}</th>
+ {% if settings.GROUPS_ENABLED %}
+ <th>{%trans%}Groups{%endtrans%} </th>
+ {%endif%}
+ <th>{%trans%}Action{%endtrans%}</th>
+ </thead>
+ <tbody>
+ {% for subscription in object_list %}
+ <tr>
+ <td>{{subscription.date_added}}</td>
+ <td>
+ {{
+ macros.tag_list_widget(
+ subscription.tag_list(),
+ deletable=False,
+ css_class='subscribed marked-tags'
+ )
+ }}
+ </td>
+ {% set comma=joiner(',') %}
+ <td>{%for user in subscription.users.all() %}{{ comma() }}
+ <a
+ href='{% url user_profile user.id, user.username|slugify %}'
+ >{{user.username}}</a>{%endfor%} <a href='#'>
+ </td>
+ {% if settings.GROUPS_ENABLED %}
+ {% set comma=joiner(',') %}
+ <td>
+ {% for group in subscription.groups.all() %}{{ comma() }}
+ <a
+ href='{% url users_by_group group.id, group.name|slugify %}'
+ >{{group.name}}</a>{%endfor%}
+ </td>
+ {%endif%}
+ <td>
+ <button type="button"><a class='action' href='{% url edit_bulk_tag_subscription subscription.id %}'>{%trans%}Edit{%endtrans%}</a></button>
+ <form action="{%url delete_bulk_tag_subscription %}" method="POST" accept-charset="utf-8">
+ <input type="hidden" name="pk" value="{{subscription.id}}" />
+ <button type="submit">Delete</button>
+ </form>
+ </td>
+ </tr>
+ {%endfor%}
+ </tbody>
+</table>
+{% endblock %}
+{#block endjs%}
+ <script type='text/javascript' src='{{"/js/tag_selector.js"|media}}'></script>
+{%endblock#}
+<!-- end template list_bulk_tag_subscription.html -->
diff --git a/askbot/templates/user_inbox/base.html b/askbot/templates/user_inbox/base.html
index 8beababc..c8bf3d8e 100644
--- a/askbot/templates/user_inbox/base.html
+++ b/askbot/templates/user_inbox/base.html
@@ -13,7 +13,7 @@
<div id="re_sections">
{% trans %}Sections:{% endtrans %}
{% set sep = joiner('|') %}
- {#{ sep() }}
+ {#{{ sep() }}
<a href="{{request.user.get_absolute_url()}}?sort=inbox&section=messages"
{% if inbox_section == 'messages' %}class="on"{% endif %}
>{% trans %}messages{% endtrans %}</a>#}
diff --git a/askbot/templates/user_inbox/messages.html b/askbot/templates/user_inbox/messages.html
index 5108d15e..a620bf66 100644
--- a/askbot/templates/user_inbox/messages.html
+++ b/askbot/templates/user_inbox/messages.html
@@ -22,6 +22,7 @@
}
table.threads-list {
width: 100%;
+ border-spacing: 0px;
}
.threads-list tr {
height: 2em;
@@ -36,6 +37,16 @@
.threads-list tr:hover {
background-color: #eff5f6;
}
+ .threads-list td.delete-or-restore {
+ width: 15px;
+ background-image: none;
+ }
+ .threads-list tr:hover td.delete-or-restore {
+ background: url({{"/images/delete.png"|media}}) no-repeat center center;
+ }
+ .threads-list.trash tr:hover td.delete-or-restore {
+ background-image: url({{"/images/delete.png"|media}});
+ }
td.empty {
line-height: 30px;
vertical-align: middle;
@@ -93,7 +104,7 @@
{% trans %}inbox - messages{% endtrans %}
{% endblock %}
{% block inbox_content %}
- {% include "group_messaging/home.html" %}
+ {% include group_messaging_template_name %}
{% endblock %}
{% block userjs %}
<script type="text/javascript" src="{{ 'js/group_messaging.js'|media }}"></script>
diff --git a/askbot/templates/user_inbox/responses_and_flags.html b/askbot/templates/user_inbox/responses_and_flags.html
index c889bb0a..16599c1d 100644
--- a/askbot/templates/user_inbox/responses_and_flags.html
+++ b/askbot/templates/user_inbox/responses_and_flags.html
@@ -28,9 +28,7 @@
<div id="responses">
{% for response in responses %}
<div class="response-parent" data-response-id="{{response.id}}">
- <p class="headline">
- <strong>"{{ response.response_title.strip()|escape}}"</strong>
- </p>
+ <h2>"{{ response.response_title.strip()|escape}}"</h2>
{{ macros.inbox_post_snippet(response, inbox_section) }}
{% for nested_response in response.nested_responses %}
{{ macros.inbox_post_snippet(nested_response, inbox_section) }}
diff --git a/askbot/templates/user_profile/user_email_subscriptions.html b/askbot/templates/user_profile/user_email_subscriptions.html
index f44e8a1e..4692456b 100644
--- a/askbot/templates/user_profile/user_email_subscriptions.html
+++ b/askbot/templates/user_profile/user_email_subscriptions.html
@@ -1,4 +1,5 @@
{% extends "user_profile/user.html" %}
+{% import "macros.html" as macros %}
<!-- user_email_subscriptions.html -->
{% block profilesection %}
{% trans %}subscriptions{% endtrans %}
@@ -24,5 +25,50 @@
</div>
</form>
</div>
+
+ {% if settings.MULTILINGUAL %}
+ <h2>{% trans %}Subscribed languages{% endtrans %}</h2>
+ <form
+ method="post"
+ action="{% url user_select_languages view_user.id, view_user.username|slugify %}"
+ >{% csrf_token %}
+ <select multiple name="languages">
+ {% for lang in settings.LANGUAGES_DICT %}
+ <option
+ value="{{ lang }}"
+ {% if lang in user_languages %}selected="selected"{% endif %}
+ >{{ settings.LANGUAGES_DICT[lang] }}</option>
+ {% endfor %}
+ </select><br/>
+ <input type="submit" class="select-language" value="{% trans %}Save languages{% endtrans %}" />
+ </form>
+ {% endif %}
+
+ {%if settings.SUBSCRIBED_TAG_SELECTOR_ENABLED %}
+ <h2>{% trans %}Subscribed Tags{% endtrans %}</h2>
+ {{
+ macros.tag_list_widget(
+ subscribed_tag_names,
+ deletable = True,
+ css_class = 'subscribed marked-tags special',
+ )
+ }}
+ <br/>
+ <div class="inputs">
+ <input id="subscribedTagInput" autocomplete="off" type="text"/>
+ <input id="subscribedTagAdd" type="submit" value="{% trans %}add{% endtrans%}"/>
+ </div>
+ </div>
+ {%endif%}
+{% endblock %}
+{%block userjs%}
+ <script type='text/javascript'>
+ search = new FullTextSearch();
+ askbot['controllers'] = askbot['controllers'] || {}
+ askbot['controllers']['fullTextSearch'] = search;
+ askbot['urls']['mark_subscribed_tag'] = '{% url mark_subscribed_tag %}';
+ askbot['urls']['unmark_tag'] = '{% url unmark_tag %}';
+ </script>
+ <script type='text/javascript' src='{{"/js/tag_selector.js"|media}}'></script>
{% endblock %}
<!-- end user_email_subscriptions.html -->
diff --git a/askbot/templates/user_profile/user_info.html b/askbot/templates/user_profile/user_info.html
index 89f06321..e6d24463 100644
--- a/askbot/templates/user_profile/user_info.html
+++ b/askbot/templates/user_profile/user_info.html
@@ -98,7 +98,7 @@
<tr>
<!--todo - redo this with whole sentence translation -->
<td>{% trans %}age{% endtrans %}</td>
- <td>{{view_user.date_of_birth|get_age}} {% trans %}age unit{% endtrans %}</td>
+ <td>{% trans age=view_user.date_of_birth|get_age%}{{ age }} years old{% endtrans %}</td>
</tr>
{% endif %}
{% if votes_today_left %}
diff --git a/askbot/templates/user_profile/user_stats.html b/askbot/templates/user_profile/user_stats.html
index dc3d97e0..c042b5fb 100644
--- a/askbot/templates/user_profile/user_stats.html
+++ b/askbot/templates/user_profile/user_stats.html
@@ -124,7 +124,7 @@
</span>
<ul id="badge-context-{{ badge.id }}" class="badge-context-list" style="display:none">
{% for award in badge_user_awards %}
- {% if award.content_object_is_post %}
+ {% if award.content_object and award.content_object_is_post %}
<li>
<a
title="{{ award.content_object.get_snippet()|collapse }}"
@@ -158,8 +158,5 @@
});
</script>
<script type='text/javascript' src='{{"/js/tag_selector.js"|media}}'></script>
- <script type="text/javascript">
- askbot['urls']['questions'] = '{% url "questions" %}';
- </script>
{% endblock %}
<!-- end user_stats.html -->
diff --git a/askbot/templates/users.html b/askbot/templates/users.html
index a1c4ed11..09a2c117 100644
--- a/askbot/templates/users.html
+++ b/askbot/templates/users.html
@@ -31,26 +31,26 @@
{% if settings.KARMA_MODE == 'public' %}
<a
id="sort_reputation"
- href="{{ request.path }}?sort=reputation"
+ href="{{ request.path|escape }}?sort=reputation"
{% if tab_id == 'reputation' %}class="on"{% endif %}
title="{% trans %}see people with the highest reputation{% endtrans %}"
><span>{% trans %}karma{% endtrans %}</span></a>
{% endif %}
<a
id="sort_newest"
- href="{{ request.path }}?sort=newest"
+ href="{{ request.path|escape }}?sort=newest"
{% if tab_id == 'newest' %}class="on"{% endif %}
class="off" title="{% trans %}see people who joined most recently{% endtrans %}"
><span>{% trans %}recent{% endtrans %}</span></a>
<a
id="sort_last"
- href="{{ request.path }}?sort=last"
+ href="{{ request.path|escape }}?sort=last"
{% if tab_id == 'last' %}class="on"{% endif %}
class="off" title="{% trans %}see people who joined the site first{% endtrans %}"
><span>{% trans %}oldest{% endtrans %}<span></a>
<a
id="sort_user"
- href="{{ request.path }}?sort=user"
+ href="{{ request.path|escape }}?sort=user"
{% if tab_id == 'user' %}class="on"{% endif %}
title="{% trans %}see people sorted by name{% endtrans %}"
><span>{% trans %}by username{% endtrans %}</span></a>
diff --git a/askbot/templates/widget_base.html b/askbot/templates/widget_base.html
index 44be3e5f..be5bf301 100644
--- a/askbot/templates/widget_base.html
+++ b/askbot/templates/widget_base.html
@@ -9,7 +9,7 @@
{% block forejs %}{% endblock %}
</head>
{% endspaceless %}
- <body class="lang-{{settings.LANGUAGE_CODE}}">
+ <body class="lang-{{ language_code }}">
{% block body%}
{% endblock %}
{% block content%}
diff --git a/askbot/templates/widgets/ask_form.html b/askbot/templates/widgets/ask_form.html
index 0f851fee..53b93158 100644
--- a/askbot/templates/widgets/ask_form.html
+++ b/askbot/templates/widgets/ask_form.html
@@ -1,16 +1,7 @@
{% import "macros.html" as macros %}
<form id="fmask" action="" method="post" >{% csrf_token %}
- <div class="form-item">
+ <div class="form-item ask-form-bar">
<div id="askFormBar">
- {% if not request.user.is_authenticated() %}
-<p>{% trans %}<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.{% endtrans %}</p>
- {% else %}
- {% if settings.EMAIL_VALIDATION %}
- {% if not request.user.email_isvalid %}
- {% trans email=request.user.email %}<span class='strong big'>Looks like your email address, %(email)s has not yet been validated.</span> To post messages you must verify your email, please see <a href='%(email_validation_faq_url)s'>more details here</a>.<br>You can submit your question now and validate email after that. Your question will saved as pending meanwhile.{% endtrans %}
- {% endif %}
- {% endif %}
- {% endif %}
<input id="id_title" class="questionTitleInput" name="title" autocomplete="off"
value="{% if form.initial.title %}{{form.initial.title|escape}}{% endif %}"/>
<span class="form-error">{{ form.title.errors }}</span>
@@ -19,7 +10,6 @@
{{ form.title.help_text }}
</div>
</div>
- <div id='question-list'></div>
{{
macros.edit_post(
form,
@@ -45,6 +35,12 @@
%}
{{ macros.checkbox_in_div(form.post_privately) }}
{% endif %}
+ {% if settings.MULTILINGUAL %}
+ <div class="lang-selector">
+ <label for="id_language">{% trans %}Select language{% endtrans %}</label>
+ {{ form.language }}
+ </div>
+ {% endif %}
</div>
{% if not request.user.is_authenticated() %}
<input type="submit" name="post_anon" value="{% trans %}Login/Signup to Post{% endtrans %}" class="submit" />
diff --git a/askbot/templates/widgets/edit_post.html b/askbot/templates/widgets/edit_post.html
index b9bfa1e3..9e9a3761 100644
--- a/askbot/templates/widgets/edit_post.html
+++ b/askbot/templates/widgets/edit_post.html
@@ -64,7 +64,7 @@
</div>
{% endif %}
{% if 'summary' in post_form['fields'] %}
- <div class="form-item">
+ <div class="form-item revision-comment">
<strong>{{ post_form.summary.label_tag() }}</strong> <br/>
{{ post_form.summary }}
<div class="title-desc">
@@ -83,6 +83,7 @@
[{% trans %}hide preview{% endtrans %}]
</span>
</div>
+ <div class="clearfix"></div>
<div id="previewer" class="wmd-preview"></div>
{% endif %}
diff --git a/askbot/templates/widgets/footer.html b/askbot/templates/widgets/footer.html
index 6eb3afc2..75721e50 100644
--- a/askbot/templates/widgets/footer.html
+++ b/askbot/templates/widgets/footer.html
@@ -46,7 +46,7 @@
"{{settings.FEEDBACK_SITE_URL}}"
target="_blank">
{% else %}
- "{% url feedback %}?next={{request.path}}">
+ "{% url feedback %}?next={{request.path|escape}}">
{% endif %}
{% trans %}give feedback{% endtrans %}
</a>
diff --git a/askbot/templates/widgets/language_nav.html b/askbot/templates/widgets/language_nav.html
new file mode 100644
index 00000000..a8b4c8d9
--- /dev/null
+++ b/askbot/templates/widgets/language_nav.html
@@ -0,0 +1,14 @@
+<span class="lang-nav">
+ <span>{{ settings.LANGUAGES_DICT[current_language_code] }}</span>
+ <ul>
+ {% for lang in settings.LANGUAGES_DICT %}
+ {% if lang != current_language_code %}
+ <li>
+ <a
+ href="/{{ lang }}/{{ settings.ASKBOT_URL }}"
+ >{{ settings.LANGUAGES_DICT[lang] }}</a>
+ </li>
+ {% endif %}
+ {% endfor %}
+ </ul>
+</span>
diff --git a/askbot/templates/widgets/markdown_help.html b/askbot/templates/widgets/markdown_help.html
index 9816fe26..cea8847b 100644
--- a/askbot/templates/widgets/markdown_help.html
+++ b/askbot/templates/widgets/markdown_help.html
@@ -17,7 +17,7 @@
</li>
{% endif %}
<li>
- <b>{% trans %}link{% endtrans %}</b>:[{% trans %}text{% endtrans %}](http://url.com/ "{% trans %}title{% endtrans %}")
+ <b>{% trans %}link{% endtrans %}</b>:[{% trans %}text{% endtrans %}](http://example.com/ "{% trans %}title{% endtrans %}")
</li>
<li>
diff --git a/askbot/templates/widgets/scope_nav.html b/askbot/templates/widgets/scope_nav.html
index a6bda630..b68d899c 100644
--- a/askbot/templates/widgets/scope_nav.html
+++ b/askbot/templates/widgets/scope_nav.html
@@ -1,3 +1,4 @@
+<div id="scopeNav">
{% if active_tab != "ask" %}
{% if not search_state %} {# get empty SearchState() if there's none #}
{% set search_state=search_state|get_empty_search_state %}
@@ -13,3 +14,4 @@
{% else %}
<div class="scope-selector ask-message">{% trans %}Please ask your question here{% endtrans %}</div>
{% endif %}
+</div>
diff --git a/askbot/templates/widgets/search_bar.html b/askbot/templates/widgets/search_bar.html
index 59c4fd58..8c485c73 100644
--- a/askbot/templates/widgets/search_bar.html
+++ b/askbot/templates/widgets/search_bar.html
@@ -1,17 +1,7 @@
{% if active_tab != "ask" %}
{% spaceless %}
-<div id="searchBar">
+<div id="searchBar" {% if query %}class="cancelable"{% endif %}>
{# url action depends on which tab is active #}
- <form
- {% if active_tab == "tags" %}
- action="{% url tags %}"
- {% elif active_tab == "users" %}
- action="{% url users %}"
- {% else %}
- action="{% url questions %}" id="searchForm"
- {% endif %}
- method="get">
- <input type="submit" value="" name="search" class="searchBtn" />
{% if active_tab == "tags" %}
<input type="hidden" name="t" value="tag"/>
{% else %}
@@ -21,26 +11,13 @@
{% endif %}
{# class was searchInput #}
<input
- {% if query %}
- class="searchInputCancelable"
- {% else %}
class="searchInput"
- {% endif %}
type="text"
autocomplete="off"
value="{{ query|default_if_none('') }}"
name="query"
id="keywords"
/>
- <input type="button"
- value="X"
- name="reset_query"
- class="cancelSearchBtn"
- {% if not query %}{# query is only defined by questions view (active_tab) #}
- style="display: none;"
- {% endif %}
- />
- </form>
</div>
{% endspaceless %}
{% endif %}
diff --git a/askbot/templates/widgets/secondary_header.html b/askbot/templates/widgets/secondary_header.html
index caf190bc..defd7148 100644
--- a/askbot/templates/widgets/secondary_header.html
+++ b/askbot/templates/widgets/secondary_header.html
@@ -1,12 +1,45 @@
<!-- template secondary_header.html -->
<div id="secondaryHeader">
<div class="content-wrapper">
- <a id="homeButton" href="{% url questions %}"></a>
- <div id="scopeWrapper">
- {% include "widgets/scope_nav.html" %}
+ {# form is wrapping search buttons and the search bar inputs #}
+ <form
+ {% if active_tab == "tags" %}
+ action="{% url tags %}"
+ {% elif active_tab == "users" %}
+ action=""
+ {% else %}
+ action="{% url questions %}" id="searchForm"
+ {% endif %}
+ 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
+ #}
+ {% include "widgets/ask_button.html" %}
+ <input type="submit" value="" name="search" class="searchBtn" />
+ <input type="button"
+ value="X"
+ name="reset_query"
+ class="cancelSearchBtn"
+ {% if not query %}{# query is only defined by questions view (active_tab) #}
+ style="display: none;"
+ {% endif %}
+ />
+ {# clears button floats #}
+ <div class="clearfix"></div>
+ </div>
{% include "widgets/search_bar.html" %} {# include search form widget #}
- </div>
- {% include "widgets/ask_button.html" %}
- <div class="clean"></div>
+ </form>
</div>
</div>
diff --git a/askbot/templates/widgets/user_long_score_and_badge_summary.html b/askbot/templates/widgets/user_long_score_and_badge_summary.html
index efc59c55..65966376 100644
--- a/askbot/templates/widgets/user_long_score_and_badge_summary.html
+++ b/askbot/templates/widgets/user_long_score_and_badge_summary.html
@@ -1,10 +1,10 @@
+{% set have_badges = user.gold or user.silver or user.bronze %}
{%- if karma_mode != 'hidden' -%}
<a class="user-micro-info"
href="{{user.get_absolute_url()}}?sort=reputation"
->{% trans %}karma:{% endtrans %} {{user.reputation}}</a>
+>{% trans %}karma:{% endtrans %} {{user.reputation}}</a>{% if badges_mode == 'public' and have_badges %},{% endif %}
{%- endif -%}
-{% if badges_mode == 'public' %}
- {%- if user.gold or user.silver or user.bronze %}
+{% if badges_mode == 'public' and have_badges %}
<a class="user-micro-info"
href="{{user.get_absolute_url()}}#badges"
><span title="{{user.get_badge_summary}}">{% trans %}badges:{% endtrans %}
@@ -21,5 +21,4 @@
<span class="badgecount">{{user.bronze}}</span>
{%- endif -%}
</span></a>
- {%- endif -%}
{%- endif -%}
diff --git a/askbot/templates/widgets/user_navigation.html b/askbot/templates/widgets/user_navigation.html
index 06b0cdb9..9cde343c 100644
--- a/askbot/templates/widgets/user_navigation.html
+++ b/askbot/templates/widgets/user_navigation.html
@@ -17,10 +17,10 @@
<a href="{{ settings.LOGOUT_URL }}?next={{ settings.LOGOUT_REDIRECT_URL }}">{% trans %}sign out{% endtrans %}</a>
{% endif %}
{% elif settings.USE_ASKBOT_LOGIN_SYSTEM %}
- <a href="{{ settings.LOGIN_URL }}?next={{request.path|clean_login_url}}">{% trans %}Hi there! Please sign in{% endtrans %}</a>
+ <a href="{{ settings.LOGIN_URL }}?next={{request.path|clean_login_url|escape}}">{% trans %}Hi there! Please sign in{% endtrans %}</a>
{% endif %}
{% if request.user.is_authenticated() and request.user.is_administrator() %}
- <a href="{% url site_settings %}">{% trans %}settings{% endtrans %}</a>
- <a href="{% url widgets %}">{% trans %}widgets{% endtrans %}</a>
+ <a class="settings" href="{% url site_settings %}">{% trans %}settings{% endtrans %}</a>
+ <a class="widgets" href="{% url widgets %}">{% trans %}widgets{% endtrans %}</a>
{% endif %}
- <a href="{% url "help" %}" title="{% trans %}help{% endtrans %}">{% trans %}help{% endtrans %}</a>
+ <a class="help" href="{% url "help" %}" title="{% trans %}help{% endtrans %}">{% trans %}help{% endtrans %}</a>
diff --git a/askbot/templatetags/extra_filters_jinja.py b/askbot/templatetags/extra_filters_jinja.py
index 146de6d1..e927ccbf 100644
--- a/askbot/templatetags/extra_filters_jinja.py
+++ b/askbot/templatetags/extra_filters_jinja.py
@@ -6,6 +6,7 @@ import urllib
from coffin import template as coffin_template
from django.core import exceptions as django_exceptions
from django.utils.translation import ugettext as _
+from django.utils.translation import get_language as django_get_language
from django.contrib.humanize.templatetags import humanize
from django.template import defaultfilters
from django.core.urlresolvers import reverse, resolve
@@ -38,6 +39,10 @@ def add_tz_offset(datetime_object):
return str(datetime_object) + ' ' + TIMEZONE_STR
@register.filter
+def is_current_language(lang):
+ return lang == django_get_language()
+
+@register.filter
def safe_urlquote(text, quote_plus = False):
if quote_plus:
return urllib.quote_plus(text.encode('utf8'))
diff --git a/askbot/templatetags/extra_tags.py b/askbot/templatetags/extra_tags.py
index dc9da5fc..a74438de 100644
--- a/askbot/templatetags/extra_tags.py
+++ b/askbot/templatetags/extra_tags.py
@@ -1,11 +1,12 @@
import math
from django import template
+from django.template import RequestContext
+from django.template.loader import get_template
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from askbot.utils import functions
from askbot.utils.slug import slugify
-from askbot.skins.loaders import get_template
from askbot.conf import settings as askbot_settings
register = template.Library()
@@ -14,7 +15,7 @@ GRAVATAR_TEMPLATE = (
'<a style="text-decoration:none" '
'href="%(user_profile_url)s"><img class="gravatar" '
'width="%(size)s" height="%(size)s" '
- 'src="http://www.gravatar.com/avatar/%(gravatar_hash)s'
+ 'src="//www.gravatar.com/avatar/%(gravatar_hash)s'
'?s=%(size)s&amp;d=%(gravatar_type)s&amp;r=PG" '
'title="%(username)s" '
'alt="%(alt_text)s" /></a>')
@@ -90,8 +91,8 @@ class IncludeJinja(template.Node):
self.request_var = template.Variable(request_var)
def render(self, context):
request = self.request_var.resolve(context)
- jinja_template = get_template(self.filename, request)
- return jinja_template.render(context)
+ jinja_template = get_template(self.filename)
+ return jinja_template.render(RequestContext(request, context))
@register.tag
def include_jinja(parser, token):
@@ -112,4 +113,3 @@ def include_jinja(parser, token):
raise template.TemplateSyntaxError('file name must be quoted')
return IncludeJinja(filename, request_var)
-
diff --git a/askbot/tests/badge_tests.py b/askbot/tests/badge_tests.py
index c184db6f..91c6b349 100644
--- a/askbot/tests/badge_tests.py
+++ b/askbot/tests/badge_tests.py
@@ -1,5 +1,6 @@
import datetime
from django.conf import settings as django_settings
+from django.core.urlresolvers import reverse
from django.test.client import Client
from askbot.tests.utils import AskbotTestCase
from askbot.conf import settings
@@ -502,6 +503,6 @@ class BadgeTests(AskbotTestCase):
self.u1.save()
self.assert_have_badge('enthusiast', self.u1, 0)
self.client.login(method = 'force', user_id = self.u1.id)
- self.client.get('/' + django_settings.ASKBOT_URL)
+ self.client.get(reverse('questions'))
self.assert_have_badge('enthusiast', self.u1, 1)
diff --git a/askbot/tests/db_api_tests.py b/askbot/tests/db_api_tests.py
index 0af6d955..91c25867 100644
--- a/askbot/tests/db_api_tests.py
+++ b/askbot/tests/db_api_tests.py
@@ -184,7 +184,7 @@ class DBApiTests(AskbotTestCase):
saved_question = models.Post.objects.get_questions().get(id = self.question.id)
self.assertTrue(saved_question.thread.answer_count == 1)
- def test_unused_tag_is_auto_deleted(self):
+ def test_unused_tag_is_not_auto_deleted(self):
self.user.retag_question(self.question, tags='one-tag')
tag = models.Tag.objects.get(name='one-tag')
self.assertEquals(tag.used_count, 1)
@@ -192,7 +192,7 @@ class DBApiTests(AskbotTestCase):
self.user.retag_question(self.question, tags='two-tag')
count = models.Tag.objects.filter(name='one-tag').count()
- self.assertEquals(count, 0)
+ self.assertEquals(count, 1)
@with_settings(MAX_TAG_LENGTH=200, MAX_TAGS_PER_POST=50)
def test_retag_tags_too_long_raises(self):
diff --git a/askbot/tests/email_alert_tests.py b/askbot/tests/email_alert_tests.py
index bdb361e5..d11890a8 100644
--- a/askbot/tests/email_alert_tests.py
+++ b/askbot/tests/email_alert_tests.py
@@ -576,6 +576,16 @@ class InstantWholeForumEmailAlertTests(EmailAlertTests):
self.expected_results['q_ans'] = {'message_count': 1, }
self.expected_results['q_ans_new_answer'] = {'message_count': 2, }
+ def test_global_subscriber_with_zero_frequency_gets_no_email(self):
+ user = self.target_user
+ user.notification_subscriptions.update(frequency='n')
+ user.email_tag_filter_strategy = const.INCLUDE_ALL
+ user.save()
+ self.post_question(author=self.other_user)
+ outbox = django.core.mail.outbox
+ self.assertEqual(len(outbox), 0)
+
+
class BlankWeeklySelectedQuestionsEmailAlertTests(EmailAlertTests):
"""blank means that this is testing for the absence of email
because questions are not followed as set by default in the
@@ -739,12 +749,12 @@ class FeedbackTests(utils.AskbotTestCase):
class TagFollowedInstantWholeForumEmailAlertTests(utils.AskbotTestCase):
def setUp(self):
- self.create_user(
+ self.user1 = self.create_user(
username = 'user1',
notification_schedule = {'q_all': 'i'},
status = 'm'
)
- self.create_user(
+ self.user2 = self.create_user(
username = 'user2',
status = 'm'
)
@@ -773,7 +783,8 @@ class TagFollowedInstantWholeForumEmailAlertTests(utils.AskbotTestCase):
self.user1.email in outbox[0].recipients()
)
- def test_tag_based_subscription_on_new_question_works(self):
+ @with_settings(SUBSCRIBED_TAG_SELECTOR_ENABLED=False)
+ def test_tag_based_subscription_on_new_question_works1(self):
"""someone subscribes for an pre-existing tag
then another user asks a question with that tag
and the subcriber receives an alert
@@ -802,6 +813,36 @@ class TagFollowedInstantWholeForumEmailAlertTests(utils.AskbotTestCase):
self.user1.email in outbox[0].recipients()
)
+ @with_settings(SUBSCRIBED_TAG_SELECTOR_ENABLED=True)
+ def test_tag_based_subscription_on_new_question_works1(self):
+ """someone subscribes for an pre-existing tag
+ then another user asks a question with that tag
+ and the subcriber receives an alert
+ """
+ models.Tag(
+ name = 'something',
+ created_by = self.user1
+ ).save()
+
+ self.user1.email_tag_filter_strategy = const.INCLUDE_SUBSCRIBED
+ self.user1.save()
+ self.user1.mark_tags(
+ tagnames = ('something',),
+ reason = 'subscribed',
+ action = 'add'
+ )
+ self.user2.post_question(
+ title = 'some title',
+ body_text = 'some text for the question',
+ tags = 'something'
+ )
+ outbox = django.core.mail.outbox
+ self.assertEqual(len(outbox), 1)
+ self.assertEqual(len(outbox[0].recipients()), 1)
+ self.assertTrue(
+ self.user1.email in outbox[0].recipients()
+ )
+
class EmailReminderTestCase(utils.AskbotTestCase):
#subclass must define these (example below)
#enable_setting_name = 'ENABLE_UNANSWERED_REMINDERS'
diff --git a/askbot/tests/email_parsing_tests.py b/askbot/tests/email_parsing_tests.py
index 6cc5e576..3ed0908a 100644
--- a/askbot/tests/email_parsing_tests.py
+++ b/askbot/tests/email_parsing_tests.py
@@ -1,11 +1,12 @@
+# -*- coding: utf-8 -*-
from django.conf import settings as django_settings
-from askbot.skins.loaders import get_template
from django.template import Context
+from django.template.loader import get_template
from askbot import mail
from askbot import models
from askbot.tests import utils
-class EmailParseTests(utils.AskbotTestCase):
+class EmailParsingTests(utils.AskbotTestCase):
def setUp(self):
self.template_name = 'email/welcome_lamson_on.html'
@@ -22,12 +23,38 @@ class EmailParseTests(utils.AskbotTestCase):
print '=================================================='
print cleaned_body
print "CLEANED BODY"
- self.assertEquals(cleaned_body, self.expected_output)
+ self.assertEqual(cleaned_body, self.expected_output)
-"""collection of quote separators separated with an empty line
-u'\n\nthis is my reply!\n\nOn Wed, Oct 31, 2012 at 1:45 AM, <kp@kp-dev.askbot.com> wrote:\n\n> **\n> '
+ def test_gmail_rich_text_response_stripped(self):
+ text = u'\n\nthis is my reply!\n\nOn Wed, Oct 31, 2012 at 1:45 AM, <kp@kp-dev.askbot.com> wrote:\n\n> **\n> '
+ self.assertEqual(mail.extract_reply(text), 'this is my reply!')
-u'\n\nthis is my another reply!\n\nOn Wed, Oct 31, 2012 at 1:45 AM, <kp@kp-dev.askbot.com> wrote:\n>\n> '
+ def test_gmail_plain_text_response_stripped(self):
+ text = u'\n\nthis is my another reply!\n\nOn Wed, Oct 31, 2012 at 1:45 AM, <kp@kp-dev.askbot.com> wrote:\n>\n> '
+ self.assertEqual(mail.extract_reply(text), 'this is my another reply!')
-u'\n\nSending this from my yahoo mail account.\n\n\n\n________________________________\n From: "kp@kp-dev.askbot.com" <kp@kp-dev.askbot.com>\nTo: fadeev@rocketmail.com \nSent: Wednesday, October 31, 2012 2:41 AM\nSubject: "This is my test question"\n \n\n \n \n \n'
-"""
+ def test_yahoo_mail_response_stripped(self):
+ text = u'\n\nthis is my reply!\n\n\n\n________________________________\n From: "kp@kp-dev.askbot.com" <kp@kp-dev.askbot.com>\nTo: fadeev@rocketmail.com \nSent: Wednesday, October 31, 2012 2:41 AM\nSubject: "This is my test question"\n \n\n \n \n \n'
+ self.assertEqual(mail.extract_reply(text), 'this is my reply!')
+
+ def test_kmail_plain_text_response_stripped(self):
+ text = u'On Monday 01 October 2012 21:22:44 you wrote: \n\nthis is my reply!'
+ self.assertEqual(mail.extract_reply(text), 'this is my reply!')
+
+ def test_outlook_com_with_rtf_response_stripped(self):
+ text = u'outlook.com (new hotmail) with RTF on \n\nSubject: "Posting a question by email." \nFrom: kp@kp-dev.askbot.com \nTo: aj_fitoria@hotmail.com \nDate: Thu, 1 Nov 2012 16:30:27 +0000'
+ self.assertEqual(
+ mail.extract_reply(text),
+ 'outlook.com (new hotmail) with RTF on'
+ )
+ self.assertEqual(
+ mail.extract_reply(text),
+ 'outlook.com (new hotmail) with RTF on'
+ )
+
+ def test_outlook_com_plain_text_response_stripped(self):
+ text = u'reply from hotmail without RTF \n________________________________ \n> Subject: "test with recovered signature" \n> From: kp@kp-dev.askbot.com \n> To: aj_fitoria@hotmail.com \n> Date: Thu, 1 Nov 2012 16:44:35 +0000'
+ self.assertEqual(
+ mail.extract_reply(text),
+ u'reply from hotmail without RTF'
+ )
diff --git a/askbot/tests/page_load_tests.py b/askbot/tests/page_load_tests.py
index 4efac0f0..c4ee8554 100644
--- a/askbot/tests/page_load_tests.py
+++ b/askbot/tests/page_load_tests.py
@@ -6,6 +6,7 @@ from django.core import management
from django.core.cache.backends.dummy import DummyCache
from django.core import cache
from django.utils import simplejson
+from django.utils.translation import activate as activate_language
import coffin
import coffin.template
@@ -20,7 +21,6 @@ from askbot.tests.utils import skipIf
from askbot.tests.utils import with_settings
-
def patch_jinja2():
from jinja2 import Template
ORIG_JINJA2_RENDERER = Template.render
@@ -54,6 +54,7 @@ class PageLoadTestCase(AskbotTestCase):
@classmethod
def setUpClass(cls):
management.call_command('flush', verbosity=0, interactive=False)
+ activate_language(settings.LANGUAGE_CODE)
management.call_command('askbot_add_test_content', verbosity=0, interactive=False)
@classmethod
@@ -104,6 +105,9 @@ class PageLoadTestCase(AskbotTestCase):
if hasattr(self.client, 'redirect_chain'):
print 'redirect chain: %s' % ','.join(self.client.redirect_chain)
+ if r.status_code != status_code:
+ print 'Error in status code for url: %s' % url
+
self.assertEqual(r.status_code, status_code)
if template and status_code != 302:
@@ -135,7 +139,8 @@ class PageLoadTestCase(AskbotTestCase):
response = self.client.get(reverse('index'), follow=True)
self.assertEqual(response.status_code, 200)
self.failUnless(len(response.redirect_chain) == 1)
- self.failUnless(response.redirect_chain[0][0].endswith('/questions/'))
+ redirect_url = response.redirect_chain[0][0]
+ self.failUnless(unicode(redirect_url).endswith('/questions/'))
self.assertTrue(isinstance(response.template, list))
self.assertIn('main_page.html', [t.name for t in response.template])
@@ -153,14 +158,14 @@ class PageLoadTestCase(AskbotTestCase):
self.proto_test_ask_page(True, 200)
@with_settings(GROUPS_ENABLED=False)
- def test_api_get_questions_groups_disabled(self):
- data = {'query': 'Question'}
- response = self.client.get(reverse('api_get_questions'), data)
+ def test_title_search_groups_disabled(self):
+ data = {'query_text': 'Question'}
+ response = self.client.get(reverse('title_search'), data)
data = simplejson.loads(response.content)
self.assertTrue(len(data) > 1)
@with_settings(GROUPS_ENABLED=True)
- def test_api_get_questions_groups_enabled(self):
+ def test_title_search_groups_enabled(self):
group = models.Group(name='secret group', openness=models.Group.OPEN)
group.save()
@@ -169,14 +174,14 @@ class PageLoadTestCase(AskbotTestCase):
question = self.post_question(user=user, title='alibaba', group_id=group.id)
#ask for data anonymously - should get nothing
- query_data = {'query': 'alibaba'}
- response = self.client.get(reverse('api_get_questions'), query_data)
+ query_data = {'query_text': 'alibaba'}
+ response = self.client.get(reverse('title_search'), query_data)
response_data = simplejson.loads(response.content)
self.assertEqual(len(response_data), 0)
#log in - should get the question
self.client.login(method='force', user_id=user.id)
- response = self.client.get(reverse('api_get_questions'), query_data)
+ response = self.client.get(reverse('title_search'), query_data)
response_data = simplejson.loads(response.content)
self.assertEqual(len(response_data), 1)
@@ -194,19 +199,17 @@ class PageLoadTestCase(AskbotTestCase):
'get_groups_list',
status_code=status_code
)
+ #self.try_url(
+ # 'individual_question_feed',
+ # kwargs={'pk':'one-tag'},
+ # status_code=status_code)
self.try_url(
- 'feeds',
- status_code=status_code,
- kwargs={'url':'rss'})
+ 'latest_questions_feed',
+ status_code=status_code)
self.try_url(
- 'feeds',
- kwargs={'url':'rss'},
+ 'latest_questions_feed',
data={'tags':'one-tag'},
status_code=status_code)
- #self.try_url(
- # 'feeds',
- # kwargs={'url':'question'},
- # status_code=status_code)
self.try_url(
'about',
status_code=status_code,
@@ -722,3 +725,71 @@ class CommandViewTests(AskbotTestCase):
def test_load_object_description_fails(self):
response = self.client.get(reverse('load_object_description'))
self.assertEqual(response.status_code, 404)#bad request
+
+ def test_set_tag_filter_strategy(self):
+ user = self.create_user('someuser')
+
+ def run_test_for_setting(self, filter_type, value):
+ response = self.client.post(
+ reverse('set_tag_filter_strategy'),
+ data={
+ 'filter_type': filter_type,
+ 'filter_value': value
+ },
+ HTTP_X_REQUESTED_WITH='XMLHttpRequest'
+ )
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.content, '')
+
+ self.client.login(user_id=user.id, method='force')
+
+ from askbot import conf
+ values = dict(conf.get_tag_email_filter_strategy_choices()).keys()
+ for value in values:
+ run_test_for_setting(self, 'email', value)
+ user = self.reload_object(user)
+ self.assertEqual(user.email_tag_filter_strategy, value)
+
+ values = dict(conf.get_tag_display_filter_strategy_choices()).keys()
+ for value in values:
+ run_test_for_setting(self, 'display', value)
+ user = self.reload_object(user)
+ self.assertEqual(user.display_tag_filter_strategy, value)
+
+
+class UserProfilePageTests(AskbotTestCase):
+ def setUp(self):
+ self.user = self.create_user('user')
+
+ @with_settings(EDITABLE_EMAIL=False)
+ def test_user_cannot_change_email(self):
+ #log in
+ self.client.login(user_id=self.user.id, method='force')
+ email_before = self.user.email
+ response = self.client.post(
+ reverse('edit_user', kwargs={'id': self.user.id}),
+ data={
+ 'username': 'edited',
+ 'email': 'fake@example.com'
+ }
+ )
+ self.assertEqual(response.status_code, 302)
+ user = self.reload_object(self.user)
+ self.assertEqual(user.username, 'edited')
+ self.assertEqual(user.email, email_before)
+
+ @with_settings(EDITABLE_EMAIL=True)
+ def test_user_can_change_email(self):
+ self.client.login(user_id=self.user.id, method='force')
+ email_before = self.user.email
+ response = self.client.post(
+ reverse('edit_user', kwargs={'id': self.user.id}),
+ data={
+ 'username': 'edited',
+ 'email': 'new@example.com'
+ }
+ )
+ self.assertEqual(response.status_code, 302)
+ user = self.reload_object(self.user)
+ self.assertEqual(user.username, 'edited')
+ self.assertEqual(user.email, 'new@example.com')
diff --git a/askbot/tests/post_model_tests.py b/askbot/tests/post_model_tests.py
index e61fcd2d..cad58388 100644
--- a/askbot/tests/post_model_tests.py
+++ b/askbot/tests/post_model_tests.py
@@ -3,13 +3,13 @@ import datetime
from operator import attrgetter
import time
from askbot.search.state_manager import SearchState
-from askbot.skins.loaders import get_template
from django.contrib.auth.models import User
from django.core import cache, urlresolvers
from django.core.cache.backends.dummy import DummyCache
from django.core.cache.backends.locmem import LocMemCache
from django.core.exceptions import ValidationError
+from django.template.loader import get_template
from askbot.tests.utils import AskbotTestCase
from askbot.models import Post
from askbot.models import PostRevision
@@ -126,17 +126,21 @@ class PostModelTests(AskbotTestCase):
th.title = 'lala-x-lala'
p = Post(id=3, post_type='question')
p._thread_cache = th # cannot assign non-Thread instance directly
- self.assertEqual('/question/3/lala-x-lala/', p.get_absolute_url(thread=th))
+ expected_url = urlresolvers.reverse('question', kwargs={'id': 3}) \
+ + th.title + '/'
+ self.assertEqual(expected_url, p.get_absolute_url(thread=th))
self.assertTrue(p._thread_cache is th)
- self.assertEqual('/question/3/lala-x-lala/', p.get_absolute_url(thread=th))
+ self.assertEqual(expected_url, p.get_absolute_url(thread=th))
def test_cached_get_absolute_url_2(self):
p = Post(id=3, post_type='question')
th = lambda:1
th.title = 'lala-x-lala'
- self.assertEqual('/question/3/lala-x-lala/', p.get_absolute_url(thread=th))
+ expected_url = urlresolvers.reverse('question', kwargs={'id': 3}) \
+ + th.title + '/'
+ self.assertEqual(expected_url, p.get_absolute_url(thread=th))
self.assertTrue(p._thread_cache is th)
- self.assertEqual('/question/3/lala-x-lala/', p.get_absolute_url(thread=th))
+ self.assertEqual(expected_url, p.get_absolute_url(thread=th))
def test_get_moderators_with_groups(self):
groups_enabled_backup = askbot_settings.GROUPS_ENABLED
diff --git a/askbot/tests/question_views_tests.py b/askbot/tests/question_views_tests.py
index 223f65f6..9486b854 100644
--- a/askbot/tests/question_views_tests.py
+++ b/askbot/tests/question_views_tests.py
@@ -32,7 +32,7 @@ class PrivateQuestionViewsTests(AskbotTestCase):
response2 = self.client.get(response1['location'])
dom = BeautifulSoup(response2.content)
title = dom.find('h1').text
- self.assertTrue(const.POST_STATUS['private'] in title)
+ self.assertTrue(unicode(const.POST_STATUS['private']) in title)
question = models.Thread.objects.get(id=1)
self.assertEqual(question.title, self.qdata['title'])
self.assertFalse(models.Group.objects.get_global_group() in set(question.groups.all()))
@@ -54,7 +54,7 @@ class PrivateQuestionViewsTests(AskbotTestCase):
def test_publish_private_question(self):
question = self.post_question(user=self.user, is_private=True)
title = question.thread.get_title()
- self.assertTrue(const.POST_STATUS['private'] in title)
+ self.assertTrue(unicode(const.POST_STATUS['private']) in title)
data = self.qdata
#data['post_privately'] = 'false'
data['select_revision'] = 'false'
@@ -76,7 +76,7 @@ class PrivateQuestionViewsTests(AskbotTestCase):
def test_privatize_public_question(self):
question = self.post_question(user=self.user)
title = question.thread.get_title()
- self.assertFalse(const.POST_STATUS['private'] in title)
+ self.assertFalse(unicode(const.POST_STATUS['private']) in title)
data = self.qdata
data['post_privately'] = 'checked'
data['select_revision'] = 'false'
@@ -88,7 +88,7 @@ class PrivateQuestionViewsTests(AskbotTestCase):
dom = BeautifulSoup(response2.content)
title = dom.find('h1').text
self.assertFalse(models.Group.objects.get_global_group() in set(question.groups.all()))
- self.assertTrue(const.POST_STATUS['private'] in title)
+ self.assertTrue(unicode(const.POST_STATUS['private']) in title)
def test_private_checkbox_is_on_when_editing_private_question(self):
question = self.post_question(user=self.user, is_private=True)
diff --git a/askbot/tests/reply_by_email_tests.py b/askbot/tests/reply_by_email_tests.py
index 30cb48be..ec63e38a 100644
--- a/askbot/tests/reply_by_email_tests.py
+++ b/askbot/tests/reply_by_email_tests.py
@@ -1,4 +1,4 @@
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from askbot.models import ReplyAddress
from askbot.mail.lamson_handlers import PROCESS, VALIDATE_EMAIL, get_parts
from askbot.mail import extract_user_signature
@@ -84,8 +84,8 @@ class ReplyAddressModelTests(AskbotTestCase):
'instruction': 'reply above this line'
}
msg = MockMessage(
- "This is a test reply \n\nOn such and such someone"
- "wrote something \n\n%s\nlorem ipsum " % (reply_separator),
+ "This is a test reply \n\nOn such and such someone "
+ "wrote: \n\n%s\nlorem ipsum " % (reply_separator),
"user1@domain.com"
)
msg['Subject'] = 'test subject'
diff --git a/askbot/tests/skin_tests.py b/askbot/tests/skin_tests.py
index 5226e6d6..96bb7d43 100644
--- a/askbot/tests/skin_tests.py
+++ b/askbot/tests/skin_tests.py
@@ -1,20 +1,23 @@
import os
import shutil
+import tempfile
from django.test import TestCase
from django.core.files.uploadedfile import UploadedFile
from django.conf import settings as django_settings
from askbot.conf import settings as askbot_settings
-from askbot.utils.path import mkdir_p
from askbot.skins import utils as skin_utils
+from askbot.utils.path import mkdir_p
import askbot
class SkinTests(TestCase):
def setUp(self):
#create dummy skin
+ self.temp_dir = tempfile.mkdtemp()
+ self.skins_dir_backup = getattr(django_settings, 'ASKBOT_EXTRA_SKINS_DIR', None)
+ setattr(django_settings, 'ASKBOT_EXTRA_SKINS_DIR', self.temp_dir)
skin_image_dir = os.path.join(
- askbot.get_install_directory(),
- 'skins',
+ self.temp_dir,
'test_skin',
'media',
'images'
@@ -31,12 +34,15 @@ class SkinTests(TestCase):
def tearDown(self):
#delete the dummy skin
test_skin_dir = os.path.join(
- askbot.get_install_directory(),
- 'skins',
+ self.temp_dir,
'test_skin'
)
- shutil.rmtree(test_skin_dir)
+ shutil.rmtree(self.temp_dir)
askbot_settings.update('ASKBOT_DEFAULT_SKIN', 'default')
+ if self.skins_dir_backup is None:
+ del(django_settings.ASKBOT_EXTRA_SKINS_DIR)
+ else:
+ django_settings.ASKBOT_EXTRA_SKINS_DIR = self.skins_dir_backup
def assert_default_logo_in_skin(self, skin_name):
url = skin_utils.get_media_url(askbot_settings.SITE_LOGO_URL)
@@ -62,5 +68,5 @@ class SkinTests(TestCase):
askbot_settings.update('SITE_LOGO_URL', new_logo)
logo_url = askbot_settings.SITE_LOGO_URL
self.assertTrue(logo_url.startswith(django_settings.MEDIA_URL))
- response = self.client.get(logo_url)
+ response = self.client.get(logo_url, follow=True)
self.assertTrue(response.status_code == 200)
diff --git a/askbot/tests/test_data.json b/askbot/tests/test_data.json
deleted file mode 100644
index b8050889..00000000
--- a/askbot/tests/test_data.json
+++ /dev/null
@@ -1,12264 +0,0 @@
-[
- {
- "pk": 22,
- "model": "auth.permission",
- "fields": {
- "codename": "add_logentry",
- "name": "Can add log entry",
- "content_type": 8
- }
- },
- {
- "pk": 23,
- "model": "auth.permission",
- "fields": {
- "codename": "change_logentry",
- "name": "Can change log entry",
- "content_type": 8
- }
- },
- {
- "pk": 24,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_logentry",
- "name": "Can delete log entry",
- "content_type": 8
- }
- },
- {
- "pk": 37,
- "model": "auth.permission",
- "fields": {
- "codename": "add_activity",
- "name": "Can add activity",
- "content_type": 13
- }
- },
- {
- "pk": 38,
- "model": "auth.permission",
- "fields": {
- "codename": "change_activity",
- "name": "Can change activity",
- "content_type": 13
- }
- },
- {
- "pk": 39,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_activity",
- "name": "Can delete activity",
- "content_type": 13
- }
- },
- {
- "pk": 34,
- "model": "auth.permission",
- "fields": {
- "codename": "add_activityauditstatus",
- "name": "Can add activity audit status",
- "content_type": 12
- }
- },
- {
- "pk": 35,
- "model": "auth.permission",
- "fields": {
- "codename": "change_activityauditstatus",
- "name": "Can change activity audit status",
- "content_type": 12
- }
- },
- {
- "pk": 36,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_activityauditstatus",
- "name": "Can delete activity audit status",
- "content_type": 12
- }
- },
- {
- "pk": 73,
- "model": "auth.permission",
- "fields": {
- "codename": "add_anonymousanswer",
- "name": "Can add anonymous answer",
- "content_type": 25
- }
- },
- {
- "pk": 74,
- "model": "auth.permission",
- "fields": {
- "codename": "change_anonymousanswer",
- "name": "Can change anonymous answer",
- "content_type": 25
- }
- },
- {
- "pk": 75,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_anonymousanswer",
- "name": "Can delete anonymous answer",
- "content_type": 25
- }
- },
- {
- "pk": 67,
- "model": "auth.permission",
- "fields": {
- "codename": "add_anonymousquestion",
- "name": "Can add anonymous question",
- "content_type": 23
- }
- },
- {
- "pk": 68,
- "model": "auth.permission",
- "fields": {
- "codename": "change_anonymousquestion",
- "name": "Can change anonymous question",
- "content_type": 23
- }
- },
- {
- "pk": 69,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_anonymousquestion",
- "name": "Can delete anonymous question",
- "content_type": 23
- }
- },
- {
- "pk": 70,
- "model": "auth.permission",
- "fields": {
- "codename": "add_answer",
- "name": "Can add answer",
- "content_type": 24
- }
- },
- {
- "pk": 71,
- "model": "auth.permission",
- "fields": {
- "codename": "change_answer",
- "name": "Can change answer",
- "content_type": 24
- }
- },
- {
- "pk": 72,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_answer",
- "name": "Can delete answer",
- "content_type": 24
- }
- },
- {
- "pk": 28,
- "model": "auth.permission",
- "fields": {
- "codename": "add_award",
- "name": "Can add award",
- "content_type": 10
- }
- },
- {
- "pk": 29,
- "model": "auth.permission",
- "fields": {
- "codename": "change_award",
- "name": "Can change award",
- "content_type": 10
- }
- },
- {
- "pk": 30,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_award",
- "name": "Can delete award",
- "content_type": 10
- }
- },
- {
- "pk": 25,
- "model": "auth.permission",
- "fields": {
- "codename": "add_badgedata",
- "name": "Can add badge data",
- "content_type": 9
- }
- },
- {
- "pk": 26,
- "model": "auth.permission",
- "fields": {
- "codename": "change_badgedata",
- "name": "Can change badge data",
- "content_type": 9
- }
- },
- {
- "pk": 27,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_badgedata",
- "name": "Can delete badge data",
- "content_type": 9
- }
- },
- {
- "pk": 46,
- "model": "auth.permission",
- "fields": {
- "codename": "add_comment",
- "name": "Can add comment",
- "content_type": 16
- }
- },
- {
- "pk": 47,
- "model": "auth.permission",
- "fields": {
- "codename": "change_comment",
- "name": "Can change comment",
- "content_type": 16
- }
- },
- {
- "pk": 48,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_comment",
- "name": "Can delete comment",
- "content_type": 16
- }
- },
- {
- "pk": 40,
- "model": "auth.permission",
- "fields": {
- "codename": "add_emailfeedsetting",
- "name": "Can add email feed setting",
- "content_type": 14
- }
- },
- {
- "pk": 41,
- "model": "auth.permission",
- "fields": {
- "codename": "change_emailfeedsetting",
- "name": "Can change email feed setting",
- "content_type": 14
- }
- },
- {
- "pk": 42,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_emailfeedsetting",
- "name": "Can delete email feed setting",
- "content_type": 14
- }
- },
- {
- "pk": 64,
- "model": "auth.permission",
- "fields": {
- "codename": "add_favoritequestion",
- "name": "Can add favorite question",
- "content_type": 22
- }
- },
- {
- "pk": 65,
- "model": "auth.permission",
- "fields": {
- "codename": "change_favoritequestion",
- "name": "Can change favorite question",
- "content_type": 22
- }
- },
- {
- "pk": 66,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_favoritequestion",
- "name": "Can delete favorite question",
- "content_type": 22
- }
- },
- {
- "pk": 52,
- "model": "auth.permission",
- "fields": {
- "codename": "add_markedtag",
- "name": "Can add marked tag",
- "content_type": 18
- }
- },
- {
- "pk": 53,
- "model": "auth.permission",
- "fields": {
- "codename": "change_markedtag",
- "name": "Can change marked tag",
- "content_type": 18
- }
- },
- {
- "pk": 54,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_markedtag",
- "name": "Can delete marked tag",
- "content_type": 18
- }
- },
- {
- "pk": 55,
- "model": "auth.permission",
- "fields": {
- "codename": "add_postrevision",
- "name": "Can add post revision",
- "content_type": 19
- }
- },
- {
- "pk": 56,
- "model": "auth.permission",
- "fields": {
- "codename": "change_postrevision",
- "name": "Can change post revision",
- "content_type": 19
- }
- },
- {
- "pk": 57,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_postrevision",
- "name": "Can delete post revision",
- "content_type": 19
- }
- },
- {
- "pk": 58,
- "model": "auth.permission",
- "fields": {
- "codename": "add_question",
- "name": "Can add question",
- "content_type": 20
- }
- },
- {
- "pk": 59,
- "model": "auth.permission",
- "fields": {
- "codename": "change_question",
- "name": "Can change question",
- "content_type": 20
- }
- },
- {
- "pk": 60,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_question",
- "name": "Can delete question",
- "content_type": 20
- }
- },
- {
- "pk": 61,
- "model": "auth.permission",
- "fields": {
- "codename": "add_questionview",
- "name": "Can add question view",
- "content_type": 21
- }
- },
- {
- "pk": 62,
- "model": "auth.permission",
- "fields": {
- "codename": "change_questionview",
- "name": "Can change question view",
- "content_type": 21
- }
- },
- {
- "pk": 63,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_questionview",
- "name": "Can delete question view",
- "content_type": 21
- }
- },
- {
- "pk": 31,
- "model": "auth.permission",
- "fields": {
- "codename": "add_repute",
- "name": "Can add repute",
- "content_type": 11
- }
- },
- {
- "pk": 32,
- "model": "auth.permission",
- "fields": {
- "codename": "change_repute",
- "name": "Can change repute",
- "content_type": 11
- }
- },
- {
- "pk": 33,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_repute",
- "name": "Can delete repute",
- "content_type": 11
- }
- },
- {
- "pk": 49,
- "model": "auth.permission",
- "fields": {
- "codename": "add_tag",
- "name": "Can add tag",
- "content_type": 17
- }
- },
- {
- "pk": 50,
- "model": "auth.permission",
- "fields": {
- "codename": "change_tag",
- "name": "Can change tag",
- "content_type": 17
- }
- },
- {
- "pk": 51,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_tag",
- "name": "Can delete tag",
- "content_type": 17
- }
- },
- {
- "pk": 43,
- "model": "auth.permission",
- "fields": {
- "codename": "add_vote",
- "name": "Can add vote",
- "content_type": 15
- }
- },
- {
- "pk": 44,
- "model": "auth.permission",
- "fields": {
- "codename": "change_vote",
- "name": "Can change vote",
- "content_type": 15
- }
- },
- {
- "pk": 45,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_vote",
- "name": "Can delete vote",
- "content_type": 15
- }
- },
- {
- "pk": 4,
- "model": "auth.permission",
- "fields": {
- "codename": "add_group",
- "name": "Can add group",
- "content_type": 2
- }
- },
- {
- "pk": 5,
- "model": "auth.permission",
- "fields": {
- "codename": "change_group",
- "name": "Can change group",
- "content_type": 2
- }
- },
- {
- "pk": 6,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_group",
- "name": "Can delete group",
- "content_type": 2
- }
- },
- {
- "pk": 10,
- "model": "auth.permission",
- "fields": {
- "codename": "add_message",
- "name": "Can add message",
- "content_type": 4
- }
- },
- {
- "pk": 11,
- "model": "auth.permission",
- "fields": {
- "codename": "change_message",
- "name": "Can change message",
- "content_type": 4
- }
- },
- {
- "pk": 12,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_message",
- "name": "Can delete message",
- "content_type": 4
- }
- },
- {
- "pk": 1,
- "model": "auth.permission",
- "fields": {
- "codename": "add_permission",
- "name": "Can add permission",
- "content_type": 1
- }
- },
- {
- "pk": 2,
- "model": "auth.permission",
- "fields": {
- "codename": "change_permission",
- "name": "Can change permission",
- "content_type": 1
- }
- },
- {
- "pk": 3,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_permission",
- "name": "Can delete permission",
- "content_type": 1
- }
- },
- {
- "pk": 7,
- "model": "auth.permission",
- "fields": {
- "codename": "add_user",
- "name": "Can add user",
- "content_type": 3
- }
- },
- {
- "pk": 8,
- "model": "auth.permission",
- "fields": {
- "codename": "change_user",
- "name": "Can change user",
- "content_type": 3
- }
- },
- {
- "pk": 9,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_user",
- "name": "Can delete user",
- "content_type": 3
- }
- },
- {
- "pk": 13,
- "model": "auth.permission",
- "fields": {
- "codename": "add_contenttype",
- "name": "Can add content type",
- "content_type": 5
- }
- },
- {
- "pk": 14,
- "model": "auth.permission",
- "fields": {
- "codename": "change_contenttype",
- "name": "Can change content type",
- "content_type": 5
- }
- },
- {
- "pk": 15,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_contenttype",
- "name": "Can delete content type",
- "content_type": 5
- }
- },
- {
- "pk": 79,
- "model": "auth.permission",
- "fields": {
- "codename": "add_association",
- "name": "Can add association",
- "content_type": 27
- }
- },
- {
- "pk": 80,
- "model": "auth.permission",
- "fields": {
- "codename": "change_association",
- "name": "Can change association",
- "content_type": 27
- }
- },
- {
- "pk": 81,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_association",
- "name": "Can delete association",
- "content_type": 27
- }
- },
- {
- "pk": 76,
- "model": "auth.permission",
- "fields": {
- "codename": "add_nonce",
- "name": "Can add nonce",
- "content_type": 26
- }
- },
- {
- "pk": 77,
- "model": "auth.permission",
- "fields": {
- "codename": "change_nonce",
- "name": "Can change nonce",
- "content_type": 26
- }
- },
- {
- "pk": 78,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_nonce",
- "name": "Can delete nonce",
- "content_type": 26
- }
- },
- {
- "pk": 82,
- "model": "auth.permission",
- "fields": {
- "codename": "add_userassociation",
- "name": "Can add user association",
- "content_type": 28
- }
- },
- {
- "pk": 83,
- "model": "auth.permission",
- "fields": {
- "codename": "change_userassociation",
- "name": "Can change user association",
- "content_type": 28
- }
- },
- {
- "pk": 84,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_userassociation",
- "name": "Can delete user association",
- "content_type": 28
- }
- },
- {
- "pk": 85,
- "model": "auth.permission",
- "fields": {
- "codename": "add_userpasswordqueue",
- "name": "Can add user password queue",
- "content_type": 29
- }
- },
- {
- "pk": 86,
- "model": "auth.permission",
- "fields": {
- "codename": "change_userpasswordqueue",
- "name": "Can change user password queue",
- "content_type": 29
- }
- },
- {
- "pk": 87,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_userpasswordqueue",
- "name": "Can delete user password queue",
- "content_type": 29
- }
- },
- {
- "pk": 112,
- "model": "auth.permission",
- "fields": {
- "codename": "add_crontabschedule",
- "name": "Can add crontab",
- "content_type": 38
- }
- },
- {
- "pk": 113,
- "model": "auth.permission",
- "fields": {
- "codename": "change_crontabschedule",
- "name": "Can change crontab",
- "content_type": 38
- }
- },
- {
- "pk": 114,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_crontabschedule",
- "name": "Can delete crontab",
- "content_type": 38
- }
- },
- {
- "pk": 109,
- "model": "auth.permission",
- "fields": {
- "codename": "add_intervalschedule",
- "name": "Can add interval",
- "content_type": 37
- }
- },
- {
- "pk": 110,
- "model": "auth.permission",
- "fields": {
- "codename": "change_intervalschedule",
- "name": "Can change interval",
- "content_type": 37
- }
- },
- {
- "pk": 111,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_intervalschedule",
- "name": "Can delete interval",
- "content_type": 37
- }
- },
- {
- "pk": 118,
- "model": "auth.permission",
- "fields": {
- "codename": "add_periodictask",
- "name": "Can add periodic task",
- "content_type": 40
- }
- },
- {
- "pk": 119,
- "model": "auth.permission",
- "fields": {
- "codename": "change_periodictask",
- "name": "Can change periodic task",
- "content_type": 40
- }
- },
- {
- "pk": 120,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_periodictask",
- "name": "Can delete periodic task",
- "content_type": 40
- }
- },
- {
- "pk": 115,
- "model": "auth.permission",
- "fields": {
- "codename": "add_periodictasks",
- "name": "Can add periodic tasks",
- "content_type": 39
- }
- },
- {
- "pk": 116,
- "model": "auth.permission",
- "fields": {
- "codename": "change_periodictasks",
- "name": "Can change periodic tasks",
- "content_type": 39
- }
- },
- {
- "pk": 117,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_periodictasks",
- "name": "Can delete periodic tasks",
- "content_type": 39
- }
- },
- {
- "pk": 103,
- "model": "auth.permission",
- "fields": {
- "codename": "add_taskmeta",
- "name": "Can add task meta",
- "content_type": 35
- }
- },
- {
- "pk": 104,
- "model": "auth.permission",
- "fields": {
- "codename": "change_taskmeta",
- "name": "Can change task meta",
- "content_type": 35
- }
- },
- {
- "pk": 105,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_taskmeta",
- "name": "Can delete task meta",
- "content_type": 35
- }
- },
- {
- "pk": 106,
- "model": "auth.permission",
- "fields": {
- "codename": "add_tasksetmeta",
- "name": "Can add taskset meta",
- "content_type": 36
- }
- },
- {
- "pk": 107,
- "model": "auth.permission",
- "fields": {
- "codename": "change_tasksetmeta",
- "name": "Can change taskset meta",
- "content_type": 36
- }
- },
- {
- "pk": 108,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_tasksetmeta",
- "name": "Can delete taskset meta",
- "content_type": 36
- }
- },
- {
- "pk": 124,
- "model": "auth.permission",
- "fields": {
- "codename": "add_taskstate",
- "name": "Can add task",
- "content_type": 42
- }
- },
- {
- "pk": 125,
- "model": "auth.permission",
- "fields": {
- "codename": "change_taskstate",
- "name": "Can change task",
- "content_type": 42
- }
- },
- {
- "pk": 126,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_taskstate",
- "name": "Can delete task",
- "content_type": 42
- }
- },
- {
- "pk": 121,
- "model": "auth.permission",
- "fields": {
- "codename": "add_workerstate",
- "name": "Can add worker",
- "content_type": 41
- }
- },
- {
- "pk": 122,
- "model": "auth.permission",
- "fields": {
- "codename": "change_workerstate",
- "name": "Can change worker",
- "content_type": 41
- }
- },
- {
- "pk": 123,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_workerstate",
- "name": "Can delete worker",
- "content_type": 41
- }
- },
- {
- "pk": 130,
- "model": "auth.permission",
- "fields": {
- "codename": "add_message",
- "name": "Can add message",
- "content_type": 44
- }
- },
- {
- "pk": 131,
- "model": "auth.permission",
- "fields": {
- "codename": "change_message",
- "name": "Can change message",
- "content_type": 44
- }
- },
- {
- "pk": 132,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_message",
- "name": "Can delete message",
- "content_type": 44
- }
- },
- {
- "pk": 127,
- "model": "auth.permission",
- "fields": {
- "codename": "add_queue",
- "name": "Can add queue",
- "content_type": 43
- }
- },
- {
- "pk": 128,
- "model": "auth.permission",
- "fields": {
- "codename": "change_queue",
- "name": "Can change queue",
- "content_type": 43
- }
- },
- {
- "pk": 129,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_queue",
- "name": "Can delete queue",
- "content_type": 43
- }
- },
- {
- "pk": 133,
- "model": "auth.permission",
- "fields": {
- "codename": "add_followuser",
- "name": "Can add followuser",
- "content_type": 45
- }
- },
- {
- "pk": 134,
- "model": "auth.permission",
- "fields": {
- "codename": "change_followuser",
- "name": "Can change followuser",
- "content_type": 45
- }
- },
- {
- "pk": 135,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_followuser",
- "name": "Can delete followuser",
- "content_type": 45
- }
- },
- {
- "pk": 94,
- "model": "auth.permission",
- "fields": {
- "codename": "add_longsetting",
- "name": "Can add long setting",
- "content_type": 32
- }
- },
- {
- "pk": 95,
- "model": "auth.permission",
- "fields": {
- "codename": "change_longsetting",
- "name": "Can change long setting",
- "content_type": 32
- }
- },
- {
- "pk": 96,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_longsetting",
- "name": "Can delete long setting",
- "content_type": 32
- }
- },
- {
- "pk": 91,
- "model": "auth.permission",
- "fields": {
- "codename": "add_setting",
- "name": "Can add setting",
- "content_type": 31
- }
- },
- {
- "pk": 92,
- "model": "auth.permission",
- "fields": {
- "codename": "change_setting",
- "name": "Can change setting",
- "content_type": 31
- }
- },
- {
- "pk": 93,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_setting",
- "name": "Can delete setting",
- "content_type": 31
- }
- },
- {
- "pk": 100,
- "model": "auth.permission",
- "fields": {
- "codename": "add_rule",
- "name": "Can add rule",
- "content_type": 34
- }
- },
- {
- "pk": 101,
- "model": "auth.permission",
- "fields": {
- "codename": "change_rule",
- "name": "Can change rule",
- "content_type": 34
- }
- },
- {
- "pk": 102,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_rule",
- "name": "Can delete rule",
- "content_type": 34
- }
- },
- {
- "pk": 97,
- "model": "auth.permission",
- "fields": {
- "codename": "add_url",
- "name": "Can add url",
- "content_type": 33
- }
- },
- {
- "pk": 98,
- "model": "auth.permission",
- "fields": {
- "codename": "change_url",
- "name": "Can change url",
- "content_type": 33
- }
- },
- {
- "pk": 99,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_url",
- "name": "Can delete url",
- "content_type": 33
- }
- },
- {
- "pk": 16,
- "model": "auth.permission",
- "fields": {
- "codename": "add_session",
- "name": "Can add session",
- "content_type": 6
- }
- },
- {
- "pk": 17,
- "model": "auth.permission",
- "fields": {
- "codename": "change_session",
- "name": "Can change session",
- "content_type": 6
- }
- },
- {
- "pk": 18,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_session",
- "name": "Can delete session",
- "content_type": 6
- }
- },
- {
- "pk": 19,
- "model": "auth.permission",
- "fields": {
- "codename": "add_site",
- "name": "Can add site",
- "content_type": 7
- }
- },
- {
- "pk": 20,
- "model": "auth.permission",
- "fields": {
- "codename": "change_site",
- "name": "Can change site",
- "content_type": 7
- }
- },
- {
- "pk": 21,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_site",
- "name": "Can delete site",
- "content_type": 7
- }
- },
- {
- "pk": 88,
- "model": "auth.permission",
- "fields": {
- "codename": "add_migrationhistory",
- "name": "Can add migration history",
- "content_type": 30
- }
- },
- {
- "pk": 89,
- "model": "auth.permission",
- "fields": {
- "codename": "change_migrationhistory",
- "name": "Can change migration history",
- "content_type": 30
- }
- },
- {
- "pk": 90,
- "model": "auth.permission",
- "fields": {
- "codename": "delete_migrationhistory",
- "name": "Can delete migration history",
- "content_type": 30
- }
- },
- {
- "pk": 1,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": true,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": true,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 61,
- "email": "test_user_0@askbot.org",
- "username": "test_user_0",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$917a5$8d31e7e3f8b7b8bbc27d27efdd49fc681cbad56b",
- "silver": 0,
- "bronze": 3,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 520,
- "gravatar": "97b89e3082d2741855254393f078fe6c",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 2,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 58,
- "email": "test_user_1@askbot.org",
- "username": "test_user_1",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$2fd95$07bdf8b37814d2a84b6f1673fffada9f84f63c0e",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 496,
- "gravatar": "6859f8f5f86ae184bab4c5e2297a6f85",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 3,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 55,
- "email": "test_user_2@askbot.org",
- "username": "test_user_2",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$f1879$be089b0acfe1cfc8e4f4c1bba92a0bc8f0cb0fc9",
- "silver": 0,
- "bronze": 4,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 518,
- "gravatar": "564666778b07615b15a36ce51ac7f7d2",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 4,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 52,
- "email": "test_user_3@askbot.org",
- "username": "test_user_3",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$2c013$304d5239a9b0f7f066b756c54fab18d2383fc3c7",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 496,
- "gravatar": "32f9b7a8113ca3b42b63435fe4859b31",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 5,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 49,
- "email": "test_user_4@askbot.org",
- "username": "test_user_4",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$df5ca$648a261a796f846a5e8e64b83ef74a13cdf82ee8",
- "silver": 0,
- "bronze": 4,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 518,
- "gravatar": "23f7d972c0c664b156d0473c0999a697",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 6,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 46,
- "email": "test_user_5@askbot.org",
- "username": "test_user_5",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$a994b$fc8d7f44c567e7d2fbf95b335b1749fd8cccd483",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 496,
- "gravatar": "9846d347d8a7d759c40cda0f3d13483f",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 7,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 43,
- "email": "test_user_6@askbot.org",
- "username": "test_user_6",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$496b9$f8d26a187baffa8beadd90aed0dd0ae7868315cc",
- "silver": 0,
- "bronze": 4,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 518,
- "gravatar": "7ce778a81f19e1304bbcc21ee6331063",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 8,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 40,
- "email": "test_user_7@askbot.org",
- "username": "test_user_7",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$5d4b5$0196b971f4a784e0af71ec0655a52a1590c1e478",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 496,
- "gravatar": "4556e9e446c727e6fdf37af356097ff2",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 9,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 37,
- "email": "test_user_8@askbot.org",
- "username": "test_user_8",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$84ffb$1fba7b1ef5993e0d0cc045593221921efb4a0104",
- "silver": 0,
- "bronze": 4,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 518,
- "gravatar": "2efc123f13b1590ab7f54b229b6ce61c",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 10,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 34,
- "email": "test_user_9@askbot.org",
- "username": "test_user_9",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$bf988$c56f74855686fa8fb9c5bd039d2774ee9c22b506",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 496,
- "gravatar": "2872546b9b5fa933413b58b18b0d56ca",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 11,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 31,
- "email": "test_user_10@askbot.org",
- "username": "test_user_10",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$25de1$b946e2022e115fd1276922296fd6d9e8465f4d39",
- "silver": 0,
- "bronze": 4,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 518,
- "gravatar": "83458295fcf6dcdc6ee5815491cbee3f",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 12,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:20",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:20",
- "location": "",
- "new_response_count": 28,
- "email": "test_user_11@askbot.org",
- "username": "test_user_11",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$a5edf$d53052d9c1fc1e671b43c83a840c14c922b50215",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 496,
- "gravatar": "ccb4b8fe5a80781e5051435db97becaa",
- "last_seen": "2011-12-20 12:51:20"
- }
- },
- {
- "pk": 13,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 25,
- "email": "test_user_12@askbot.org",
- "username": "test_user_12",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$d67f9$03c49b636e84766be0af76f7d7a1fd2c5482f201",
- "silver": 0,
- "bronze": 4,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 518,
- "gravatar": "6a70087a63bbc7c6a4028365ed4e1950",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 14,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 22,
- "email": "test_user_13@askbot.org",
- "username": "test_user_13",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$8f8ab$b0a4ca8e7e2c2539e2101c325584b9d9679a85f7",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 496,
- "gravatar": "77dc2a59fecaa4eeb06fa9f563ebf669",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 15,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 19,
- "email": "test_user_14@askbot.org",
- "username": "test_user_14",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$69539$e48d801c8c567413cf7ab6d11a78996d89e65b4f",
- "silver": 0,
- "bronze": 4,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 518,
- "gravatar": "0a4b98e7ec7867d097ef4ee1c3d23104",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 16,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 16,
- "email": "test_user_15@askbot.org",
- "username": "test_user_15",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$58954$055ea2ca379369686a8767f0f0efec14d6067537",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 496,
- "gravatar": "6c5d8511aa4f85cd75a16dbb3e03c5c7",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 17,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 13,
- "email": "test_user_16@askbot.org",
- "username": "test_user_16",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$ae00f$8df4d6129e34242ef50158fd2edaf7bea7ca1928",
- "silver": 0,
- "bronze": 4,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 518,
- "gravatar": "f2174ffb3833816753de7f596f69468b",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 18,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 10,
- "email": "test_user_17@askbot.org",
- "username": "test_user_17",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$85dfc$68f8f1587a87befee8ac262eaee9b9269a089d64",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 496,
- "gravatar": "b6778982e44fe0fbd78e3496069f1352",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 19,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 7,
- "email": "test_user_18@askbot.org",
- "username": "test_user_18",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$3a85d$8070b80232d0e6ec351d9d9d66b09c6212a77a2d",
- "silver": 0,
- "bronze": 4,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 518,
- "gravatar": "ec0f9a859b26512fdcc994516be5e752",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 20,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 2,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_19@askbot.org",
- "username": "test_user_19",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$f7931$fd6d24ecd06ca9acbb15506c3f3ff4d105dc693a",
- "silver": 2,
- "bronze": 4,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 713,
- "gravatar": "b75bdbeb7354745fdf9fdf72200eb799",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 21,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_20@askbot.org",
- "username": "test_user_20",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$ce673$cbe2240ab8a6b25003ab85d4bb705e07d7d76f74",
- "silver": 0,
- "bronze": 2,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 509,
- "gravatar": "4f877025b0ab869a9e9400e28ed3eab5",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 22,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_21@askbot.org",
- "username": "test_user_21",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$27f03$44e4b1227e5cd18fdd2d9af34bf6b090e360390d",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 498,
- "gravatar": "76b52b8b8655a296120d87715dbdd3e6",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 23,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_22@askbot.org",
- "username": "test_user_22",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$f2a81$9799180e6ff6e310fa091ca69ac0010c51342f4b",
- "silver": 0,
- "bronze": 2,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 509,
- "gravatar": "a5ddb8c0343a8aa84250f50535368aaf",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 24,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_23@askbot.org",
- "username": "test_user_23",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$fc47b$9d1f96ef03f26ee6949815fc53c08704e30cd2b1",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 498,
- "gravatar": "0b7ee0d2855d536bfcd272fe59e51e85",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 25,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_24@askbot.org",
- "username": "test_user_24",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$45370$2514c920f4058028a57a0adb6ec5c4e472775e0f",
- "silver": 0,
- "bronze": 2,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 509,
- "gravatar": "9273b4ea8133885f6864afbc27b17a6b",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 26,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_25@askbot.org",
- "username": "test_user_25",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$87174$1e7f2ee79f0322329581577f392c345ab1407204",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 498,
- "gravatar": "3f02ce1295ff1104020fb76e0a713f19",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 27,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_26@askbot.org",
- "username": "test_user_26",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$b024a$4c21a57f1b5b48fa974b90f1d3802caa3ca58e8b",
- "silver": 0,
- "bronze": 2,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 509,
- "gravatar": "2089b5251d55cadb48417b9d2b78b4b2",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 28,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_27@askbot.org",
- "username": "test_user_27",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$58826$41c5e9f5dce2835b5175b023eb527fcade98d2d4",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 498,
- "gravatar": "489074a9a117be5320690bd6977ece9e",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 29,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_28@askbot.org",
- "username": "test_user_28",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$66e41$907b68d8b88a2ee9c8b3e30649f9117cbd07519c",
- "silver": 0,
- "bronze": 2,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 509,
- "gravatar": "7ea520152dac05fa69541ffe139bcca2",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 30,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_29@askbot.org",
- "username": "test_user_29",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$7abb4$302c303a96f5aadfc1a744f4288fa0b7f60ce58d",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 498,
- "gravatar": "98be33fd4cf91cd0d26e8bbdda1691f2",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 31,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_30@askbot.org",
- "username": "test_user_30",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$8f341$7effe1a8dd068de04bf1da8c44d87f9d8b7ef541",
- "silver": 0,
- "bronze": 2,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 509,
- "gravatar": "4db2d8490aa35168e331b5ee5a0fd63b",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 32,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_31@askbot.org",
- "username": "test_user_31",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$a609f$b43e70ce92cd80413937108704a2faf96c659589",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 498,
- "gravatar": "e1646ca0338becadfc188108ef11a963",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 33,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_32@askbot.org",
- "username": "test_user_32",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$c0ee2$ac5ff63a7e0a57041b640151f3aaa844db9b509a",
- "silver": 0,
- "bronze": 2,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 509,
- "gravatar": "1f4576d9b347126a61b9b6ca39aaf46d",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 34,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_33@askbot.org",
- "username": "test_user_33",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$fdc5b$5e1792dcf3371268956f3d4463b2240642db0979",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 498,
- "gravatar": "a3d70733b55cca2d4e94e42b246ce2af",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 35,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_34@askbot.org",
- "username": "test_user_34",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$6effa$92f04edd455daf51f7fa680630b86ff7b6a9d5c7",
- "silver": 0,
- "bronze": 2,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 509,
- "gravatar": "a0a078c93e5bae4f19920e9f0ab6bd1d",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 36,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_35@askbot.org",
- "username": "test_user_35",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$64ff0$24d4e4c0998862417646a9195fb846bc1a7c35aa",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 498,
- "gravatar": "7cb624e123b95ef9694b64823b0fb0f1",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 37,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_36@askbot.org",
- "username": "test_user_36",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$264cc$e72669914cc404990b135dc48816b8c4c4afa6ff",
- "silver": 0,
- "bronze": 2,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 509,
- "gravatar": "906f494d5d4015f2d7d13a781d5dd2e7",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 38,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_37@askbot.org",
- "username": "test_user_37",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$a924b$25d6b03ca36b78d3420464097dba8142ba90b20d",
- "silver": 0,
- "bronze": 1,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 498,
- "gravatar": "641aca2f46519377ccd0500b6ab96ef0",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 39,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 0,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_38@askbot.org",
- "username": "test_user_38",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$6a84f$002738f797df0f265e17f970ccc67fabfee526a7",
- "silver": 0,
- "bronze": 2,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 509,
- "gravatar": "fcc3f6722e53bafdacdfea9ced92bbff",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 40,
- "model": "auth.user",
- "fields": {
- "status": "w",
- "last_name": "",
- "gold": 1,
- "is_staff": false,
- "user_permissions": [],
- "interesting_tags": "",
- "email_key": null,
- "date_joined": "2011-12-20 12:51:21",
- "first_name": "",
- "email_isvalid": false,
- "avatar_type": "n",
- "website": "",
- "is_superuser": false,
- "date_of_birth": null,
- "last_login": "2011-12-20 12:51:21",
- "location": "",
- "new_response_count": 0,
- "email": "test_user_39@askbot.org",
- "username": "test_user_39",
- "is_active": true,
- "consecutive_days_visit_count": 0,
- "email_tag_filter_strategy": 1,
- "groups": [],
- "password": "sha1$b2cca$fffcd0641241dff108a6015328497977a8452fb6",
- "silver": 1,
- "bronze": 5,
- "questions_per_page": 10,
- "about": "",
- "show_country": false,
- "country": "",
- "display_tag_filter_strategy": 0,
- "seen_response_count": 0,
- "real_name": "",
- "ignored_tags": "",
- "reputation": 702,
- "gravatar": "43d568bd3fb5f364a3e3a5aa2db795e4",
- "last_seen": "2011-12-20 12:51:21"
- }
- },
- {
- "pk": 1,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:22",
- "notified": false,
- "object_id": 1,
- "user": 1,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 2,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:22",
- "notified": false,
- "object_id": 1,
- "user": 2,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 3,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:24",
- "notified": false,
- "object_id": 2,
- "user": 3,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 4,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:24",
- "notified": false,
- "object_id": 3,
- "user": 3,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 5,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:24",
- "notified": false,
- "object_id": 3,
- "user": 4,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 6,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:24",
- "notified": false,
- "object_id": 4,
- "user": 5,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 7,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:24",
- "notified": false,
- "object_id": 5,
- "user": 5,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 8,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:24",
- "notified": false,
- "object_id": 5,
- "user": 6,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 9,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:24",
- "notified": false,
- "object_id": 6,
- "user": 7,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 10,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:24",
- "notified": false,
- "object_id": 7,
- "user": 7,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 11,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:24",
- "notified": false,
- "object_id": 7,
- "user": 8,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 12,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 8,
- "user": 9,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 13,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 9,
- "user": 9,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 14,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 9,
- "user": 10,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 15,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 10,
- "user": 11,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 16,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 11,
- "user": 11,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 17,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 11,
- "user": 12,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 18,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 12,
- "user": 13,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 19,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 13,
- "user": 13,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 20,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 13,
- "user": 14,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 21,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 14,
- "user": 15,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 22,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 15,
- "user": 15,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 23,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:25",
- "notified": false,
- "object_id": 15,
- "user": 16,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 24,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:26",
- "notified": false,
- "object_id": 16,
- "user": 17,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 25,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:26",
- "notified": false,
- "object_id": 17,
- "user": 17,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 26,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:26",
- "notified": false,
- "object_id": 17,
- "user": 18,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 27,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:26",
- "notified": false,
- "object_id": 18,
- "user": 19,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 28,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:26",
- "notified": false,
- "object_id": 19,
- "user": 19,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 29,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:26",
- "notified": false,
- "object_id": 19,
- "user": 20,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 30,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:26",
- "notified": false,
- "object_id": 20,
- "user": 21,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 31,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:26",
- "notified": false,
- "object_id": 21,
- "user": 21,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 32,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:26",
- "notified": false,
- "object_id": 21,
- "user": 22,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 33,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:26",
- "notified": false,
- "object_id": 22,
- "user": 23,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 34,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:27",
- "notified": false,
- "object_id": 23,
- "user": 23,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 35,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:27",
- "notified": false,
- "object_id": 23,
- "user": 24,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 36,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:27",
- "notified": false,
- "object_id": 24,
- "user": 25,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 37,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:27",
- "notified": false,
- "object_id": 25,
- "user": 25,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 38,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:27",
- "notified": false,
- "object_id": 25,
- "user": 26,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 39,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:27",
- "notified": false,
- "object_id": 26,
- "user": 27,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 40,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:27",
- "notified": false,
- "object_id": 27,
- "user": 27,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 41,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:27",
- "notified": false,
- "object_id": 27,
- "user": 28,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 42,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:27",
- "notified": false,
- "object_id": 28,
- "user": 29,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 43,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 29,
- "user": 29,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 44,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 29,
- "user": 30,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 45,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 30,
- "user": 31,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 46,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 31,
- "user": 31,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 47,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 31,
- "user": 32,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 48,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 32,
- "user": 33,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 49,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 33,
- "user": 33,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 50,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 33,
- "user": 34,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 51,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 34,
- "user": 35,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 52,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 35,
- "user": 35,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 53,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:28",
- "notified": false,
- "object_id": 35,
- "user": 36,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 54,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:29",
- "notified": false,
- "object_id": 36,
- "user": 37,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 55,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:29",
- "notified": false,
- "object_id": 37,
- "user": 37,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 56,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:29",
- "notified": false,
- "object_id": 37,
- "user": 38,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 57,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:29",
- "notified": false,
- "object_id": 38,
- "user": 39,
- "content_type": 20,
- "badge": 3
- }
- },
- {
- "pk": 58,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:29",
- "notified": false,
- "object_id": 39,
- "user": 39,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 59,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:29",
- "notified": false,
- "object_id": 39,
- "user": 40,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 60,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:29",
- "notified": false,
- "object_id": 40,
- "user": 40,
- "content_type": 20,
- "badge": 1
- }
- },
- {
- "pk": 61,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:29",
- "notified": false,
- "object_id": 40,
- "user": 1,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 62,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:29",
- "notified": false,
- "object_id": 1,
- "user": 1,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 63,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:30",
- "notified": false,
- "object_id": 40,
- "user": 40,
- "content_type": 20,
- "badge": 5
- }
- },
- {
- "pk": 64,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:30",
- "notified": false,
- "object_id": 40,
- "user": 40,
- "content_type": 20,
- "badge": 6
- }
- },
- {
- "pk": 65,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:30",
- "notified": false,
- "object_id": 40,
- "user": 3,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 66,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:30",
- "notified": false,
- "object_id": 3,
- "user": 3,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 67,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:30",
- "notified": false,
- "object_id": 40,
- "user": 40,
- "content_type": 20,
- "badge": 7
- }
- },
- {
- "pk": 68,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:30",
- "notified": false,
- "object_id": 40,
- "user": 5,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 69,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:31",
- "notified": false,
- "object_id": 5,
- "user": 5,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 70,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:31",
- "notified": false,
- "object_id": 40,
- "user": 7,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 71,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:31",
- "notified": false,
- "object_id": 7,
- "user": 7,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 72,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:32",
- "notified": false,
- "object_id": 40,
- "user": 9,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 73,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:32",
- "notified": false,
- "object_id": 9,
- "user": 9,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 74,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:33",
- "notified": false,
- "object_id": 40,
- "user": 11,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 75,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:33",
- "notified": false,
- "object_id": 11,
- "user": 11,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 76,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:34",
- "notified": false,
- "object_id": 40,
- "user": 13,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 77,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:34",
- "notified": false,
- "object_id": 13,
- "user": 13,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 78,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:35",
- "notified": false,
- "object_id": 40,
- "user": 15,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 79,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:35",
- "notified": false,
- "object_id": 15,
- "user": 15,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 80,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:36",
- "notified": false,
- "object_id": 40,
- "user": 17,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 81,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:36",
- "notified": false,
- "object_id": 17,
- "user": 17,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 82,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:38",
- "notified": false,
- "object_id": 40,
- "user": 19,
- "content_type": 20,
- "badge": 2
- }
- },
- {
- "pk": 83,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:38",
- "notified": false,
- "object_id": 19,
- "user": 19,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 84,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:39",
- "notified": false,
- "object_id": 20,
- "user": 20,
- "content_type": 24,
- "badge": 4
- }
- },
- {
- "pk": 85,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:39",
- "notified": false,
- "object_id": 20,
- "user": 20,
- "content_type": 24,
- "badge": 8
- }
- },
- {
- "pk": 86,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:39",
- "notified": false,
- "object_id": 20,
- "user": 20,
- "content_type": 24,
- "badge": 9
- }
- },
- {
- "pk": 87,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:40",
- "notified": false,
- "object_id": 20,
- "user": 20,
- "content_type": 24,
- "badge": 10
- }
- },
- {
- "pk": 88,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:50",
- "notified": false,
- "object_id": 40,
- "user": 40,
- "content_type": 20,
- "badge": 11
- }
- },
- {
- "pk": 89,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:50",
- "notified": false,
- "object_id": 20,
- "user": 20,
- "content_type": 24,
- "badge": 11
- }
- },
- {
- "pk": 90,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:52",
- "notified": false,
- "object_id": 20,
- "user": 40,
- "content_type": 24,
- "badge": 12
- }
- },
- {
- "pk": 91,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:52",
- "notified": false,
- "object_id": 20,
- "user": 20,
- "content_type": 24,
- "badge": 13
- }
- },
- {
- "pk": 92,
- "model": "askbot.award",
- "fields": {
- "awarded_at": "2011-12-20 12:51:52",
- "notified": false,
- "object_id": 20,
- "user": 20,
- "content_type": 24,
- "badge": 14
- }
- },
- {
- "pk": 1,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 1,
- "negative": 0,
- "reputation_type": 1,
- "user": 1,
- "reputed_at": "2011-12-20 12:51:22",
- "reputation": 510
- }
- },
- {
- "pk": 2,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 2,
- "negative": -2,
- "reputation_type": -3,
- "user": 2,
- "reputed_at": "2011-12-20 12:51:24",
- "reputation": 498
- }
- },
- {
- "pk": 3,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 2,
- "negative": -1,
- "reputation_type": -5,
- "user": 3,
- "reputed_at": "2011-12-20 12:51:24",
- "reputation": 499
- }
- },
- {
- "pk": 4,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 3,
- "negative": 0,
- "reputation_type": 1,
- "user": 3,
- "reputed_at": "2011-12-20 12:51:24",
- "reputation": 509
- }
- },
- {
- "pk": 5,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 4,
- "negative": -2,
- "reputation_type": -3,
- "user": 4,
- "reputed_at": "2011-12-20 12:51:24",
- "reputation": 498
- }
- },
- {
- "pk": 6,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 4,
- "negative": -1,
- "reputation_type": -5,
- "user": 5,
- "reputed_at": "2011-12-20 12:51:24",
- "reputation": 499
- }
- },
- {
- "pk": 7,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 5,
- "negative": 0,
- "reputation_type": 1,
- "user": 5,
- "reputed_at": "2011-12-20 12:51:24",
- "reputation": 509
- }
- },
- {
- "pk": 8,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 6,
- "negative": -2,
- "reputation_type": -3,
- "user": 6,
- "reputed_at": "2011-12-20 12:51:24",
- "reputation": 498
- }
- },
- {
- "pk": 9,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 6,
- "negative": -1,
- "reputation_type": -5,
- "user": 7,
- "reputed_at": "2011-12-20 12:51:24",
- "reputation": 499
- }
- },
- {
- "pk": 10,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 7,
- "negative": 0,
- "reputation_type": 1,
- "user": 7,
- "reputed_at": "2011-12-20 12:51:24",
- "reputation": 509
- }
- },
- {
- "pk": 11,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 8,
- "negative": -2,
- "reputation_type": -3,
- "user": 8,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 498
- }
- },
- {
- "pk": 12,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 8,
- "negative": -1,
- "reputation_type": -5,
- "user": 9,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 499
- }
- },
- {
- "pk": 13,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 9,
- "negative": 0,
- "reputation_type": 1,
- "user": 9,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 509
- }
- },
- {
- "pk": 14,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 10,
- "negative": -2,
- "reputation_type": -3,
- "user": 10,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 498
- }
- },
- {
- "pk": 15,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 10,
- "negative": -1,
- "reputation_type": -5,
- "user": 11,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 499
- }
- },
- {
- "pk": 16,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 11,
- "negative": 0,
- "reputation_type": 1,
- "user": 11,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 509
- }
- },
- {
- "pk": 17,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 12,
- "negative": -2,
- "reputation_type": -3,
- "user": 12,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 498
- }
- },
- {
- "pk": 18,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 12,
- "negative": -1,
- "reputation_type": -5,
- "user": 13,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 499
- }
- },
- {
- "pk": 19,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 13,
- "negative": 0,
- "reputation_type": 1,
- "user": 13,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 509
- }
- },
- {
- "pk": 20,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 14,
- "negative": -2,
- "reputation_type": -3,
- "user": 14,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 498
- }
- },
- {
- "pk": 21,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 14,
- "negative": -1,
- "reputation_type": -5,
- "user": 15,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 499
- }
- },
- {
- "pk": 22,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 15,
- "negative": 0,
- "reputation_type": 1,
- "user": 15,
- "reputed_at": "2011-12-20 12:51:25",
- "reputation": 509
- }
- },
- {
- "pk": 23,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 16,
- "negative": -2,
- "reputation_type": -3,
- "user": 16,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 498
- }
- },
- {
- "pk": 24,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 16,
- "negative": -1,
- "reputation_type": -5,
- "user": 17,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 499
- }
- },
- {
- "pk": 25,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 17,
- "negative": 0,
- "reputation_type": 1,
- "user": 17,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 509
- }
- },
- {
- "pk": 26,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 18,
- "negative": -2,
- "reputation_type": -3,
- "user": 18,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 498
- }
- },
- {
- "pk": 27,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 18,
- "negative": -1,
- "reputation_type": -5,
- "user": 19,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 499
- }
- },
- {
- "pk": 28,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 19,
- "negative": 0,
- "reputation_type": 1,
- "user": 19,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 509
- }
- },
- {
- "pk": 29,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 20,
- "negative": -2,
- "reputation_type": -3,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 498
- }
- },
- {
- "pk": 30,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 20,
- "negative": -1,
- "reputation_type": -5,
- "user": 21,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 499
- }
- },
- {
- "pk": 31,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 21,
- "negative": 0,
- "reputation_type": 1,
- "user": 21,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 509
- }
- },
- {
- "pk": 32,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 22,
- "negative": -2,
- "reputation_type": -3,
- "user": 22,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 498
- }
- },
- {
- "pk": 33,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 22,
- "negative": -1,
- "reputation_type": -5,
- "user": 23,
- "reputed_at": "2011-12-20 12:51:26",
- "reputation": 499
- }
- },
- {
- "pk": 34,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 23,
- "negative": 0,
- "reputation_type": 1,
- "user": 23,
- "reputed_at": "2011-12-20 12:51:27",
- "reputation": 509
- }
- },
- {
- "pk": 35,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 24,
- "negative": -2,
- "reputation_type": -3,
- "user": 24,
- "reputed_at": "2011-12-20 12:51:27",
- "reputation": 498
- }
- },
- {
- "pk": 36,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 24,
- "negative": -1,
- "reputation_type": -5,
- "user": 25,
- "reputed_at": "2011-12-20 12:51:27",
- "reputation": 499
- }
- },
- {
- "pk": 37,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 25,
- "negative": 0,
- "reputation_type": 1,
- "user": 25,
- "reputed_at": "2011-12-20 12:51:27",
- "reputation": 509
- }
- },
- {
- "pk": 38,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 26,
- "negative": -2,
- "reputation_type": -3,
- "user": 26,
- "reputed_at": "2011-12-20 12:51:27",
- "reputation": 498
- }
- },
- {
- "pk": 39,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 26,
- "negative": -1,
- "reputation_type": -5,
- "user": 27,
- "reputed_at": "2011-12-20 12:51:27",
- "reputation": 499
- }
- },
- {
- "pk": 40,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 27,
- "negative": 0,
- "reputation_type": 1,
- "user": 27,
- "reputed_at": "2011-12-20 12:51:27",
- "reputation": 509
- }
- },
- {
- "pk": 41,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 28,
- "negative": -2,
- "reputation_type": -3,
- "user": 28,
- "reputed_at": "2011-12-20 12:51:27",
- "reputation": 498
- }
- },
- {
- "pk": 42,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 28,
- "negative": -1,
- "reputation_type": -5,
- "user": 29,
- "reputed_at": "2011-12-20 12:51:27",
- "reputation": 499
- }
- },
- {
- "pk": 43,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 29,
- "negative": 0,
- "reputation_type": 1,
- "user": 29,
- "reputed_at": "2011-12-20 12:51:28",
- "reputation": 509
- }
- },
- {
- "pk": 44,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 30,
- "negative": -2,
- "reputation_type": -3,
- "user": 30,
- "reputed_at": "2011-12-20 12:51:28",
- "reputation": 498
- }
- },
- {
- "pk": 45,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 30,
- "negative": -1,
- "reputation_type": -5,
- "user": 31,
- "reputed_at": "2011-12-20 12:51:28",
- "reputation": 499
- }
- },
- {
- "pk": 46,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 31,
- "negative": 0,
- "reputation_type": 1,
- "user": 31,
- "reputed_at": "2011-12-20 12:51:28",
- "reputation": 509
- }
- },
- {
- "pk": 47,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 32,
- "negative": -2,
- "reputation_type": -3,
- "user": 32,
- "reputed_at": "2011-12-20 12:51:28",
- "reputation": 498
- }
- },
- {
- "pk": 48,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 32,
- "negative": -1,
- "reputation_type": -5,
- "user": 33,
- "reputed_at": "2011-12-20 12:51:28",
- "reputation": 499
- }
- },
- {
- "pk": 49,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 33,
- "negative": 0,
- "reputation_type": 1,
- "user": 33,
- "reputed_at": "2011-12-20 12:51:28",
- "reputation": 509
- }
- },
- {
- "pk": 50,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 34,
- "negative": -2,
- "reputation_type": -3,
- "user": 34,
- "reputed_at": "2011-12-20 12:51:28",
- "reputation": 498
- }
- },
- {
- "pk": 51,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 34,
- "negative": -1,
- "reputation_type": -5,
- "user": 35,
- "reputed_at": "2011-12-20 12:51:28",
- "reputation": 499
- }
- },
- {
- "pk": 52,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 35,
- "negative": 0,
- "reputation_type": 1,
- "user": 35,
- "reputed_at": "2011-12-20 12:51:28",
- "reputation": 509
- }
- },
- {
- "pk": 53,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 36,
- "negative": -2,
- "reputation_type": -3,
- "user": 36,
- "reputed_at": "2011-12-20 12:51:29",
- "reputation": 498
- }
- },
- {
- "pk": 54,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 36,
- "negative": -1,
- "reputation_type": -5,
- "user": 37,
- "reputed_at": "2011-12-20 12:51:29",
- "reputation": 499
- }
- },
- {
- "pk": 55,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 37,
- "negative": 0,
- "reputation_type": 1,
- "user": 37,
- "reputed_at": "2011-12-20 12:51:29",
- "reputation": 509
- }
- },
- {
- "pk": 56,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 38,
- "negative": -2,
- "reputation_type": -3,
- "user": 38,
- "reputed_at": "2011-12-20 12:51:29",
- "reputation": 498
- }
- },
- {
- "pk": 57,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 38,
- "negative": -1,
- "reputation_type": -5,
- "user": 39,
- "reputed_at": "2011-12-20 12:51:29",
- "reputation": 499
- }
- },
- {
- "pk": 58,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 39,
- "negative": 0,
- "reputation_type": 1,
- "user": 39,
- "reputed_at": "2011-12-20 12:51:29",
- "reputation": 509
- }
- },
- {
- "pk": 59,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:29",
- "reputation": 510
- }
- },
- {
- "pk": 60,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 1,
- "reputed_at": "2011-12-20 12:51:29",
- "reputation": 520
- }
- },
- {
- "pk": 61,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:30",
- "reputation": 520
- }
- },
- {
- "pk": 62,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -2,
- "reputation_type": -3,
- "user": 2,
- "reputed_at": "2011-12-20 12:51:30",
- "reputation": 496
- }
- },
- {
- "pk": 63,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -1,
- "reputation_type": -5,
- "user": 3,
- "reputed_at": "2011-12-20 12:51:30",
- "reputation": 508
- }
- },
- {
- "pk": 64,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:30",
- "reputation": 530
- }
- },
- {
- "pk": 65,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 3,
- "reputed_at": "2011-12-20 12:51:30",
- "reputation": 518
- }
- },
- {
- "pk": 66,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:30",
- "reputation": 540
- }
- },
- {
- "pk": 67,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -2,
- "reputation_type": -3,
- "user": 4,
- "reputed_at": "2011-12-20 12:51:30",
- "reputation": 496
- }
- },
- {
- "pk": 68,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -1,
- "reputation_type": -5,
- "user": 5,
- "reputed_at": "2011-12-20 12:51:30",
- "reputation": 508
- }
- },
- {
- "pk": 69,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:30",
- "reputation": 550
- }
- },
- {
- "pk": 70,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 5,
- "reputed_at": "2011-12-20 12:51:31",
- "reputation": 518
- }
- },
- {
- "pk": 71,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:31",
- "reputation": 560
- }
- },
- {
- "pk": 72,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -2,
- "reputation_type": -3,
- "user": 6,
- "reputed_at": "2011-12-20 12:51:31",
- "reputation": 496
- }
- },
- {
- "pk": 73,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -1,
- "reputation_type": -5,
- "user": 7,
- "reputed_at": "2011-12-20 12:51:31",
- "reputation": 508
- }
- },
- {
- "pk": 74,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:31",
- "reputation": 570
- }
- },
- {
- "pk": 75,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 7,
- "reputed_at": "2011-12-20 12:51:31",
- "reputation": 518
- }
- },
- {
- "pk": 76,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:32",
- "reputation": 580
- }
- },
- {
- "pk": 77,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -2,
- "reputation_type": -3,
- "user": 8,
- "reputed_at": "2011-12-20 12:51:32",
- "reputation": 496
- }
- },
- {
- "pk": 78,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -1,
- "reputation_type": -5,
- "user": 9,
- "reputed_at": "2011-12-20 12:51:32",
- "reputation": 508
- }
- },
- {
- "pk": 79,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:32",
- "reputation": 590
- }
- },
- {
- "pk": 80,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 9,
- "reputed_at": "2011-12-20 12:51:32",
- "reputation": 518
- }
- },
- {
- "pk": 81,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:32",
- "reputation": 600
- }
- },
- {
- "pk": 82,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -2,
- "reputation_type": -3,
- "user": 10,
- "reputed_at": "2011-12-20 12:51:33",
- "reputation": 496
- }
- },
- {
- "pk": 83,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -1,
- "reputation_type": -5,
- "user": 11,
- "reputed_at": "2011-12-20 12:51:33",
- "reputation": 508
- }
- },
- {
- "pk": 84,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:33",
- "reputation": 610
- }
- },
- {
- "pk": 85,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 11,
- "reputed_at": "2011-12-20 12:51:33",
- "reputation": 518
- }
- },
- {
- "pk": 86,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:33",
- "reputation": 620
- }
- },
- {
- "pk": 87,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -2,
- "reputation_type": -3,
- "user": 12,
- "reputed_at": "2011-12-20 12:51:33",
- "reputation": 496
- }
- },
- {
- "pk": 88,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -1,
- "reputation_type": -5,
- "user": 13,
- "reputed_at": "2011-12-20 12:51:33",
- "reputation": 508
- }
- },
- {
- "pk": 89,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:34",
- "reputation": 630
- }
- },
- {
- "pk": 90,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 13,
- "reputed_at": "2011-12-20 12:51:34",
- "reputation": 518
- }
- },
- {
- "pk": 91,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:34",
- "reputation": 640
- }
- },
- {
- "pk": 92,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -2,
- "reputation_type": -3,
- "user": 14,
- "reputed_at": "2011-12-20 12:51:34",
- "reputation": 496
- }
- },
- {
- "pk": 93,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -1,
- "reputation_type": -5,
- "user": 15,
- "reputed_at": "2011-12-20 12:51:34",
- "reputation": 508
- }
- },
- {
- "pk": 94,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:35",
- "reputation": 650
- }
- },
- {
- "pk": 95,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 15,
- "reputed_at": "2011-12-20 12:51:35",
- "reputation": 518
- }
- },
- {
- "pk": 96,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:36",
- "reputation": 660
- }
- },
- {
- "pk": 97,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -2,
- "reputation_type": -3,
- "user": 16,
- "reputed_at": "2011-12-20 12:51:36",
- "reputation": 496
- }
- },
- {
- "pk": 98,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -1,
- "reputation_type": -5,
- "user": 17,
- "reputed_at": "2011-12-20 12:51:36",
- "reputation": 508
- }
- },
- {
- "pk": 99,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:36",
- "reputation": 670
- }
- },
- {
- "pk": 100,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 17,
- "reputed_at": "2011-12-20 12:51:36",
- "reputation": 518
- }
- },
- {
- "pk": 101,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:37",
- "reputation": 680
- }
- },
- {
- "pk": 102,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -2,
- "reputation_type": -3,
- "user": 18,
- "reputed_at": "2011-12-20 12:51:37",
- "reputation": 496
- }
- },
- {
- "pk": 103,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 0,
- "question": 40,
- "negative": -1,
- "reputation_type": -5,
- "user": 19,
- "reputed_at": "2011-12-20 12:51:37",
- "reputation": 508
- }
- },
- {
- "pk": 104,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:38",
- "reputation": 690
- }
- },
- {
- "pk": 105,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 19,
- "reputed_at": "2011-12-20 12:51:38",
- "reputation": 518
- }
- },
- {
- "pk": 106,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:38",
- "reputation": 700
- }
- },
- {
- "pk": 107,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:39",
- "reputation": 508
- }
- },
- {
- "pk": 108,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:39",
- "reputation": 518
- }
- },
- {
- "pk": 109,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:39",
- "reputation": 528
- }
- },
- {
- "pk": 110,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:40",
- "reputation": 538
- }
- },
- {
- "pk": 111,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:40",
- "reputation": 548
- }
- },
- {
- "pk": 112,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:40",
- "reputation": 558
- }
- },
- {
- "pk": 113,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:41",
- "reputation": 568
- }
- },
- {
- "pk": 114,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:41",
- "reputation": 578
- }
- },
- {
- "pk": 115,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:42",
- "reputation": 588
- }
- },
- {
- "pk": 116,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:42",
- "reputation": 598
- }
- },
- {
- "pk": 117,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:43",
- "reputation": 608
- }
- },
- {
- "pk": 118,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:44",
- "reputation": 618
- }
- },
- {
- "pk": 119,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:44",
- "reputation": 628
- }
- },
- {
- "pk": 120,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:45",
- "reputation": 638
- }
- },
- {
- "pk": 121,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:46",
- "reputation": 648
- }
- },
- {
- "pk": 122,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:46",
- "reputation": 658
- }
- },
- {
- "pk": 123,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:47",
- "reputation": 668
- }
- },
- {
- "pk": 124,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:48",
- "reputation": 678
- }
- },
- {
- "pk": 125,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:49",
- "reputation": 688
- }
- },
- {
- "pk": 126,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 10,
- "question": 40,
- "negative": 0,
- "reputation_type": 1,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:49",
- "reputation": 698
- }
- },
- {
- "pk": 127,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 15,
- "question": 40,
- "negative": 0,
- "reputation_type": 2,
- "user": 20,
- "reputed_at": "2011-12-20 12:51:52",
- "reputation": 713
- }
- },
- {
- "pk": 128,
- "model": "askbot.repute",
- "fields": {
- "comment": null,
- "positive": 2,
- "question": 40,
- "negative": 0,
- "reputation_type": 3,
- "user": 40,
- "reputed_at": "2011-12-20 12:51:52",
- "reputation": 702
- }
- },
- {
- "pk": 1,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:22",
- "user": 2,
- "content_type": 20,
- "object_id": 1
- }
- },
- {
- "pk": 2,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:24",
- "user": 3,
- "content_type": 20,
- "object_id": 2
- }
- },
- {
- "pk": 3,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:24",
- "user": 4,
- "content_type": 20,
- "object_id": 3
- }
- },
- {
- "pk": 4,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:24",
- "user": 5,
- "content_type": 20,
- "object_id": 4
- }
- },
- {
- "pk": 5,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:24",
- "user": 6,
- "content_type": 20,
- "object_id": 5
- }
- },
- {
- "pk": 6,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:24",
- "user": 7,
- "content_type": 20,
- "object_id": 6
- }
- },
- {
- "pk": 7,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:24",
- "user": 8,
- "content_type": 20,
- "object_id": 7
- }
- },
- {
- "pk": 8,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:25",
- "user": 9,
- "content_type": 20,
- "object_id": 8
- }
- },
- {
- "pk": 9,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:25",
- "user": 10,
- "content_type": 20,
- "object_id": 9
- }
- },
- {
- "pk": 10,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:25",
- "user": 11,
- "content_type": 20,
- "object_id": 10
- }
- },
- {
- "pk": 11,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:25",
- "user": 12,
- "content_type": 20,
- "object_id": 11
- }
- },
- {
- "pk": 12,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:25",
- "user": 13,
- "content_type": 20,
- "object_id": 12
- }
- },
- {
- "pk": 13,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:25",
- "user": 14,
- "content_type": 20,
- "object_id": 13
- }
- },
- {
- "pk": 14,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:25",
- "user": 15,
- "content_type": 20,
- "object_id": 14
- }
- },
- {
- "pk": 15,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:25",
- "user": 16,
- "content_type": 20,
- "object_id": 15
- }
- },
- {
- "pk": 16,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:26",
- "user": 17,
- "content_type": 20,
- "object_id": 16
- }
- },
- {
- "pk": 17,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:26",
- "user": 18,
- "content_type": 20,
- "object_id": 17
- }
- },
- {
- "pk": 18,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:26",
- "user": 19,
- "content_type": 20,
- "object_id": 18
- }
- },
- {
- "pk": 19,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:26",
- "user": 20,
- "content_type": 20,
- "object_id": 19
- }
- },
- {
- "pk": 20,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:26",
- "user": 21,
- "content_type": 20,
- "object_id": 20
- }
- },
- {
- "pk": 21,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:26",
- "user": 22,
- "content_type": 20,
- "object_id": 21
- }
- },
- {
- "pk": 22,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:26",
- "user": 23,
- "content_type": 20,
- "object_id": 22
- }
- },
- {
- "pk": 23,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:27",
- "user": 24,
- "content_type": 20,
- "object_id": 23
- }
- },
- {
- "pk": 24,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:27",
- "user": 25,
- "content_type": 20,
- "object_id": 24
- }
- },
- {
- "pk": 25,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:27",
- "user": 26,
- "content_type": 20,
- "object_id": 25
- }
- },
- {
- "pk": 26,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:27",
- "user": 27,
- "content_type": 20,
- "object_id": 26
- }
- },
- {
- "pk": 27,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:27",
- "user": 28,
- "content_type": 20,
- "object_id": 27
- }
- },
- {
- "pk": 28,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:27",
- "user": 29,
- "content_type": 20,
- "object_id": 28
- }
- },
- {
- "pk": 29,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:28",
- "user": 30,
- "content_type": 20,
- "object_id": 29
- }
- },
- {
- "pk": 30,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:28",
- "user": 31,
- "content_type": 20,
- "object_id": 30
- }
- },
- {
- "pk": 31,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:28",
- "user": 32,
- "content_type": 20,
- "object_id": 31
- }
- },
- {
- "pk": 32,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:28",
- "user": 33,
- "content_type": 20,
- "object_id": 32
- }
- },
- {
- "pk": 33,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:28",
- "user": 34,
- "content_type": 20,
- "object_id": 33
- }
- },
- {
- "pk": 34,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:28",
- "user": 35,
- "content_type": 20,
- "object_id": 34
- }
- },
- {
- "pk": 35,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:28",
- "user": 36,
- "content_type": 20,
- "object_id": 35
- }
- },
- {
- "pk": 36,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:29",
- "user": 37,
- "content_type": 20,
- "object_id": 36
- }
- },
- {
- "pk": 37,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:29",
- "user": 38,
- "content_type": 20,
- "object_id": 37
- }
- },
- {
- "pk": 38,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:29",
- "user": 39,
- "content_type": 20,
- "object_id": 38
- }
- },
- {
- "pk": 39,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:29",
- "user": 40,
- "content_type": 20,
- "object_id": 39
- }
- },
- {
- "pk": 40,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:29",
- "user": 1,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 41,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:29",
- "user": 2,
- "content_type": 24,
- "object_id": 1
- }
- },
- {
- "pk": 42,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:30",
- "user": 2,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 43,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:30",
- "user": 3,
- "content_type": 24,
- "object_id": 2
- }
- },
- {
- "pk": 44,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:30",
- "user": 3,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 45,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:30",
- "user": 4,
- "content_type": 24,
- "object_id": 3
- }
- },
- {
- "pk": 46,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:30",
- "user": 4,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 47,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:30",
- "user": 5,
- "content_type": 24,
- "object_id": 4
- }
- },
- {
- "pk": 48,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:30",
- "user": 5,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 49,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:31",
- "user": 6,
- "content_type": 24,
- "object_id": 5
- }
- },
- {
- "pk": 50,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:31",
- "user": 6,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 51,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:31",
- "user": 7,
- "content_type": 24,
- "object_id": 6
- }
- },
- {
- "pk": 52,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:31",
- "user": 7,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 53,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:31",
- "user": 8,
- "content_type": 24,
- "object_id": 7
- }
- },
- {
- "pk": 54,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:32",
- "user": 8,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 55,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:32",
- "user": 9,
- "content_type": 24,
- "object_id": 8
- }
- },
- {
- "pk": 56,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:32",
- "user": 9,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 57,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:32",
- "user": 10,
- "content_type": 24,
- "object_id": 9
- }
- },
- {
- "pk": 58,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:32",
- "user": 10,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 59,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:33",
- "user": 11,
- "content_type": 24,
- "object_id": 10
- }
- },
- {
- "pk": 60,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:33",
- "user": 11,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 61,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:33",
- "user": 12,
- "content_type": 24,
- "object_id": 11
- }
- },
- {
- "pk": 62,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:33",
- "user": 12,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 63,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:33",
- "user": 13,
- "content_type": 24,
- "object_id": 12
- }
- },
- {
- "pk": 64,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:34",
- "user": 13,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 65,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:34",
- "user": 14,
- "content_type": 24,
- "object_id": 13
- }
- },
- {
- "pk": 66,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:34",
- "user": 14,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 67,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:34",
- "user": 15,
- "content_type": 24,
- "object_id": 14
- }
- },
- {
- "pk": 68,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:35",
- "user": 15,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 69,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:35",
- "user": 16,
- "content_type": 24,
- "object_id": 15
- }
- },
- {
- "pk": 70,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:36",
- "user": 16,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 71,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:36",
- "user": 17,
- "content_type": 24,
- "object_id": 16
- }
- },
- {
- "pk": 72,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:36",
- "user": 17,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 73,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:36",
- "user": 18,
- "content_type": 24,
- "object_id": 17
- }
- },
- {
- "pk": 74,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:37",
- "user": 18,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 75,
- "model": "askbot.vote",
- "fields": {
- "vote": -1,
- "voted_at": "2011-12-20 12:51:37",
- "user": 19,
- "content_type": 24,
- "object_id": 18
- }
- },
- {
- "pk": 76,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:38",
- "user": 19,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 77,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:38",
- "user": 20,
- "content_type": 24,
- "object_id": 19
- }
- },
- {
- "pk": 78,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:38",
- "user": 20,
- "content_type": 20,
- "object_id": 40
- }
- },
- {
- "pk": 79,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:39",
- "user": 1,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 80,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:39",
- "user": 2,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 81,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:39",
- "user": 3,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 82,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:40",
- "user": 4,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 83,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:40",
- "user": 5,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 84,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:40",
- "user": 6,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 85,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:41",
- "user": 7,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 86,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:41",
- "user": 8,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 87,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:42",
- "user": 9,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 88,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:42",
- "user": 10,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 89,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:43",
- "user": 11,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 90,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:44",
- "user": 12,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 91,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:44",
- "user": 13,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 92,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:45",
- "user": 14,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 93,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:46",
- "user": 15,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 94,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:46",
- "user": 16,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 95,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:47",
- "user": 17,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 96,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:48",
- "user": 18,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 97,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:49",
- "user": 19,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 98,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:49",
- "user": 20,
- "content_type": 24,
- "object_id": 20
- }
- },
- {
- "pk": 99,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:49",
- "user": 1,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 100,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:49",
- "user": 1,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 101,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:49",
- "user": 2,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 102,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:49",
- "user": 2,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 103,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:49",
- "user": 3,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 104,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:49",
- "user": 3,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 105,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 4,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 106,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 4,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 107,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 5,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 108,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 5,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 109,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 6,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 110,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 6,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 111,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 7,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 112,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 7,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 113,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 8,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 114,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 8,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 115,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 9,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 116,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 9,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 117,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 10,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 118,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 10,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 119,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 11,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 120,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 11,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 121,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 12,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 122,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 12,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 123,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 13,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 124,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 13,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 125,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 14,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 126,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 14,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 127,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 15,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 128,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 15,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 129,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 16,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 130,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 16,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 131,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 17,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 132,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 17,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 133,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 18,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 134,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 18,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 135,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 19,
- "content_type": 16,
- "object_id": 39
- }
- },
- {
- "pk": 136,
- "model": "askbot.vote",
- "fields": {
- "vote": 1,
- "voted_at": "2011-12-20 12:51:50",
- "user": 19,
- "content_type": 16,
- "object_id": 40
- }
- },
- {
- "pk": 40,
- "model": "askbot.comment",
- "fields": {
- "comment": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "score": 19,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:49",
- "offensive_flag_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "user": 20,
- "content_type": 24
- }
- },
- {
- "pk": 39,
- "model": "askbot.comment",
- "fields": {
- "comment": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "score": 19,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:49",
- "offensive_flag_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "user": 20,
- "content_type": 20
- }
- },
- {
- "pk": 38,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:48",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 19,
- "content_type": 24
- }
- },
- {
- "pk": 37,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:48",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 19,
- "content_type": 20
- }
- },
- {
- "pk": 36,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:47",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 18,
- "content_type": 24
- }
- },
- {
- "pk": 35,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:47",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 18,
- "content_type": 20
- }
- },
- {
- "pk": 34,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:47",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 17,
- "content_type": 24
- }
- },
- {
- "pk": 33,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:46",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 17,
- "content_type": 20
- }
- },
- {
- "pk": 32,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:46",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 16,
- "content_type": 24
- }
- },
- {
- "pk": 31,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:46",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 16,
- "content_type": 20
- }
- },
- {
- "pk": 30,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:45",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 15,
- "content_type": 24
- }
- },
- {
- "pk": 29,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:45",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 15,
- "content_type": 20
- }
- },
- {
- "pk": 28,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:45",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 14,
- "content_type": 24
- }
- },
- {
- "pk": 27,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:44",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 14,
- "content_type": 20
- }
- },
- {
- "pk": 26,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:44",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 13,
- "content_type": 24
- }
- },
- {
- "pk": 25,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:44",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 13,
- "content_type": 20
- }
- },
- {
- "pk": 24,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:43",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 12,
- "content_type": 24
- }
- },
- {
- "pk": 23,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:43",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 12,
- "content_type": 20
- }
- },
- {
- "pk": 22,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:43",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 11,
- "content_type": 24
- }
- },
- {
- "pk": 21,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:42",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 11,
- "content_type": 20
- }
- },
- {
- "pk": 20,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:42",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 10,
- "content_type": 24
- }
- },
- {
- "pk": 19,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:42",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 10,
- "content_type": 20
- }
- },
- {
- "pk": 18,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:42",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 9,
- "content_type": 24
- }
- },
- {
- "pk": 17,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:41",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 9,
- "content_type": 20
- }
- },
- {
- "pk": 16,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:41",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 8,
- "content_type": 24
- }
- },
- {
- "pk": 15,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:41",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 8,
- "content_type": 20
- }
- },
- {
- "pk": 14,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:41",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 7,
- "content_type": 24
- }
- },
- {
- "pk": 13,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:40",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 7,
- "content_type": 20
- }
- },
- {
- "pk": 12,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:40",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 6,
- "content_type": 24
- }
- },
- {
- "pk": 11,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:40",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 6,
- "content_type": 20
- }
- },
- {
- "pk": 10,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:40",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 5,
- "content_type": 24
- }
- },
- {
- "pk": 9,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:40",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 5,
- "content_type": 20
- }
- },
- {
- "pk": 8,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:39",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 4,
- "content_type": 24
- }
- },
- {
- "pk": 7,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:39",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 4,
- "content_type": 20
- }
- },
- {
- "pk": 6,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:39",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 3,
- "content_type": 24
- }
- },
- {
- "pk": 5,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:39",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 3,
- "content_type": 20
- }
- },
- {
- "pk": 4,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:39",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 2,
- "content_type": 24
- }
- },
- {
- "pk": 3,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:39",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 2,
- "content_type": 20
- }
- },
- {
- "pk": 2,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 20,
- "added_at": "2011-12-20 12:51:38",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 1,
- "content_type": 24
- }
- },
- {
- "pk": 1,
- "model": "askbot.comment",
- "fields": {
- "comment": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "score": 0,
- "object_id": 40,
- "added_at": "2011-12-20 12:51:38",
- "offensive_flag_count": 0,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "user": 1,
- "content_type": 20
- }
- },
- {
- "pk": 1,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-1-0",
- "deleted": false,
- "created_by": 1,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 2,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-1-1",
- "deleted": false,
- "created_by": 1,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 20,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-10-0",
- "deleted": false,
- "created_by": 10,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 19,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-10-1",
- "deleted": false,
- "created_by": 10,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 21,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-11-0",
- "deleted": false,
- "created_by": 11,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 22,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-11-1",
- "deleted": false,
- "created_by": 11,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 24,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-12-0",
- "deleted": false,
- "created_by": 12,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 23,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-12-1",
- "deleted": false,
- "created_by": 12,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 25,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-13-0",
- "deleted": false,
- "created_by": 13,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 26,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-13-1",
- "deleted": false,
- "created_by": 13,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 28,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-14-0",
- "deleted": false,
- "created_by": 14,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 27,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-14-1",
- "deleted": false,
- "created_by": 14,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 29,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-15-0",
- "deleted": false,
- "created_by": 15,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 30,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-15-1",
- "deleted": false,
- "created_by": 15,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 32,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-16-0",
- "deleted": false,
- "created_by": 16,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 31,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-16-1",
- "deleted": false,
- "created_by": 16,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 33,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-17-0",
- "deleted": false,
- "created_by": 17,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 34,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-17-1",
- "deleted": false,
- "created_by": 17,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 36,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-18-0",
- "deleted": false,
- "created_by": 18,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 35,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-18-1",
- "deleted": false,
- "created_by": 18,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 37,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-19-0",
- "deleted": false,
- "created_by": 19,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 38,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-19-1",
- "deleted": false,
- "created_by": 19,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 4,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-2-0",
- "deleted": false,
- "created_by": 2,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 3,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-2-1",
- "deleted": false,
- "created_by": 2,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 39,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-20-0",
- "deleted": false,
- "created_by": 20,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 40,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-20-1",
- "deleted": false,
- "created_by": 20,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 42,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-21-0",
- "deleted": false,
- "created_by": 21,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 41,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-21-1",
- "deleted": false,
- "created_by": 21,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 43,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-22-0",
- "deleted": false,
- "created_by": 22,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 44,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-22-1",
- "deleted": false,
- "created_by": 22,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 46,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-23-0",
- "deleted": false,
- "created_by": 23,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 45,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-23-1",
- "deleted": false,
- "created_by": 23,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 47,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-24-0",
- "deleted": false,
- "created_by": 24,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 48,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-24-1",
- "deleted": false,
- "created_by": 24,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 50,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-25-0",
- "deleted": false,
- "created_by": 25,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 49,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-25-1",
- "deleted": false,
- "created_by": 25,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 51,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-26-0",
- "deleted": false,
- "created_by": 26,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 52,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-26-1",
- "deleted": false,
- "created_by": 26,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 54,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-27-0",
- "deleted": false,
- "created_by": 27,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 53,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-27-1",
- "deleted": false,
- "created_by": 27,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 55,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-28-0",
- "deleted": false,
- "created_by": 28,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 56,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-28-1",
- "deleted": false,
- "created_by": 28,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 58,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-29-0",
- "deleted": false,
- "created_by": 29,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 57,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-29-1",
- "deleted": false,
- "created_by": 29,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 5,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-3-0",
- "deleted": false,
- "created_by": 3,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 6,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-3-1",
- "deleted": false,
- "created_by": 3,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 60,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-30-0",
- "deleted": false,
- "created_by": 30,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 59,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-30-1",
- "deleted": false,
- "created_by": 30,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 61,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-31-0",
- "deleted": false,
- "created_by": 31,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 62,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-31-1",
- "deleted": false,
- "created_by": 31,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 64,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-32-0",
- "deleted": false,
- "created_by": 32,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 63,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-32-1",
- "deleted": false,
- "created_by": 32,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 65,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-33-0",
- "deleted": false,
- "created_by": 33,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 66,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-33-1",
- "deleted": false,
- "created_by": 33,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 68,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-34-0",
- "deleted": false,
- "created_by": 34,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 67,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-34-1",
- "deleted": false,
- "created_by": 34,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 69,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-35-0",
- "deleted": false,
- "created_by": 35,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 70,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-35-1",
- "deleted": false,
- "created_by": 35,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 72,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-36-0",
- "deleted": false,
- "created_by": 36,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 71,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-36-1",
- "deleted": false,
- "created_by": 36,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 73,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-37-0",
- "deleted": false,
- "created_by": 37,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 74,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-37-1",
- "deleted": false,
- "created_by": 37,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 76,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-38-0",
- "deleted": false,
- "created_by": 38,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 75,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-38-1",
- "deleted": false,
- "created_by": 38,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 77,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-39-0",
- "deleted": false,
- "created_by": 39,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 78,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-39-1",
- "deleted": false,
- "created_by": 39,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 8,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-4-0",
- "deleted": false,
- "created_by": 4,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 7,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-4-1",
- "deleted": false,
- "created_by": 4,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 79,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-40-0",
- "deleted": false,
- "created_by": 40,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 80,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-40-1",
- "deleted": false,
- "created_by": 40,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 9,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-5-0",
- "deleted": false,
- "created_by": 5,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 10,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-5-1",
- "deleted": false,
- "created_by": 5,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 12,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-6-0",
- "deleted": false,
- "created_by": 6,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 11,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-6-1",
- "deleted": false,
- "created_by": 6,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 13,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-7-0",
- "deleted": false,
- "created_by": 7,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 14,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-7-1",
- "deleted": false,
- "created_by": 7,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 16,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-8-0",
- "deleted": false,
- "created_by": 8,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 15,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-8-1",
- "deleted": false,
- "created_by": 8,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 17,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-9-0",
- "deleted": false,
- "created_by": 9,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 18,
- "model": "askbot.tag",
- "fields": {
- "name": "tag-9-1",
- "deleted": false,
- "created_by": 9,
- "deleted_by": null,
- "used_count": 1,
- "deleted_at": null
- }
- },
- {
- "pk": 61,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 40,
- "tagnames": "tag-40-0 tag-40-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.EDITED",
- "question": 40,
- "revised_at": "2011-12-20 12:51:50",
- "summary": "EDITED",
- "revision_type": 1,
- "answer": null,
- "revision": 2
- }
- },
- {
- "pk": 62,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 20,
- "tagnames": "",
- "text": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:50",
- "summary": "No.2 Revision",
- "revision_type": 2,
- "answer": 20,
- "revision": 2
- }
- },
- {
- "pk": 1,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 1,
- "tagnames": "tag-1-0 tag-1-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.1",
- "question": 1,
- "revised_at": "2011-12-20 12:51:22",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 2,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 2,
- "tagnames": "tag-2-0 tag-2-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.2",
- "question": 2,
- "revised_at": "2011-12-20 12:51:24",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 3,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 3,
- "tagnames": "tag-3-0 tag-3-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.3",
- "question": 3,
- "revised_at": "2011-12-20 12:51:24",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 4,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 4,
- "tagnames": "tag-4-0 tag-4-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.4",
- "question": 4,
- "revised_at": "2011-12-20 12:51:24",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 5,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 5,
- "tagnames": "tag-5-0 tag-5-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.5",
- "question": 5,
- "revised_at": "2011-12-20 12:51:24",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 6,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 6,
- "tagnames": "tag-6-0 tag-6-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.6",
- "question": 6,
- "revised_at": "2011-12-20 12:51:24",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 7,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 7,
- "tagnames": "tag-7-0 tag-7-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.7",
- "question": 7,
- "revised_at": "2011-12-20 12:51:24",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 8,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 8,
- "tagnames": "tag-8-0 tag-8-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.8",
- "question": 8,
- "revised_at": "2011-12-20 12:51:24",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 9,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 9,
- "tagnames": "tag-9-0 tag-9-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.9",
- "question": 9,
- "revised_at": "2011-12-20 12:51:25",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 10,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 10,
- "tagnames": "tag-10-0 tag-10-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.10",
- "question": 10,
- "revised_at": "2011-12-20 12:51:25",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 11,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 11,
- "tagnames": "tag-11-0 tag-11-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.11",
- "question": 11,
- "revised_at": "2011-12-20 12:51:25",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 12,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 12,
- "tagnames": "tag-12-0 tag-12-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.12",
- "question": 12,
- "revised_at": "2011-12-20 12:51:25",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 13,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 13,
- "tagnames": "tag-13-0 tag-13-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.13",
- "question": 13,
- "revised_at": "2011-12-20 12:51:25",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 14,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 14,
- "tagnames": "tag-14-0 tag-14-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.14",
- "question": 14,
- "revised_at": "2011-12-20 12:51:25",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 15,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 15,
- "tagnames": "tag-15-0 tag-15-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.15",
- "question": 15,
- "revised_at": "2011-12-20 12:51:25",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 16,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 16,
- "tagnames": "tag-16-0 tag-16-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.16",
- "question": 16,
- "revised_at": "2011-12-20 12:51:26",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 17,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 17,
- "tagnames": "tag-17-0 tag-17-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.17",
- "question": 17,
- "revised_at": "2011-12-20 12:51:26",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 18,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 18,
- "tagnames": "tag-18-0 tag-18-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.18",
- "question": 18,
- "revised_at": "2011-12-20 12:51:26",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 19,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 19,
- "tagnames": "tag-19-0 tag-19-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.19",
- "question": 19,
- "revised_at": "2011-12-20 12:51:26",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 20,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 20,
- "tagnames": "tag-20-0 tag-20-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.20",
- "question": 20,
- "revised_at": "2011-12-20 12:51:26",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 21,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 21,
- "tagnames": "tag-21-0 tag-21-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.21",
- "question": 21,
- "revised_at": "2011-12-20 12:51:26",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 22,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 22,
- "tagnames": "tag-22-0 tag-22-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.22",
- "question": 22,
- "revised_at": "2011-12-20 12:51:26",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 23,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 23,
- "tagnames": "tag-23-0 tag-23-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.23",
- "question": 23,
- "revised_at": "2011-12-20 12:51:27",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 24,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 24,
- "tagnames": "tag-24-0 tag-24-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.24",
- "question": 24,
- "revised_at": "2011-12-20 12:51:27",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 25,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 25,
- "tagnames": "tag-25-0 tag-25-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.25",
- "question": 25,
- "revised_at": "2011-12-20 12:51:27",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 26,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 26,
- "tagnames": "tag-26-0 tag-26-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.26",
- "question": 26,
- "revised_at": "2011-12-20 12:51:27",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 27,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 27,
- "tagnames": "tag-27-0 tag-27-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.27",
- "question": 27,
- "revised_at": "2011-12-20 12:51:27",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 28,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 28,
- "tagnames": "tag-28-0 tag-28-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.28",
- "question": 28,
- "revised_at": "2011-12-20 12:51:27",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 29,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 29,
- "tagnames": "tag-29-0 tag-29-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.29",
- "question": 29,
- "revised_at": "2011-12-20 12:51:27",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 30,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 30,
- "tagnames": "tag-30-0 tag-30-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.30",
- "question": 30,
- "revised_at": "2011-12-20 12:51:28",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 31,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 31,
- "tagnames": "tag-31-0 tag-31-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.31",
- "question": 31,
- "revised_at": "2011-12-20 12:51:28",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 32,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 32,
- "tagnames": "tag-32-0 tag-32-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.32",
- "question": 32,
- "revised_at": "2011-12-20 12:51:28",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 33,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 33,
- "tagnames": "tag-33-0 tag-33-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.33",
- "question": 33,
- "revised_at": "2011-12-20 12:51:28",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 34,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 34,
- "tagnames": "tag-34-0 tag-34-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.34",
- "question": 34,
- "revised_at": "2011-12-20 12:51:28",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 35,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 35,
- "tagnames": "tag-35-0 tag-35-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.35",
- "question": 35,
- "revised_at": "2011-12-20 12:51:28",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 36,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 36,
- "tagnames": "tag-36-0 tag-36-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.36",
- "question": 36,
- "revised_at": "2011-12-20 12:51:29",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 37,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 37,
- "tagnames": "tag-37-0 tag-37-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.37",
- "question": 37,
- "revised_at": "2011-12-20 12:51:29",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 38,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 38,
- "tagnames": "tag-38-0 tag-38-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.38",
- "question": 38,
- "revised_at": "2011-12-20 12:51:29",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 39,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 39,
- "tagnames": "tag-39-0 tag-39-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.39",
- "question": 39,
- "revised_at": "2011-12-20 12:51:29",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 40,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 40,
- "tagnames": "tag-40-0 tag-40-1",
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "title": "Test question title No.40",
- "question": 40,
- "revised_at": "2011-12-20 12:51:29",
- "summary": "initial version",
- "revision_type": 1,
- "answer": null,
- "revision": 1
- }
- },
- {
- "pk": 41,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 1,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:29",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 1,
- "revision": 1
- }
- },
- {
- "pk": 42,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 2,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:30",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 2,
- "revision": 1
- }
- },
- {
- "pk": 43,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 3,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:30",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 3,
- "revision": 1
- }
- },
- {
- "pk": 44,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 4,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:30",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 4,
- "revision": 1
- }
- },
- {
- "pk": 45,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 5,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:30",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 5,
- "revision": 1
- }
- },
- {
- "pk": 46,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 6,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:31",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 6,
- "revision": 1
- }
- },
- {
- "pk": 47,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 7,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:31",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 7,
- "revision": 1
- }
- },
- {
- "pk": 48,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 8,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:31",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 8,
- "revision": 1
- }
- },
- {
- "pk": 49,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 9,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:32",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 9,
- "revision": 1
- }
- },
- {
- "pk": 50,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 10,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:32",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 10,
- "revision": 1
- }
- },
- {
- "pk": 51,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 11,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:33",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 11,
- "revision": 1
- }
- },
- {
- "pk": 52,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 12,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:33",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 12,
- "revision": 1
- }
- },
- {
- "pk": 53,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 13,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:33",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 13,
- "revision": 1
- }
- },
- {
- "pk": 54,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 14,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:34",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 14,
- "revision": 1
- }
- },
- {
- "pk": 55,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 15,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:35",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 15,
- "revision": 1
- }
- },
- {
- "pk": 56,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 16,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:35",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 16,
- "revision": 1
- }
- },
- {
- "pk": 57,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 17,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:36",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 17,
- "revision": 1
- }
- },
- {
- "pk": 58,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 18,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:36",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 18,
- "revision": 1
- }
- },
- {
- "pk": 59,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 19,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:37",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 19,
- "revision": 1
- }
- },
- {
- "pk": 60,
- "model": "askbot.postrevision",
- "fields": {
- "is_anonymous": false,
- "author": 20,
- "tagnames": "",
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "title": "",
- "question": null,
- "revised_at": "2011-12-20 12:51:38",
- "summary": "initial version",
- "revision_type": 2,
- "answer": 20,
- "revision": 1
- }
- },
- {
- "pk": 1,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 1,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 1,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 1,
- 2
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:22",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-1-0 tag-1-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:22",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.1",
- "last_edited_at": null
- }
- },
- {
- "pk": 2,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 2,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 2,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 4,
- 3
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:24",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-2-0 tag-2-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:24",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.2",
- "last_edited_at": null
- }
- },
- {
- "pk": 3,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 3,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 3,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 5,
- 6
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:24",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-3-0 tag-3-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:24",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.3",
- "last_edited_at": null
- }
- },
- {
- "pk": 4,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 4,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 4,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 8,
- 7
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:24",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-4-0 tag-4-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:24",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.4",
- "last_edited_at": null
- }
- },
- {
- "pk": 5,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 5,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 5,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 9,
- 10
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:24",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-5-0 tag-5-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:24",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.5",
- "last_edited_at": null
- }
- },
- {
- "pk": 6,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 6,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 6,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 12,
- 11
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:24",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-6-0 tag-6-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:24",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.6",
- "last_edited_at": null
- }
- },
- {
- "pk": 7,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 7,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 7,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 13,
- 14
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:24",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-7-0 tag-7-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:24",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.7",
- "last_edited_at": null
- }
- },
- {
- "pk": 8,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 8,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 8,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 16,
- 15
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:24",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-8-0 tag-8-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:24",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.8",
- "last_edited_at": null
- }
- },
- {
- "pk": 9,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 9,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 9,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 17,
- 18
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:25",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-9-0 tag-9-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:25",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.9",
- "last_edited_at": null
- }
- },
- {
- "pk": 10,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 10,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 10,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 20,
- 19
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:25",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-10-0 tag-10-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:25",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.10",
- "last_edited_at": null
- }
- },
- {
- "pk": 11,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 11,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 11,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 21,
- 22
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:25",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-11-0 tag-11-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:25",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.11",
- "last_edited_at": null
- }
- },
- {
- "pk": 12,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 12,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 12,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 24,
- 23
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:25",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-12-0 tag-12-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:25",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.12",
- "last_edited_at": null
- }
- },
- {
- "pk": 13,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 13,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 13,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 25,
- 26
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:25",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-13-0 tag-13-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:25",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.13",
- "last_edited_at": null
- }
- },
- {
- "pk": 14,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 14,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 14,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 28,
- 27
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:25",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-14-0 tag-14-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:25",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.14",
- "last_edited_at": null
- }
- },
- {
- "pk": 15,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 15,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 15,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 29,
- 30
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:25",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-15-0 tag-15-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:25",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.15",
- "last_edited_at": null
- }
- },
- {
- "pk": 16,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 16,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 16,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 32,
- 31
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:26",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-16-0 tag-16-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:26",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.16",
- "last_edited_at": null
- }
- },
- {
- "pk": 17,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 17,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 17,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 33,
- 34
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:26",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-17-0 tag-17-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:26",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.17",
- "last_edited_at": null
- }
- },
- {
- "pk": 18,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 18,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 18,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 36,
- 35
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:26",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-18-0 tag-18-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:26",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.18",
- "last_edited_at": null
- }
- },
- {
- "pk": 19,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 19,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 19,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 37,
- 38
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:26",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-19-0 tag-19-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:26",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.19",
- "last_edited_at": null
- }
- },
- {
- "pk": 20,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 20,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 20,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 39,
- 40
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:26",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-20-0 tag-20-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:26",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.20",
- "last_edited_at": null
- }
- },
- {
- "pk": 21,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 21,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 21,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 42,
- 41
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:26",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-21-0 tag-21-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:26",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.21",
- "last_edited_at": null
- }
- },
- {
- "pk": 22,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 22,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 22,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 43,
- 44
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:26",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-22-0 tag-22-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:26",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.22",
- "last_edited_at": null
- }
- },
- {
- "pk": 23,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 23,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 23,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 46,
- 45
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:27",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-23-0 tag-23-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:27",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.23",
- "last_edited_at": null
- }
- },
- {
- "pk": 24,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 24,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 24,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 47,
- 48
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:27",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-24-0 tag-24-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:27",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.24",
- "last_edited_at": null
- }
- },
- {
- "pk": 25,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 25,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 25,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 50,
- 49
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:27",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-25-0 tag-25-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:27",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.25",
- "last_edited_at": null
- }
- },
- {
- "pk": 26,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 26,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 26,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 51,
- 52
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:27",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-26-0 tag-26-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:27",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.26",
- "last_edited_at": null
- }
- },
- {
- "pk": 27,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 27,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 27,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 54,
- 53
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:27",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-27-0 tag-27-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:27",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.27",
- "last_edited_at": null
- }
- },
- {
- "pk": 28,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 28,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 28,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 55,
- 56
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:27",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-28-0 tag-28-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:27",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.28",
- "last_edited_at": null
- }
- },
- {
- "pk": 29,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 29,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 29,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 58,
- 57
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:27",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-29-0 tag-29-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:27",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.29",
- "last_edited_at": null
- }
- },
- {
- "pk": 30,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 30,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 30,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 60,
- 59
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:28",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-30-0 tag-30-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:28",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.30",
- "last_edited_at": null
- }
- },
- {
- "pk": 31,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 31,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 31,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 61,
- 62
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:28",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-31-0 tag-31-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:28",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.31",
- "last_edited_at": null
- }
- },
- {
- "pk": 32,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 32,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 32,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 64,
- 63
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:28",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-32-0 tag-32-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:28",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.32",
- "last_edited_at": null
- }
- },
- {
- "pk": 33,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 33,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 33,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 65,
- 66
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:28",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-33-0 tag-33-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:28",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.33",
- "last_edited_at": null
- }
- },
- {
- "pk": 34,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 34,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 34,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 68,
- 67
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:28",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-34-0 tag-34-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:28",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.34",
- "last_edited_at": null
- }
- },
- {
- "pk": 35,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 35,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 35,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 69,
- 70
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:28",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-35-0 tag-35-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:28",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.35",
- "last_edited_at": null
- }
- },
- {
- "pk": 36,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 36,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 36,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 72,
- 71
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:29",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-36-0 tag-36-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:29",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.36",
- "last_edited_at": null
- }
- },
- {
- "pk": 37,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 37,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 37,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 73,
- 74
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:29",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-37-0 tag-37-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:29",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.37",
- "last_edited_at": null
- }
- },
- {
- "pk": 38,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 38,
- "view_count": 0,
- "locked_at": null,
- "score": -1,
- "author": 38,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 1,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 76,
- 75
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:29",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-38-0 tag-38-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:29",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.38",
- "last_edited_at": null
- }
- },
- {
- "pk": 39,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 39,
- "view_count": 0,
- "locked_at": null,
- "score": 1,
- "author": 39,
- "comment_count": 0,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": false,
- "last_edited_by": null,
- "followed_by": [],
- "favourite_count": 0,
- "tags": [
- 77,
- 78
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 0,
- "last_activity_at": "2011-12-20 12:51:29",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-39-0 tag-39-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:29",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.39",
- "last_edited_at": null
- }
- },
- {
- "pk": 40,
- "model": "askbot.question",
- "fields": {
- "wiki": false,
- "vote_up_count": 20,
- "text": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n **A/B** testing *shrink* a market venture capital pitch.",
- "offensive_flag_count": 0,
- "closed_at": null,
- "deleted_at": null,
- "last_activity_by": 20,
- "view_count": 0,
- "locked_at": null,
- "score": 20,
- "author": 40,
- "comment_count": 20,
- "html": "<p>Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User engagement\n <strong>A/B</strong> testing <em>shrink</em> a market venture capital pitch.</p>\n",
- "vote_down_count": 0,
- "closed": false,
- "answer_accepted": true,
- "last_edited_by": 40,
- "followed_by": [
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 16,
- 17,
- 18,
- 19,
- 20
- ],
- "favourite_count": 0,
- "tags": [
- 79,
- 80
- ],
- "deleted": false,
- "summary": "Lorem lean startup ipsum product market fit customer\n development acquihire technical cofounder. User",
- "answer_count": 20,
- "last_activity_at": "2011-12-20 12:51:50",
- "closed_by": null,
- "close_reason": null,
- "locked": false,
- "is_anonymous": false,
- "tagnames": "tag-40-0 tag-40-1",
- "locked_by": null,
- "added_at": "2011-12-20 12:51:29",
- "deleted_by": null,
- "wikified_at": null,
- "title": "Test question title No.EDITED",
- "last_edited_at": "2011-12-20 12:51:50"
- }
- },
- {
- "pk": 1,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 1,
- "author": 1,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 0,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:29",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 2,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": -1,
- "author": 2,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 1,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:30",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 3,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 1,
- "author": 3,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 0,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:30",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 4,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": -1,
- "author": 4,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 1,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:30",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 5,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 1,
- "author": 5,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 0,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:30",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 6,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": -1,
- "author": 6,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 1,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:31",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 7,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 1,
- "author": 7,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 0,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:31",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 8,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": -1,
- "author": 8,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 1,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:31",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 9,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 1,
- "author": 9,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 0,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:32",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 10,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": -1,
- "author": 10,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 1,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:32",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 11,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 1,
- "author": 11,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 0,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:33",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 12,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": -1,
- "author": 12,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 1,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:33",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 13,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 1,
- "author": 13,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 0,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:33",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 14,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": -1,
- "author": 14,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 1,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:34",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 15,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 1,
- "author": 15,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 0,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:35",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 16,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": -1,
- "author": 16,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 1,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:35",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 17,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 1,
- "author": 17,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 0,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:36",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 18,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 0,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": -1,
- "author": 18,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 1,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:36",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 19,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 1,
- "text": "Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 1,
- "author": 19,
- "question": 40,
- "comment_count": 0,
- "html": "<p>Accelerator photo sharing business school drop out ramen\n hustle crush it revenue traction platforms.</p>\n",
- "vote_down_count": 0,
- "last_edited_by": null,
- "accepted_at": null,
- "deleted": false,
- "accepted": false,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:37",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": null
- }
- },
- {
- "pk": 20,
- "model": "askbot.answer",
- "fields": {
- "wiki": false,
- "vote_up_count": 20,
- "text": "Main differentiators business model micro economics\n marketplace equity augmented reality human computer",
- "offensive_flag_count": 0,
- "deleted_at": null,
- "locked_at": null,
- "score": 20,
- "author": 20,
- "question": 40,
- "comment_count": 20,
- "html": "<p>Main differentiators business model micro economics\n marketplace equity augmented reality human computer</p>\n",
- "vote_down_count": 0,
- "last_edited_by": 20,
- "accepted_at": "2011-12-20 12:51:52",
- "deleted": false,
- "accepted": true,
- "locked": false,
- "locked_by": null,
- "added_at": "2011-12-20 12:51:38",
- "deleted_by": null,
- "wikified_at": null,
- "last_edited_at": "2011-12-20 12:51:50"
- }
- },
- {
- "pk": 1,
- "model": "livesettings.setting",
- "fields": {
- "value": "2",
- "group": "GENERAL_SKIN_SETTINGS",
- "site": 1,
- "key": "MEDIA_RESOURCE_REVISION"
- }
- },
- {
- "pk": 2,
- "model": "livesettings.setting",
- "fields": {
- "value": "538027b7ec845c2d7b331a752af88e5f12f62e58",
- "group": "GENERAL_SKIN_SETTINGS",
- "site": 1,
- "key": "MEDIA_RESOURCE_REVISION_HASH"
- }
- }
-] \ No newline at end of file
diff --git a/askbot/tests/user_model_tests.py b/askbot/tests/user_model_tests.py
index e46cdb77..b11fb151 100644
--- a/askbot/tests/user_model_tests.py
+++ b/askbot/tests/user_model_tests.py
@@ -1,6 +1,7 @@
from askbot.tests.utils import AskbotTestCase
from django.contrib.auth.models import User
from askbot import models
+from askbot.conf import settings
from askbot.models.tag import format_personal_group_name
class UserModelTests(AskbotTestCase):
@@ -16,6 +17,30 @@ class UserModelTests(AskbotTestCase):
)
self.assertEqual(memberships.count(), 1)
+ def test_new_user_has_subscriptions(self):
+ old_value = settings.SUBSCRIBED_TAG_SELECTOR_ENABLED
+ old_group_value = settings.GROUPS_ENABLED
+ settings.SUBSCRIBED_TAG_SELECTOR_ENABLED = True
+ settings.GROUPS_ENABLED = True
+ one_tag = self.create_tag('one-tag')
+ another_tag = self.create_tag('another_tag')
+
+ global_group = models.Group.objects.get_global_group()
+
+ the_boss = self.create_user('theboss')
+ bulk_subscription = models.BulkTagSubscription.objects.create(
+ tag_names=[one_tag.name, another_tag.name],
+ group_list=[global_group],
+ tag_author=the_boss
+ )
+
+ user = self.create_user('someone')
+ marked_tags = user.get_marked_tags('subscribed')
+ self.assertTrue(one_tag in marked_tags)
+ self.assertTrue(another_tag in marked_tags)
+ settings.SUBSCRIBED_TAG_SELECTOR_ENABLED = old_value
+ settings.GROUPS_ENABLED = old_group_value
+
def test_delete_user(self):
user = self.create_user('user')
user.delete()
diff --git a/askbot/urls.py b/askbot/urls.py
index 362a16ee..551b9ecd 100644
--- a/askbot/urls.py
+++ b/askbot/urls.py
@@ -2,6 +2,7 @@
askbot askbot url configuraion file
"""
import os.path
+import django
from django.conf import settings
from django.conf.urls.defaults import url, patterns, include
from django.conf.urls.defaults import handler500, handler404
@@ -12,7 +13,7 @@ from askbot.sitemap import QuestionsSitemap
from askbot.skins.utils import update_media_revision
admin.autodiscover()
-update_media_revision()#needs to be run once, so put it here
+#update_media_revision()#needs to be run once, so put it here
if getattr(settings, "ASKBOT_TRANSLATE_URL", False):
from django.utils.translation import ugettext as _
@@ -37,7 +38,7 @@ urlpatterns = patterns('',
name='sitemap'
),
#no translation for this url!!
- url(r'import-data/$', views.writers.import_data, name='import_data'),
+ url(r'^import-data/$', views.writers.import_data, name='import_data'),
url(r'^%s$' % _('about/'), views.meta.about, name='about'),
url(r'^%s$' % _('faq/'), views.meta.faq, name='faq'),
url(r'^%s$' % _('privacy/'), views.meta.privacy, name='privacy'),
@@ -73,9 +74,9 @@ urlpatterns = patterns('',
# END main page urls
url(
- r'^api/get_questions/',
- views.commands.api_get_questions,
- name='api_get_questions'
+ r'^api/title_search/',
+ views.commands.title_search,
+ name='title_search'
),
url(
r'^get-thread-shared-users/',
@@ -193,15 +194,22 @@ urlpatterns = patterns('',
views.readers.get_comment,
name='get_comment'
),
- url(#post only
+ url(
r'^comment/convert/$',
views.writers.comment_to_answer,
name='comment_to_answer'
),
+ url(
+ r'^answer/repost-as-comment-under-question/$',
+ views.writers.repost_answer_as_comment,
+ kwargs={'destination': 'comment_under_question'},
+ name='repost_answer_as_comment_under_question'
+ ),
url(#post only
- r'^answer/convert/$',
- views.writers.answer_to_comment,
- name='answer_to_comment'
+ '^answer/repost-as-comment-under-previous-answer/$',
+ views.writers.repost_answer_as_comment,
+ kwargs={'destination': 'comment_under_previous_answer'},
+ name='repost_answer_as_comment_under_previous_answer'
),
url(#post only
r'^answer/publish/$',
@@ -214,10 +222,36 @@ urlpatterns = patterns('',
name='tags'
),
url(
+ r'^%s$' % _('tags/subscriptions/'),
+ views.commands.list_bulk_tag_subscription,
+ name='list_bulk_tag_subscription'
+ ),
+ url(#post only
+ r'^%s$' % _('tags/subscriptions/delete/'),
+ views.commands.delete_bulk_tag_subscription,
+ name='delete_bulk_tag_subscription'
+ ),
+ url(
+ r'^%s$' % _('tags/subscriptions/create/'),
+ views.commands.create_bulk_tag_subscription,
+ name='create_bulk_tag_subscription'
+ ),
+ url(
+ r'^%s(?P<pk>\d+)/$' % _('tags/subscriptions/edit/'),
+ views.commands.edit_bulk_tag_subscription,
+ name='edit_bulk_tag_subscription'
+ ),
+
+ url(
r'^%s$' % _('suggested-tags/'),
views.meta.list_suggested_tags,
name = 'list_suggested_tags'
),
+
+ #feeds
+ url(r'^feeds/rss/$', RssLastestQuestionsFeed(), name="latest_questions_feed"),
+ url(r'^feeds/question/(?P<pk>\d+)/$', RssIndividualQuestionFeed(), name="individual_question_feed"),
+
url(#ajax only
r'^%s$' % 'moderate-suggested-tag',
views.commands.moderate_suggested_tag,
@@ -360,6 +394,14 @@ urlpatterns = patterns('',
name = 'user_subscriptions'
),
url(
+ r'^%s(?P<id>\d+)/(?P<slug>.+)/%s$' % (
+ _('users/'),
+ _('select_languages/'),
+ ),
+ views.users.user_select_languages,
+ name = 'user_select_languages'
+ ),
+ url(
r'^%s(?P<id>\d+)/(?P<slug>.+)/$' % _('users/'),
views.users.user,
name='user_profile'
@@ -473,16 +515,9 @@ urlpatterns = patterns('',
views.widgets.question_widget,
name = 'question_widget'
),
- url(
- r'^feeds/(?P<url>.*)/$',
- 'django.contrib.syndication.views.feed',
- {'feed_dict': feeds},
- name='feeds'
- ),
#upload url is ajax only
url( r'^%s$' % _('upload/'), views.writers.upload, name='upload'),
url(r'^%s$' % _('feedback/'), views.meta.feedback, name='feedback'),
- #url(r'^feeds/rss/$', RssLastestQuestionsFeed, name="latest_questions_feed"),
url(
r'^doc/(?P<path>.*)$',
'django.views.static.serve',
diff --git a/askbot/utils/console.py b/askbot/utils/console.py
index a691d961..23cff6f9 100644
--- a/askbot/utils/console.py
+++ b/askbot/utils/console.py
@@ -24,7 +24,9 @@ def choice_dialog(prompt_phrase, choices = None, invalid_phrase = None):
assert(hasattr(choices, '__iter__'))
assert(not isinstance(choices, basestring))
while 1:
- response = raw_input('\n%s (type %s): ' % (prompt_phrase, '/'.join(choices)))
+ response = raw_input(
+ '\n%s (type %s)\n> ' % (prompt_phrase, '/'.join(choices))
+ )
if response in choices:
return response
elif invalid_phrase != None:
@@ -32,6 +34,31 @@ def choice_dialog(prompt_phrase, choices = None, invalid_phrase = None):
print invalid_phrase % {'opt_string': opt_string}
time.sleep(1)
+
+def simple_dialog(prompt_phrase, required=False):
+ """asks user to enter a string, if `required` is True,
+ will repeat question until non-empty input is given
+ """
+ while 1:
+
+ if required:
+ prompt_phrase += ' (required)'
+
+ response = raw_input(prompt_phrase + '\n> ').strip()
+
+ if response or required is False:
+ return response
+
+ time.sleep(1)
+
+
+def get_yes_or_no(prompt_phrase):
+ while True:
+ response = raw_input(prompt_phrase + ' (yes/no)\n> ').strip()
+ if response in ('yes', 'no'):
+ return response
+
+
def open_new_file(prompt_phrase, extension = '', hint = None):
"""will ask for a file name to be typed
by user into the console path to the file can be
@@ -91,7 +118,8 @@ class ProgressBar(object):
self.iterable = iterable
self.length = length
self.counter = float(0)
- self.barlen = 60
+ self.max_barlen = 60
+ self.curr_barlen = 0
self.progress = ''
if message and length > 0:
print message
@@ -103,17 +131,33 @@ class ProgressBar(object):
def print_progress_bar(self):
"""prints the progress bar"""
- sys.stdout.write('\b'*len(self.progress))
+ self.backspace_progress_percent()
- if self.length < self.barlen:
- sys.stdout.write('-'*(self.barlen/self.length))
- elif int(self.counter) % (self.length / self.barlen) == 0:
- sys.stdout.write('-')
+ tics_to_write = 0
+ if self.length < self.max_barlen:
+ tics_to_write = self.max_barlen/self.length
+ elif int(self.counter) % (self.length/self.max_barlen) == 0:
+ tics_to_write = 1
+
+ if self.curr_barlen + tics_to_write <= self.max_barlen:
+ sys.stdout.write('-' * tics_to_write)
+ self.curr_barlen += tics_to_write
+
+ self.print_progress_percent()
+
+ def backspace_progress_percent(self):
+ sys.stdout.write('\b'*len(self.progress))
+ def print_progress_percent(self):
+ """prints percent of achieved progress"""
self.progress = ' %.2f%%' % (100 * (self.counter/self.length))
sys.stdout.write(self.progress)
sys.stdout.flush()
+ def finish_progress_bar(self):
+ """brint the last bars, to make all bars equal length"""
+ self.backspace_progress_percent()
+ sys.stdout.write('-' * (self.max_barlen - self.curr_barlen))
def next(self):
@@ -121,7 +165,8 @@ class ProgressBar(object):
result = self.iterable.next()
except StopIteration:
if self.length > 0:
- self.print_progress_bar()
+ self.finish_progress_bar()
+ self.print_progress_percent()
sys.stdout.write('\n')
raise
diff --git a/askbot/utils/forms.py b/askbot/utils/forms.py
index 6f57f71f..4d33fd75 100644
--- a/askbot/utils/forms.py
+++ b/askbot/utils/forms.py
@@ -5,7 +5,7 @@ from django.contrib.auth.models import User
from django.conf import settings
from django.http import Http404
from django.shortcuts import get_object_or_404
-from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe
from askbot.conf import settings as askbot_settings
from askbot.utils.slug import slugify
@@ -206,10 +206,17 @@ def email_is_allowed(
return False
class UserEmailField(forms.EmailField):
- def __init__(self,skip_clean=False,**kw):
+ def __init__(self, skip_clean=False, **kw):
self.skip_clean = skip_clean
+
+ hidden = kw.pop('hidden', False)
+ if hidden is True:
+ widget_class = forms.HiddenInput
+ else:
+ widget_class = forms.TextInput
+
super(UserEmailField,self).__init__(
- widget=forms.TextInput(
+ widget=widget_class(
attrs=dict(login_form_widget_attrs, maxlength=200)
),
label=mark_safe(_('Your email <i>(never shared)</i>')),
diff --git a/askbot/utils/functions.py b/askbot/utils/functions.py
index f9d36534..2579728b 100644
--- a/askbot/utils/functions.py
+++ b/askbot/utils/functions.py
@@ -1,8 +1,8 @@
import re
+import random
import datetime
from django.utils.translation import ugettext as _
from django.utils.translation import ungettext
-from django.contrib.auth.models import User
def get_from_dict_or_object(source, key):
try:
@@ -162,8 +162,16 @@ def setup_paginator(context):
}
def get_admin():
- '''Returns an admin users, usefull for raising flags'''
+ """Returns an admin users, usefull for raising flags"""
try:
+ from django.contrib.auth.models import User
return User.objects.filter(is_superuser=True)[0]
except:
raise Exception('there is no admin users')
+
+def generate_random_key(length=16):
+ """return random string, length is number of characters"""
+ random.seed()
+ assert(isinstance(length, int))
+ format_string = '%0' + str(2*length) + 'x'
+ return format_string % random.getrandbits(length*8)
diff --git a/askbot/utils/html.py b/askbot/utils/html.py
index 3e1bfba5..1d76fdb7 100644
--- a/askbot/utils/html.py
+++ b/askbot/utils/html.py
@@ -93,7 +93,7 @@ def replace_links_with_text(html):
elif url == '' or re.match(abs_url_re, url):
link.replaceWith(format_url_replacement(url, text))
- return soup.find('body').renderContents()
+ return unicode(soup.find('body').renderContents(), 'utf-8')
def sanitize_html(html):
diff --git a/askbot/views/avatar_views.py b/askbot/views/avatar_views.py
index 42d0b38a..94252860 100644
--- a/askbot/views/avatar_views.py
+++ b/askbot/views/avatar_views.py
@@ -1,10 +1,15 @@
-"""this is an unfortunate copy-paste (mostly)
+"""
+todo: remove this module - not needed any more
+
+this is an unfortunate copy-paste (mostly)
from the avatar app - the reason is that django-avatar app
does not support jinja templates
"""
import urllib
from django.http import HttpResponseRedirect
from django.template import RequestContext
+from django.template.loader import get_template
+from django.shortcuts import render
from django.utils.translation import ugettext as _
from django.views.decorators import csrf
from django.conf import settings
@@ -17,7 +22,6 @@ from avatar.settings import AVATAR_MAX_AVATARS_PER_USER, AVATAR_DEFAULT_SIZE
from avatar.util import get_primary_avatar, get_default_avatar_url
from avatar.views import render_primary as django_avatar_render_primary
-from askbot.skins.loaders import render_into_skin
from askbot import models
notification = False
@@ -111,7 +115,7 @@ def add(request, extra_context=None, next_override=None,
if extra_context:
data.update(extra_context)
- return render_into_skin('avatar/add.html', data, request)
+ return render(request, 'avatar/add.html', data)
@login_required
@csrf.csrf_protect
@@ -153,7 +157,7 @@ def change(request, extra_context=None, next_override=None,
if extra_context:
data.update(extra_context)
- return render_into_skin('avatar/change.html', data, request)
+ return render(request, 'avatar/change.html', data)
@login_required
@csrf.csrf_protect
@@ -190,7 +194,7 @@ def delete(request, extra_context=None, next_override=None, *args, **kwargs):
if extra_context:
data.update(extra_context)
- return render_into_skin('avatar/confirm_delete.html', data, request)
+ return render(request, 'avatar/confirm_delete.html', data)
def render_primary(request, user_id = None, *args, **kwargs):
user = models.User.objects.get(id = user_id)
diff --git a/askbot/views/commands.py b/askbot/views/commands.py
index c072f7b8..f810a750 100644
--- a/askbot/views/commands.py
+++ b/askbot/views/commands.py
@@ -20,6 +20,8 @@ from django.http import HttpResponseRedirect
from django.http import HttpResponseForbidden
from django.forms import ValidationError, IntegerField, CharField
from django.shortcuts import get_object_or_404
+from django.shortcuts import render
+from django.template.loader import get_template
from django.views.decorators import csrf
from django.utils import simplejson
from django.utils.html import escape
@@ -28,18 +30,19 @@ from django.utils.translation import string_concat
from askbot.utils.slug import slugify
from askbot import models
from askbot import forms
-from askbot.conf import should_show_sort_by_relevance
+from askbot import conf
+from askbot import const
+from askbot import mail
from askbot.conf import settings as askbot_settings
from askbot.utils import category_tree
from askbot.utils import decorators
from askbot.utils import url_utils
from askbot.utils.forms import get_db_object_or_404
-from askbot import mail
-from django.template import Context
-from askbot.skins.loaders import render_into_skin, get_template
+from django.template import RequestContext
from askbot.skins.loaders import render_into_skin_as_string
from askbot.skins.loaders import render_text_into_skin
-from askbot import const
+from askbot.models.tag import get_tags_by_names
+
@csrf.csrf_exempt
@@ -115,7 +118,7 @@ def manage_inbox(request):
'post': post.html,
'reject_reason': reject_reason.details.html
}
- body_text = template.render(Context(data))
+ body_text = template.render(RequestContext(request, data))
mail.send_mail(
subject_line = _('your post was not accepted'),
body_text = unicode(body_text),
@@ -436,13 +439,18 @@ def mark_tag(request, **kwargs):#tagging system
reason = post_data['reason']
assert reason in ('good', 'bad', 'subscribed')
#separate plain tag names and wildcard tags
-
tagnames, wildcards = forms.clean_marked_tagnames(raw_tagnames)
- cleaned_tagnames, cleaned_wildcards = request.user.mark_tags(
- tagnames,
- wildcards,
- reason = reason,
- action = action
+
+ if request.user.is_administrator() and 'user' in post_data:
+ user = get_object_or_404(models.User, pk=post_data['user'])
+ else:
+ user = request.user
+
+ cleaned_tagnames, cleaned_wildcards = user.mark_tags(
+ tagnames,
+ wildcards,
+ reason = reason,
+ action = action
)
#lastly - calculate tag usage counts
@@ -684,7 +692,7 @@ def subscribe_for_tags(request):
return HttpResponseRedirect(reverse('index'))
else:
data = {'tags': tag_names}
- return render_into_skin('subscribe_for_tags.html', data, request)
+ return render(request, 'subscribe_for_tags.html', data)
else:
all_tag_names = pure_tag_names + wildcards
message = _('Please sign in to subscribe for: %(tags)s') \
@@ -693,33 +701,137 @@ def subscribe_for_tags(request):
request.session['subscribe_for_tags'] = (pure_tag_names, wildcards)
return HttpResponseRedirect(url_utils.get_login_url())
+@decorators.admins_only
+def list_bulk_tag_subscription(request):
+ if askbot_settings.SUBSCRIBED_TAG_SELECTOR_ENABLED is False:
+ raise Http404
+ object_list = models.BulkTagSubscription.objects.all()
+ data = {'object_list': object_list}
+ return render(request, 'tags/list_bulk_tag_subscription.html', data)
+
+@decorators.admins_only
+def create_bulk_tag_subscription(request):
+ if askbot_settings.SUBSCRIBED_TAG_SELECTOR_ENABLED is False:
+ raise Http404
+
+ data = {'action': _('Create')}
+ if request.method == "POST":
+ form = forms.BulkTagSubscriptionForm(request.POST)
+ if form.is_valid():
+ tag_names = form.cleaned_data['tags'].split(' ')
+ user_list = form.cleaned_data.get('users')
+ group_list = form.cleaned_data.get('groups')
+
+ bulk_subscription = models.BulkTagSubscription.objects.create(
+ tag_names=tag_names,
+ tag_author=request.user,
+ user_list=user_list,
+ group_list=group_list
+ )
+
+ return HttpResponseRedirect(reverse('list_bulk_tag_subscription'))
+ else:
+ data['form'] = form
+ else:
+ data['form'] = forms.BulkTagSubscriptionForm()
+
+ return render(request, 'tags/form_bulk_tag_subscription.html', data)
+
+@decorators.admins_only
+def edit_bulk_tag_subscription(request, pk):
+ if askbot_settings.SUBSCRIBED_TAG_SELECTOR_ENABLED is False:
+ raise Http404
+
+ bulk_subscription = get_object_or_404(models.BulkTagSubscription,
+ pk=pk)
+ data = {'action': _('Edit')}
+ if request.method == "POST":
+ form = forms.BulkTagSubscriptionForm(request.POST)
+ if form.is_valid():
+ bulk_subscription.tags.clear()
+ bulk_subscription.users.clear()
+ bulk_subscription.groups.clear()
+
+ if 'groups' in form.cleaned_data:
+ group_ids = [user.id for user in form.cleaned_data['groups']]
+ bulk_subscription.groups.add(*group_ids)
+
+ tags, new_tag_names = get_tags_by_names(form.cleaned_data['tags'].split(' '))
+ tag_id_list = [tag.id for tag in tags]
+
+ for new_tag_name in new_tag_names:
+ new_tag = models.Tag.objects.create(name=new_tag_name,
+ created_by=request.user)
+ tag_id_list.append(new_tag.id)
+
+ bulk_subscription.tags.add(*tag_id_list)
+
+ user_ids = []
+ for user in form.cleaned_data['users']:
+ user_ids.append(user)
+ user.mark_tags(bulk_subscription.tag_list(),
+ reason='subscribed', action='add')
+
+ bulk_subscription.users.add(*user_ids)
+
+ return HttpResponseRedirect(reverse('list_bulk_tag_subscription'))
+ else:
+ form_initial = {
+ 'users': bulk_subscription.users.all(),
+ 'groups': bulk_subscription.groups.all(),
+ 'tags': ' '.join([tag.name for tag in bulk_subscription.tags.all()]),
+ }
+ data.update({
+ 'bulk_subscription': bulk_subscription,
+ 'form': forms.BulkTagSubscriptionForm(initial=form_initial),
+ })
+
+ return render(request, 'tags/form_bulk_tag_subscription.html', data)
+
+@decorators.admins_only
+@decorators.post_only
+def delete_bulk_tag_subscription(request):
+ if askbot_settings.SUBSCRIBED_TAG_SELECTOR_ENABLED is False:
+ raise Http404
+
+ pk = request.POST.get('pk')
+ if pk:
+ bulk_subscription = get_object_or_404(models.BulkTagSubscription, pk=pk)
+ bulk_subscription.delete()
+ return HttpResponseRedirect(reverse('list_bulk_tag_subscription'))
+ else:
+ return HttpResponseRedirect(reverse('list_bulk_tag_subscription'))
@decorators.get_only
-def api_get_questions(request):
- """json api for retrieving questions"""
- query = request.GET.get('query', '').strip()
- if not query:
+def title_search(request):
+ """json api for retrieving questions by title match"""
+ query = request.GET.get('query_text')
+
+ if query is None:
return HttpResponseBadRequest('Invalid query')
+ query = query.strip()
+
if askbot_settings.GROUPS_ENABLED:
threads = models.Thread.objects.get_visible(user=request.user)
else:
threads = models.Thread.objects.all()
- threads = models.Thread.objects.get_for_query(
- search_query=query,
- qs=threads
- )
-
- if should_show_sort_by_relevance():
- threads = threads.extra(order_by = ['-relevance'])
+ threads = threads.get_for_title_query(query)
#todo: filter out deleted threads, for now there is no way
threads = threads.distinct()[:30]
- thread_list = [{
- 'title': escape(thread.title),
- 'url': thread.get_absolute_url(),
- 'answer_count': thread.get_answer_count(request.user)
- } for thread in threads]
+
+ thread_list = list()
+ for thread in threads:#todo: this is a temp hack until thread model is fixed
+ try:
+ thread_list.append({
+ 'title': escape(thread.title),
+ 'url': thread.get_absolute_url(),
+ 'answer_count': thread.get_answer_count(request.user)
+ })
+ except:
+ continue
+
json_data = simplejson.dumps(thread_list)
return HttpResponse(json_data, mimetype = "application/json")
@@ -735,10 +847,12 @@ def set_tag_filter_strategy(request):
filter_value = int(request.POST['filter_value'])
assert(filter_type in ('display', 'email'))
if filter_type == 'display':
- assert(filter_value in dict(const.TAG_DISPLAY_FILTER_STRATEGY_CHOICES))
+ allowed_values_dict = dict(conf.get_tag_display_filter_strategy_choices())
+ assert(filter_value in allowed_values_dict)
request.user.display_tag_filter_strategy = filter_value
else:
- assert(filter_value in dict(const.TAG_EMAIL_FILTER_STRATEGY_CHOICES))
+ allowed_values_dict = dict(conf.get_tag_email_filter_strategy_choices())
+ assert(filter_value in allowed_values_dict)
request.user.email_tag_filter_strategy = filter_value
request.user.save()
return HttpResponse('', mimetype = "application/json")
@@ -769,7 +883,7 @@ def close(request, id):#close question
'question': question,
'form': form,
}
- return render_into_skin('close.html', data, request)
+ return render(request, 'close.html', data)
except exceptions.PermissionDenied, e:
request.user.message_set.create(message = unicode(e))
return HttpResponseRedirect(question.get_absolute_url())
@@ -798,7 +912,7 @@ def reopen(request, id):#re-open question
'closed_by_profile_url': closed_by_profile_url,
'closed_by_username': closed_by_username,
}
- return render_into_skin('reopen.html', data, request)
+ return render(request, 'reopen.html', data)
except exceptions.PermissionDenied, e:
request.user.message_set.create(message = unicode(e))
@@ -815,12 +929,13 @@ def swap_question_with_answer(request):
"""
if request.user.is_authenticated():
if request.user.is_administrator() or request.user.is_moderator():
- answer = models.Post.objects.get_answers(request.user).get(id = request.POST['answer_id'])
+ answer = models.Post.objects.get_answers(
+ request.user
+ ).get(
+ id=request.POST['answer_id']
+ )
new_question = answer.swap_with_question(new_title = request.POST['new_title'])
- return {
- 'id': new_question.id,
- 'slug': new_question.slug
- }
+ return {'question_url': new_question.get_absolute_url() }
raise Http404
@csrf.csrf_exempt
@@ -1118,9 +1233,9 @@ def moderate_suggested_tag(request):
return
if thread_id:
- threads = models.Thread.objects.filter(id = thread_id)
+ threads = models.Thread.objects.filter(id=thread_id)
else:
- threads = tag.threads.all()
+ threads = tag.threads.none()
if form.cleaned_data['action'] == 'accept':
#todo: here we lose ability to come back
diff --git a/askbot/views/meta.py b/askbot/views/meta.py
index 7b271219..6714f61e 100644
--- a/askbot/views/meta.py
+++ b/askbot/views/meta.py
@@ -6,10 +6,13 @@ This module contains a collection of views displaying all sorts of secondary and
from django.shortcuts import render_to_response, get_object_or_404
from django.core.urlresolvers import reverse
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.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy
from django.views import static
from django.views.decorators import csrf
from django.db.models import Max, Count
@@ -21,16 +24,16 @@ from askbot.utils.forms import get_next_url
from askbot.mail import mail_moderators
from askbot.models import BadgeData, Award, User, Tag
from askbot.models import badges as badge_data
-from askbot.skins.loaders import get_template, render_into_skin, render_text_into_skin
+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
def generic_view(request, template = None, page_class = None):
- """this may be not necessary, since it is just a rewrite of render_into_skin"""
+ """this may be not necessary, since it is just a rewrite of render"""
if request is None: # a plug for strange import errors in django startup
return render_to_response('django_error.html')
- return render_into_skin(template, {'page_class': page_class}, request)
+ return render(request, template, {'page_class': page_class})
def config_variable(request, variable_name = None, mimetype = None):
"""Print value from the configuration settings
@@ -47,7 +50,7 @@ def about(request, template='about.html'):
'page_class': 'meta',
'content': askbot_settings.FORUM_ABOUT
}
- return render_into_skin('static_page.html', data, request)
+ return render(request, 'static_page.html', data)
def page_not_found(request, template='404.html'):
return generic_view(request, template)
@@ -60,7 +63,7 @@ def help(request):
'app_name': askbot_settings.APP_SHORT_NAME,
'page_class': 'meta'
}
- return render_into_skin('help.html', data, request)
+ return render(request, 'help.html', data)
def faq(request):
if askbot_settings.FORUM_FAQ.strip() != '':
@@ -69,18 +72,14 @@ def faq(request):
'content': askbot_settings.FORUM_FAQ,
'page_class': 'meta',
}
- return render_into_skin(
- 'static_page.html',
- data,
- request
- )
+ return render(request, 'static_page.html', data)
else:
data = {
'gravatar_faq_url': reverse('faq') + '#gravatar',
'ask_question_url': reverse('ask'),
'page_class': 'meta',
}
- return render_into_skin('faq_static.html', data, request)
+ return render(request, 'faq_static.html', data)
@csrf.csrf_protect
def feedback(request):
@@ -100,13 +99,26 @@ def feedback(request):
data=request.POST
)
if form.is_valid():
+
if not request.user.is_authenticated():
- data['email'] = form.cleaned_data.get('email',None)
+ data['email'] = form.cleaned_data.get('email', None)
+ else:
+ data['email'] = request.user.email
+
data['message'] = form.cleaned_data['message']
- data['name'] = form.cleaned_data.get('name',None)
- template = get_template('email/feedback_email.txt', request)
+ data['name'] = form.cleaned_data.get('name', None)
+ template = get_template('email/feedback_email.txt')
message = template.render(RequestContext(request, data))
- mail_moderators(_('Q&A forum feedback'), message)
+
+ headers = {}
+ if data['email']:
+ headers = {'Reply-To': data['email']}
+
+ mail_moderators(
+ _('Q&A forum feedback'),
+ message,
+ headers=headers
+ )
msg = _('Thanks for the feedback!')
request.user.message_set.create(message=msg)
return HttpResponseRedirect(get_next_url(request))
@@ -115,8 +127,8 @@ def feedback(request):
initial={'next':get_next_url(request)})
data['form'] = form
- return render_into_skin('feedback.html', data, request)
-feedback.CANCEL_MESSAGE=_('We look forward to hearing your feedback! Please, give it next time :)')
+ return render(request, 'feedback.html', data)
+feedback.CANCEL_MESSAGE=ugettext_lazy('We look forward to hearing your feedback! Please, give it next time :)')
def privacy(request):
data = {
@@ -124,7 +136,7 @@ def privacy(request):
'page_class': 'meta',
'content': askbot_settings.FORUM_PRIVACY
}
- return render_into_skin('static_page.html', data, request)
+ return render(request, 'static_page.html', data)
def badges(request):#user status/reputation system
#todo: supplement database data with the stuff from badges.py
@@ -132,23 +144,21 @@ def badges(request):#user status/reputation system
raise Http404
known_badges = badge_data.BADGES.keys()
badges = BadgeData.objects.filter(slug__in = known_badges).order_by('slug')
- my_badges = []
+ my_badge_ids = list()
if request.user.is_authenticated():
- my_badges = Award.objects.filter(
+ my_badge_ids = Award.objects.filter(
user=request.user
- ).values(
- 'badge_id'
+ ).values_list(
+ 'badge_id', flat=True
).distinct()
- #my_badges.query.group_by = ['badge_id']
data = {
'active_tab': 'badges',
'badges' : badges,
'page_class': 'meta',
- 'mybadges' : my_badges,
- 'feedback_faq_url' : reverse('feedback'),
+ 'my_badge_ids' : my_badge_ids
}
- return render_into_skin('badges.html', data, request)
+ return render(request, 'badges.html', data)
def badge(request, id):
#todo: supplement database data with the stuff from badges.py
@@ -169,7 +179,7 @@ def badge(request, id):
'badge' : badge,
'page_class': 'meta',
}
- return render_into_skin('badge.html', data, request)
+ return render(request, 'badge.html', data)
@admins_only
def list_suggested_tags(request):
@@ -209,4 +219,4 @@ def list_suggested_tags(request):
'page_title': _('Suggested tags'),
'paginator_context' : paginator_context,
}
- return render_into_skin('list_suggested_tags.html', data, request)
+ return render(request, 'list_suggested_tags.html', data)
diff --git a/askbot/views/readers.py b/askbot/views/readers.py
index 9801d5bc..ce92ded6 100644
--- a/askbot/views/readers.py
+++ b/askbot/views/readers.py
@@ -11,9 +11,11 @@ import logging
import urllib
import operator
from django.shortcuts import get_object_or_404
+from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponseNotAllowed
from django.core.paginator import Paginator, EmptyPage, InvalidPage
-from django.template import Context
+from django.template.loader import get_template
+from django.template import RequestContext
from django.utils import simplejson
from django.utils.html import escape
from django.utils.translation import ugettext as _
@@ -24,7 +26,7 @@ from django.core.urlresolvers import reverse
from django.core import exceptions as django_exceptions
from django.contrib.humanize.templatetags import humanize
from django.http import QueryDict
-from django.conf import settings
+from django.conf import settings as django_settings
import askbot
from askbot import exceptions
@@ -41,7 +43,6 @@ from askbot.utils.decorators import anonymous_forbidden, ajax_only, get_only
from askbot.search.state_manager import SearchState, DummySearchState
from askbot.templatetags import extra_tags
from askbot.conf import settings as askbot_settings
-from askbot.skins.loaders import render_into_skin, get_template #jinja2 template loading enviroment
from askbot.views import context
# used in index page
@@ -140,7 +141,10 @@ def questions(request, **kwargs):
# We have tags in session - pass it to the
# QueryDict but as a list - we want tags+
rss_query_dict.setlist("tags", search_state.tags)
- context_feed_url = '/%sfeeds/rss/?%s' % (settings.ASKBOT_URL, rss_query_dict.urlencode()) # Format the url with the QueryDict
+ context_feed_url = '/%sfeeds/rss/?%s' % (
+ django_settings.ASKBOT_URL,
+ rss_query_dict.urlencode()
+ ) # Format the url with the QueryDict
reset_method_count = len(filter(None, [search_state.query, search_state.tags, meta_data.get('author_name', None)]))
@@ -151,23 +155,31 @@ def questions(request, **kwargs):
question_counter = question_counter % {'q_num': humanize.intcomma(q_count),}
if q_count > page_size:
- paginator_tpl = get_template('main_page/paginator.html', request)
- paginator_html = paginator_tpl.render(Context({
- 'context': functions.setup_paginator(paginator_context),
- 'questions_count': q_count,
- 'page_size' : page_size,
- 'search_state': search_state,
- }))
+ paginator_tpl = get_template('main_page/paginator.html')
+ paginator_html = paginator_tpl.render(
+ RequestContext(
+ request, {
+ 'context': functions.setup_paginator(paginator_context),
+ 'questions_count': q_count,
+ 'page_size' : page_size,
+ 'search_state': search_state,
+ }
+ )
+ )
else:
paginator_html = ''
- questions_tpl = get_template('main_page/questions_loop.html', request)
- questions_html = questions_tpl.render(Context({
- 'threads': page,
- 'search_state': search_state,
- 'reset_method_count': reset_method_count,
- 'request': request
- }))
+ questions_tpl = get_template('main_page/questions_loop.html')
+ questions_html = questions_tpl.render(
+ RequestContext(
+ request, {
+ 'threads': page,
+ 'search_state': search_state,
+ 'reset_method_count': reset_method_count,
+ 'request': request
+ }
+ )
+ )
ajax_data = {
'query_data': {
@@ -219,14 +231,14 @@ def questions(request, **kwargs):
'tag_list_type' : tag_list_type,
'font_size' : extra_tags.get_tag_font_size(related_tags),
'display_tag_filter_strategy_choices': conf.get_tag_display_filter_strategy_choices(),
- 'email_tag_filter_strategy_choices': const.TAG_EMAIL_FILTER_STRATEGY_CHOICES,
+ 'email_tag_filter_strategy_choices': conf.get_tag_email_filter_strategy_choices(),
'update_avatar_data': schedules.should_update_avatar_data(request),
'query_string': search_state.query_string(),
'search_state': search_state,
'feed_url': context_feed_url,
}
- return render_into_skin('main_page.html', template_data, request)
+ return render(request, 'main_page.html', template_data)
def tags(request):#view showing a listing of available tags - plain list
@@ -316,10 +328,9 @@ def tags(request):#view showing a listing of available tags - plain list
'search_state': SearchState(*[None for x in range(7)])
}
- return render_into_skin('tags.html', data, request)
+ return render(request, 'tags.html', data)
@csrf.csrf_protect
-#@cache_page(60 * 5)
def question(request, id):#refactor - long subroutine. display question body, answers and comments
"""view that displays body of the question and
all answers to it
@@ -327,8 +338,7 @@ def question(request, id):#refactor - long subroutine. display question body, an
#process url parameters
#todo: fix inheritance of sort method from questions
#before = datetime.datetime.now()
- default_sort_method = request.session.get('questions_sort_method', 'votes')
- form = ShowQuestionForm(request.GET, default_sort_method)
+ form = ShowQuestionForm(request.GET)
form.full_clean()#always valid
show_answer = form.cleaned_data['show_answer']
show_comment = form.cleaned_data['show_comment']
@@ -440,6 +450,10 @@ def question(request, id):#refactor - long subroutine. display question body, an
thread = question_post.thread
+ if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False):
+ if thread.language_code != translation.get_language():
+ return HttpResponseRedirect(thread.get_absolute_url())
+
logging.debug('answer_sort_method=' + unicode(answer_sort_method))
#load answers and post id's->athor_id mapping
@@ -583,6 +597,7 @@ def question(request, id):#refactor - long subroutine. display question body, an
'user_post_id_list': user_post_id_list,
'user_can_post_comment': user_can_post_comment,#in general
'user_already_gave_answer': user_already_gave_answer,
+ 'oldest_answer_id': thread.get_oldest_answer_id(request.user),
'previous_answer': previous_answer,
'tab_id' : answer_sort_method,
'favorited' : favorited,
@@ -599,7 +614,7 @@ def question(request, id):#refactor - long subroutine. display question body, an
data.update(context.get_for_tag_editor())
- return render_into_skin('question.html', data, request)
+ return render(request, 'question.html', data)
def revisions(request, id, post_type = None):
assert post_type in ('question', 'answer')
@@ -622,7 +637,7 @@ def revisions(request, id, post_type = None):
'post': post,
'revisions': revisions,
}
- return render_into_skin('revisions.html', data, request)
+ return render(request, 'revisions.html', data)
@csrf.csrf_exempt
@ajax_only
diff --git a/askbot/views/users.py b/askbot/views/users.py
index 2a5b1047..0305eb48 100644
--- a/askbot/views/users.py
+++ b/askbot/views/users.py
@@ -17,10 +17,12 @@ import urllib
from django.db.models import Count
from django.conf import settings as django_settings
from django.contrib.auth.decorators import login_required
+from django.core import exceptions as django_exceptions
from django.core.paginator import Paginator, EmptyPage, InvalidPage
from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse
from django.shortcuts import get_object_or_404
+from django.shortcuts import render
from django.http import HttpResponse, HttpResponseForbidden
from django.http import HttpResponseRedirect, Http404
from django.utils.translation import ugettext as _
@@ -40,7 +42,6 @@ from askbot import models
from askbot import exceptions
from askbot.models.badges import award_badges_signal
from askbot.models.tag import format_personal_group_name
-from askbot.skins.loaders import render_into_skin
from askbot.search.state_manager import SearchState
from askbot.utils import url_utils
from askbot.utils.loading import load_module
@@ -61,7 +62,6 @@ def owner_or_moderator_required(f):
def show_users(request, by_group=False, group_id=None, group_slug=None):
"""Users view, including listing of users by group"""
-
if askbot_settings.GROUPS_ENABLED and not by_group:
default_group = models.Group.objects.get_global_group()
group_slug = slugify(default_group.name)
@@ -129,7 +129,7 @@ def show_users(request, by_group=False, group_id=None, group_slug=None):
except ValueError:
page = 1
- search_query = request.REQUEST.get('query', "")
+ search_query = request.GET.get('query', "")
if search_query == "":
if sortby == "newest":
order_by_parameter = '-date_joined'
@@ -200,7 +200,7 @@ def show_users(request, by_group=False, group_id=None, group_slug=None):
'group_openness_choices': group_openness_choices
}
- return render_into_skin('users.html', data, request)
+ return render(request, 'users.html', data)
@csrf.csrf_protect
def user_moderate(request, subject, context):
@@ -294,7 +294,7 @@ def user_moderate(request, subject, context):
'user_status_changed': user_status_changed
}
context.update(data)
- return render_into_skin('user_profile/user_moderate.html', context, request)
+ return render(request, 'user_profile/user_moderate.html', context)
#non-view function
def set_new_email(user, new_email, nomessage=False):
@@ -317,9 +317,9 @@ def edit_user(request, id):
if request.method == "POST":
form = forms.EditUserForm(user, request.POST)
if form.is_valid():
- new_email = sanitize_html(form.cleaned_data['email'])
-
- set_new_email(user, new_email)
+ if 'email' in form.cleaned_data and askbot_settings.EDITABLE_EMAIL:
+ new_email = sanitize_html(form.cleaned_data['email'])
+ set_new_email(user, new_email)
if askbot_settings.EDITABLE_SCREEN_NAME:
new_username = sanitize_html(form.cleaned_data['username'])
@@ -356,7 +356,7 @@ def edit_user(request, id):
'support_custom_avatars': ('avatar' in django_settings.INSTALLED_APPS),
'view_user': user,
}
- return render_into_skin('user_profile/user_edit.html', data, request)
+ return render(request, 'user_profile/user_edit.html', data)
def user_stats(request, user, context):
question_filter = {}
@@ -528,7 +528,7 @@ def user_stats(request, user, context):
}
context.update(data)
- return render_into_skin('user_profile/user_stats.html', context, request)
+ return render(request, 'user_profile/user_stats.html', context)
def user_recent(request, user, context):
@@ -561,24 +561,44 @@ def user_recent(request, user, context):
self.content_object = content_object
self.badge = badge
- activities = []
-
# TODO: Don't process all activities here for the user, only a subset ([:const.USER_VIEW_DATA_SIZE])
- for activity in models.Activity.objects.filter(user=user):
+ activity_types = (
+ const.TYPE_ACTIVITY_ASK_QUESTION,
+ const.TYPE_ACTIVITY_ANSWER,
+ const.TYPE_ACTIVITY_COMMENT_QUESTION,
+ const.TYPE_ACTIVITY_COMMENT_ANSWER,
+ const.TYPE_ACTIVITY_UPDATE_QUESTION,
+ const.TYPE_ACTIVITY_UPDATE_ANSWER,
+ const.TYPE_ACTIVITY_MARK_ANSWER,
+ const.TYPE_ACTIVITY_PRIZE
+ )
+
+ #source of information about activities
+ activity_objects = models.Activity.objects.filter(
+ user=user,
+ activity_type__in=activity_types
+ )[:const.USER_VIEW_DATA_SIZE]
+
+ #a list of digest objects, suitable for display
+ #the number of activities to show is not guaranteed to be
+ #const.USER_VIEW_DATA_TYPE, because we don't show activity
+ #for deleted content
+ activities = []
+ for activity in activity_objects:
# TODO: multi-if means that we have here a construct for which a design pattern should be used
# ask questions
if activity.activity_type == const.TYPE_ACTIVITY_ASK_QUESTION:
- q = activity.content_object
- if q.deleted:
+ question = activity.content_object
+ if not question.deleted:
activities.append(Event(
time=activity.active_at,
type=activity.activity_type,
- title=q.thread.title,
+ title=question.thread.title,
summary='', #q.summary, # TODO: was set to '' before, but that was probably wrong
answer_id=0,
- question_id=q.id
+ question_id=question.id
))
elif activity.activity_type == const.TYPE_ACTIVITY_ANSWER:
@@ -679,10 +699,10 @@ def user_recent(request, user, context):
'tab_name' : 'recent',
'tab_description' : _('recent user activity'),
'page_title' : _('profile - recent activity'),
- 'activities' : activities[:const.USER_VIEW_DATA_SIZE]
+ 'activities' : activities
}
context.update(data)
- return render_into_skin('user_profile/user_recent.html', context, request)
+ return render(request, 'user_profile/user_recent.html', context)
#not a view - no direct url route here, called by `user_responses`
@csrf.csrf_protect
@@ -714,7 +734,7 @@ def show_group_join_requests(request, user, context):
'join_requests': join_requests
}
context.update(data)
- return render_into_skin('user_inbox/group_join_requests.html', context, request)
+ return render(request, 'user_inbox/group_join_requests.html', context)
@owner_or_moderator_required
@@ -755,12 +775,12 @@ def user_responses(request, user, context):
elif section == 'messages':
if request.user != user:
raise Http404
- #here we take shortcut, because we don't care about
- #all the extra context loaded below
+
from group_messaging.views import SendersList, ThreadsList
context.update(SendersList().get_context(request))
context.update(ThreadsList().get_context(request))
data = {
+ 'inbox_threads_count': context['threads_count'],#a hackfor the inbox count
'active_tab':'users',
'page_class': 'user-profile-page',
'tab_name' : 'inbox',
@@ -769,9 +789,21 @@ def user_responses(request, user, context):
'page_title' : _('profile - messages')
}
context.update(data)
- return render_into_skin(
- 'user_inbox/messages.html', context, request
- )
+ if 'thread_id' in request.GET:
+ from group_messaging.models import Message
+ from group_messaging.views import ThreadDetails
+ try:
+ thread_id = request.GET['thread_id']
+ context.update(ThreadDetails().get_context(request, thread_id))
+ context['group_messaging_template_name'] = \
+ 'group_messaging/home_thread_details.html'
+ except Message.DoesNotExist:
+ raise Http404
+ else:
+ context['group_messaging_template_name'] = 'group_messaging/home.html'
+ #here we take shortcut, because we don't care about
+ #all the extra context loaded below
+ return render(request, 'user_inbox/messages.html', context)
else:
raise Http404
@@ -839,7 +871,7 @@ def user_responses(request, user, context):
'responses' : filtered_response_list,
}
context.update(data)
- return render_into_skin('user_inbox/responses_and_flags.html', context, request)
+ return render(request, 'user_inbox/responses_and_flags.html', context)
def user_network(request, user, context):
if 'followit' not in django_settings.INSTALLED_APPS:
@@ -850,7 +882,7 @@ def user_network(request, user, context):
'followers': user.get_followers(),
}
context.update(data)
- return render_into_skin('user_profile/user_network.html', context, request)
+ return render(request, 'user_profile/user_network.html', context)
@owner_or_moderator_required
def user_votes(request, user, context):
@@ -880,7 +912,7 @@ def user_votes(request, user, context):
'votes' : votes[:const.USER_VIEW_DATA_SIZE]
}
context.update(data)
- return render_into_skin('user_profile/user_votes.html', context, request)
+ return render(request, 'user_profile/user_votes.html', context)
def user_reputation(request, user, context):
@@ -903,7 +935,7 @@ def user_reputation(request, user, context):
'reps': reps
}
context.update(data)
- return render_into_skin('user_profile/user_reputation.html', context, request)
+ return render(request, 'user_profile/user_reputation.html', context)
def user_favorites(request, user, context):
@@ -921,7 +953,28 @@ def user_favorites(request, user, context):
'questions' : questions,
}
context.update(data)
- return render_into_skin('user_profile/user_favorites.html', context, request)
+ return render(request, 'user_profile/user_favorites.html', context)
+
+
+@csrf.csrf_protect
+def user_select_languages(request, id=None, slug=None):
+ if request.method != 'POST':
+ raise django_exceptions.PermissionDenied
+
+ user = get_object_or_404(models.User, id=id)
+
+ if not(request.user.id == user.id or request.user.is_administrator()):
+ raise django_exceptions.PermissionDenied
+
+ languages = request.POST.getlist('languages')
+ user.languages = ' '.join(languages)
+ user.save()
+
+ redirect_url = reverse(
+ 'user_subscriptions',
+ kwargs={'id': user.id, 'slug': slugify(user.username)}
+ )
+ return HttpResponseRedirect(redirect_url)
@owner_or_moderator_required
@@ -963,6 +1016,7 @@ def user_email_subscriptions(request, user, context):
data = {
'active_tab': 'users',
+ 'subscribed_tag_names': user.get_marked_tag_names('subscribed'),
'page_class': 'user-profile-page',
'tab_name': 'email_subscriptions',
'tab_description': _('email subscription settings'),
@@ -970,12 +1024,13 @@ def user_email_subscriptions(request, user, context):
'email_feeds_form': email_feeds_form,
'tag_filter_selection_form': tag_filter_form,
'action_status': action_status,
+ 'user_languages': user.languages.split()
}
context.update(data)
- return render_into_skin(
+ return render(
+ request,
'user_profile/user_email_subscriptions.html',
- context,
- request
+ context
)
@csrf.csrf_protect
@@ -994,7 +1049,7 @@ def user_custom_tab(request, user, context):
'tab_name': tab_settings['SLUG'],
'page_title': page_title
})
- return render_into_skin('user_profile/custom_tab.html', context, request)
+ return render(request, 'user_profile/custom_tab.html', context)
USER_VIEW_CALL_TABLE = {
'stats': user_stats,
@@ -1118,4 +1173,4 @@ def groups(request, id = None, slug = None):
'tab_name': scope,
'page_class': 'groups-page'
}
- return render_into_skin('groups.html', data, request)
+ return render(request, 'groups.html', data)
diff --git a/askbot/views/widgets.py b/askbot/views/widgets.py
index 4401bbdc..4d7d02b2 100644
--- a/askbot/views/widgets.py
+++ b/askbot/views/widgets.py
@@ -1,16 +1,15 @@
from datetime import datetime
-from django.core import exceptions
-from django.template import Context
+from django.template import RequestContext
+from django.template.loader import get_template
+from django.shortcuts import render
from django.http import HttpResponse, Http404
from django.views.decorators import csrf
from django.core.urlresolvers import reverse
from django.shortcuts import redirect, get_object_or_404
-from django.views.decorators.cache import cache_page
from django.contrib.auth.decorators import login_required
-from askbot.skins.loaders import render_into_skin, get_template
from askbot.conf import settings as askbot_settings
from askbot.utils import decorators
from askbot import models
@@ -47,7 +46,7 @@ def widgets(request):
'question_widgets': models.QuestionWidget.objects.all().count(),
'page_class': 'widgets'
}
- return render_into_skin('embed/widgets.html', data, request)
+ return render(request, 'embed/widgets.html', data)
@csrf.csrf_protect
def ask_widget(request, widget_id):
@@ -96,7 +95,7 @@ def ask_widget(request, widget_id):
}
if request.user.is_authenticated():
data_dict['author'] = request.user
- question = post_question(data_dict, request)
+ #question = post_question(data_dict, request)
return redirect('ask_by_widget_complete')
else:
request.session['widget_question'] = data_dict
@@ -129,7 +128,7 @@ def ask_widget(request, widget_id):
'widget': widget,
'editor_type': askbot_settings.EDITOR_TYPE
}
- return render_into_skin('embed/ask_by_widget.html', data, request)
+ return render(request, 'embed/ask_by_widget.html', data)
@login_required
def ask_widget_complete(request):
@@ -144,7 +143,7 @@ def ask_widget_complete(request):
del request.session['widget_css']
data = {'question_url': question_url, 'custom_css': custom_css}
- return render_into_skin('embed/ask_widget_complete.html', data, request)
+ return render(request, 'embed/ask_widget_complete.html', data)
@decorators.admins_only
@@ -155,9 +154,10 @@ def list_widgets(request, model):
'widgets': widgets,
'widget_name': model
}
- return render_into_skin('embed/list_widgets.html', data, request)
+ return render(request, 'embed/list_widgets.html', data)
@decorators.admins_only
+@csrf.csrf_protect
def create_widget(request, model):
form_class = _get_form(model)
model_class = _get_model(model)
@@ -173,9 +173,10 @@ def create_widget(request, model):
data = {'form': form,
'action': 'edit',
'widget_name': model}
- return render_into_skin('embed/widget_form.html', data, request)
+ return render(request, 'embed/widget_form.html', data)
@decorators.admins_only
+@csrf.csrf_protect
def edit_widget(request, model, widget_id):
model_class = _get_model(model)
form_class = _get_form(model)
@@ -212,9 +213,10 @@ def edit_widget(request, model, widget_id):
data = {'form': form,
'action': 'edit',
'widget_name': model}
- return render_into_skin('embed/widget_form.html', data, request)
+ return render(request, 'embed/widget_form.html', data)
@decorators.admins_only
+@csrf.csrf_protect
def delete_widget(request, model, widget_id):
model_class = _get_model(model)
widget = get_object_or_404(model_class, pk=widget_id)
@@ -222,28 +224,35 @@ def delete_widget(request, model, widget_id):
widget.delete()
return redirect('list_widgets', model=model)
else:
- return render_into_skin('embed/delete_widget.html',
- {'widget': widget, 'widget_name': model}, request)
+ return render(
+ request,
+ 'embed/delete_widget.html',
+ {'widget': widget, 'widget_name': model}
+ )
def render_ask_widget_js(request, widget_id):
widget = get_object_or_404(models.AskWidget, pk=widget_id)
variable_name = "AskbotAskWidget%d" % widget.id
- content_tpl = get_template('embed/askbot_widget.js', request)
- context_dict = {'widget': widget,
- 'host': request.get_host(),
- 'variable_name': variable_name}
- content = content_tpl.render(Context(context_dict))
+ content_tpl = get_template('embed/askbot_widget.js')
+ context_dict = {
+ 'widget': widget,
+ 'host': request.get_host(),
+ 'variable_name': variable_name
+ }
+ content = content_tpl.render(RequestContext(request, context_dict))
return HttpResponse(content, mimetype='text/javascript')
def render_ask_widget_css(request, widget_id):
widget = get_object_or_404(models.AskWidget, pk=widget_id)
variable_name = "AskbotAskWidget%d" % widget.id
- content_tpl = get_template('embed/askbot_widget.css', request)
- context_dict = {'widget': widget,
- 'host': request.get_host(),
- 'editor_type': askbot_settings.EDITOR_TYPE,
- 'variable_name': variable_name}
- content = content_tpl.render(Context(context_dict))
+ content_tpl = get_template('embed/askbot_widget.css')
+ context_dict = {
+ 'widget': widget,
+ 'host': request.get_host(),
+ 'editor_type': askbot_settings.EDITOR_TYPE,
+ 'variable_name': variable_name
+ }
+ content = content_tpl.render(RequestContext(request, context_dict))
return HttpResponse(content, mimetype='text/css')
def question_widget(request, widget_id):
@@ -277,4 +286,4 @@ def question_widget(request, widget_id):
'widget': widget
}
- return render_into_skin('embed/question_widget.html', data, request)
+ return render(request, 'embed/question_widget.html', data)
diff --git a/askbot/views/writers.py b/askbot/views/writers.py
index d1504d23..ee10c1ab 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -14,12 +14,19 @@ import tempfile
import time
import urlparse
from django.shortcuts import get_object_or_404
+from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
-from django.http import HttpResponseRedirect, HttpResponse, HttpResponseForbidden, Http404
+from django.http import HttpResponse
+from django.http import HttpResponseBadRequest
+from django.http import HttpResponseForbidden
+from django.http import HttpResponseRedirect
+from django.http import Http404
from django.utils import simplejson
from django.utils.html import strip_tags, escape
+from django.utils.translation import get_language
from django.utils.translation import ugettext as _
+from django.utils.translation import ugettext_lazy
from django.core.urlresolvers import reverse
from django.core import exceptions
from django.conf import settings
@@ -29,7 +36,6 @@ from askbot import exceptions as askbot_exceptions
from askbot import forms
from askbot import models
from askbot.conf import settings as askbot_settings
-from askbot.skins.loaders import render_into_skin
from askbot.utils import decorators
from askbot.utils.forms import format_errors
from askbot.utils.functions import diff_date
@@ -192,11 +198,11 @@ def import_data(request):
'dump_upload_form': form,
'need_configuration': (not stackexchange.is_ready())
}
- return render_into_skin('import_data.html', data, request)
+ return render(request, 'import_data.html', data)
#@login_required #actually you can post anonymously, but then must register
@csrf.csrf_protect
-@decorators.check_authorization_to_post(_(
+@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 "
@@ -222,6 +228,7 @@ def ask(request):#view used to ask a new question
ask_anonymously = form.cleaned_data['ask_anonymously']
post_privately = form.cleaned_data['post_privately']
group_id = form.cleaned_data.get('group_id', None)
+ language = form.cleaned_data.get('language', None)
if request.user.is_authenticated():
drafts = models.DraftQuestion.objects.filter(
@@ -232,14 +239,15 @@ def ask(request):#view used to ask a new question
user = form.get_post_user(request.user)
try:
question = user.post_question(
- title = title,
- body_text = text,
- tags = tagnames,
- wiki = wiki,
- is_anonymous = ask_anonymously,
- is_private = post_privately,
- timestamp = timestamp,
- group_id = group_id
+ title=title,
+ body_text=text,
+ tags=tagnames,
+ wiki=wiki,
+ is_anonymous=ask_anonymously,
+ is_private=post_privately,
+ timestamp=timestamp,
+ group_id=group_id,
+ language=language
)
return HttpResponseRedirect(question.get_absolute_url())
except exceptions.PermissionDenied, e:
@@ -249,7 +257,6 @@ def ask(request):#view used to ask a new question
else:
request.session.flush()
session_key = request.session.session_key
- summary = strip_tags(text)[:120]
models.AnonymousQuestion.objects.create(
session_key = session_key,
title = title,
@@ -257,7 +264,6 @@ def ask(request):#view used to ask a new question
wiki = wiki,
is_anonymous = ask_anonymously,
text = text,
- summary = summary,
added_at = timestamp,
ip_addr = request.META['REMOTE_ADDR'],
)
@@ -278,12 +284,13 @@ def ask(request):#view used to ask a new question
draft_tagnames = draft.tagnames
form.initial = {
- 'title': request.REQUEST.get('title', draft_title),
- 'text': request.REQUEST.get('text', draft_text),
+ 'ask_anonymously': request.REQUEST.get('ask_anonymousy', False),
'tags': request.REQUEST.get('tags', draft_tagnames),
+ 'text': request.REQUEST.get('text', draft_text),
+ 'title': request.REQUEST.get('title', draft_title),
+ 'post_privately': request.REQUEST.get('post_privately', False),
+ 'language': get_language(),
'wiki': request.REQUEST.get('wiki', False),
- 'ask_anonymously': request.REQUEST.get('ask_anonymousy', False),
- 'post_privately': request.REQUEST.get('post_privately', False)
}
if 'group_id' in request.REQUEST:
try:
@@ -302,7 +309,7 @@ def ask(request):#view used to ask a new question
'tag_names': list()#need to keep context in sync with edit_question for tag editor
}
data.update(context.get_for_tag_editor())
- return render_into_skin('ask.html', data, request)
+ return render(request, 'ask.html', data)
@login_required
@csrf.csrf_exempt
@@ -349,7 +356,7 @@ def retag_question(request, id):
'question': question,
'form' : form,
}
- return render_into_skin('question_retag.html', data, request)
+ return render(request, 'question_retag.html', data)
except exceptions.PermissionDenied, e:
if request.is_ajax():
response_data = {
@@ -394,7 +401,7 @@ def edit_question(request, id):
form = forms.EditQuestionForm(
request.POST,
question=question,
- user=quest.user,
+ user=question.user,
revision=revision
)
else:#new content edit
@@ -408,31 +415,36 @@ def edit_question(request, id):
revision_form = forms.RevisionForm(question, revision)
if form.is_valid():
if form.has_changed():
-
if form.cleaned_data['reveal_identity']:
question.thread.remove_author_anonymity()
+ if 'language' in form.cleaned_data:
+ question.thread.language_code = form.cleaned_data['language']
+
is_anon_edit = form.cleaned_data['stay_anonymous']
is_wiki = form.cleaned_data.get('wiki', question.wiki)
post_privately = form.cleaned_data['post_privately']
+ suppress_email = form.cleaned_data['suppress_email']
user = form.get_post_user(request.user)
user.edit_question(
- question = question,
- title = form.cleaned_data['title'],
- body_text = form.cleaned_data['text'],
+ question=question,
+ title=form.cleaned_data['title'],
+ body_text=form.cleaned_data['text'],
revision_comment = form.cleaned_data['summary'],
tags = form.cleaned_data['tags'],
wiki = is_wiki,
edit_anonymously = is_anon_edit,
- is_private = post_privately
+ is_private = post_privately,
+ suppress_email=suppress_email
)
return HttpResponseRedirect(question.get_absolute_url())
else:
#request type was "GET"
revision_form = forms.RevisionForm(question, revision)
initial = {
+ 'language': question.thread.language_code,
'post_privately': question.is_private(),
'wiki': question.wiki
}
@@ -455,7 +467,7 @@ def edit_question(request, id):
'category_tree_data': askbot_settings.CATEGORY_TREE
}
data.update(context.get_for_tag_editor())
- return render_into_skin('question_edit.html', data, request)
+ return render(request, 'question_edit.html', data)
except exceptions.PermissionDenied, e:
request.user.message_set.create(message = unicode(e))
@@ -500,13 +512,15 @@ def edit_answer(request, id):
if form.is_valid():
if form.has_changed():
user = form.get_post_user(request.user)
+ suppress_email = form.cleaned_data['suppress_email']
+ is_private = form.cleaned_data.get('post_privately', False)
user.edit_answer(
answer=answer,
body_text=form.cleaned_data['text'],
revision_comment=form.cleaned_data['summary'],
wiki=form.cleaned_data.get('wiki', answer.wiki),
- is_private=form.cleaned_data.get('post_privately', False)
- #todo: add wiki field to form
+ is_private=is_private,
+ suppress_email=suppress_email
)
return HttpResponseRedirect(answer.get_absolute_url())
else:
@@ -522,14 +536,14 @@ def edit_answer(request, id):
'revision_form': revision_form,
'form': form,
}
- return render_into_skin('answer_edit.html', data, request)
+ return render(request, 'answer_edit.html', data)
except exceptions.PermissionDenied, e:
request.user.message_set.create(message = unicode(e))
return HttpResponseRedirect(answer.get_absolute_url())
#todo: rename this function to post_new_answer
-@decorators.check_authorization_to_post(_('Please log in to answer questions'))
+@decorators.check_authorization_to_post(ugettext_lazy('Please log in to answer questions'))
@decorators.check_spam('text')
def answer(request, id):#process a new answer
"""view that posts new answer
@@ -580,7 +594,6 @@ def answer(request, id):#process a new answer
question=question,
wiki=wiki,
text=text,
- summary=strip_tags(text)[:120],
session_key=request.session.session_key,
ip_addr=request.META['REMOTE_ADDR'],
)
@@ -670,10 +683,20 @@ def edit_comment(request):
if request.user.is_anonymous():
raise exceptions.PermissionDenied(_('Sorry, anonymous users cannot edit comments'))
- comment_id = int(request.POST['comment_id'])
+ form = forms.EditCommentForm(request.POST)
+ if form.is_valid() == False:
+ return HttpResponseBadRequest()
+
+ comment_id = form.cleaned_data['comment_id']
+ suppress_email = form.cleaned_data['suppress_email']
+
comment_post = models.Post.objects.get(post_type='comment', id=comment_id)
- request.user.edit_comment(comment_post=comment_post, body_text = request.POST['comment'])
+ request.user.edit_comment(
+ comment_post=comment_post,
+ body_text = request.POST['comment'],
+ suppress_email=suppress_email
+ )
is_deletable = template_filters.can_delete_comment(comment_post.author, comment_post)
is_editable = template_filters.can_edit_comment(comment_post.author, comment_post)
@@ -709,14 +732,19 @@ def delete_comment(request):
raise exceptions.PermissionDenied(msg)
if request.is_ajax():
- comment_id = request.POST['comment_id']
+ form = forms.DeleteCommentForm(request.POST)
+
+ if form.is_valid() == False:
+ return HttpResponseBadRequest()
+
+ comment_id = form.cleaned_data['comment_id']
comment = get_object_or_404(models.Post, post_type='comment', id=comment_id)
request.user.assert_can_delete_comment(comment)
parent = comment.parent
comment.delete()
#attn: recalc denormalized field
- parent.comment_count = parent.comment_count - 1
+ parent.comment_count = parent.comments.count()
parent.save()
parent.thread.invalidate_cached_data()
@@ -766,22 +794,43 @@ def comment_to_answer(request):
@decorators.admins_only
@decorators.post_only
-def answer_to_comment(request):
+#todo: change the urls config for this
+def repost_answer_as_comment(request, destination=None):
+ assert(
+ destination in (
+ 'comment_under_question',
+ 'comment_under_previous_answer'
+ )
+ )
answer_id = request.POST.get('answer_id')
if answer_id:
answer_id = int(answer_id)
answer = get_object_or_404(models.Post,
post_type = 'answer', id=answer_id)
- if len(answer.text) <= 300:
+
+ if destination == 'comment_under_question':
+ destination_post = answer.thread._question_post()
+ else:
+ #comment_under_previous_answer
+ destination_post = answer.get_previous_answer(user=request.user)
+ #todo: implement for comment under other answer
+
+ if destination_post is None:
+ message = _('Error - could not find the destination post')
+ request.user.message_set.create(message=message)
+ return HttpResponseRedirect(answer.get_absolute_url())
+
+ if len(answer.text) <= askbot_settings.MAX_COMMENT_LENGTH:
answer.post_type = 'comment'
- answer.parent = answer.thread._question_post()
+ answer.parent = destination_post
#can we trust this?
old_comment_count = answer.comment_count
answer.comment_count = 0
answer_comments = models.Post.objects.get_comments().filter(parent=answer)
- answer_comments.update(parent=answer.parent)
+ answer_comments.update(parent=destination_post)
+ #why this and not just "save"?
answer.parse_and_save(author=answer.author)
answer.thread.update_answer_count()
@@ -790,7 +839,11 @@ def answer_to_comment(request):
answer.thread.invalidate_cached_data()
else:
- request.user.message_set.create(message = _("the selected answer cannot be a comment"))
+ message = _(
+ 'Cannot convert, because text has more characters than '
+ '%(max_chars)s - maximum allowed for comments'
+ ) % {'max_chars': askbot_settings.MAX_COMMENT_LENGTH}
+ request.user.message_set.create(message=message)
return HttpResponseRedirect(answer.get_absolute_url())
else:
diff --git a/askbot_requirements.txt b/askbot_requirements.txt
index 2be12b8e..a9a939b4 100644
--- a/askbot_requirements.txt
+++ b/askbot_requirements.txt
@@ -1,5 +1,5 @@
akismet
-django==1.3.1
+django>=1.3.1
Jinja2
Coffin>=0.3
South>=0.7.1
@@ -19,6 +19,7 @@ django-recaptcha-works
python-openid
pystache==0.3.1
pytz
+sanction
django-tinymce
longerusername
beautifulsoup4
diff --git a/askbot_requirements_dev.txt b/askbot_requirements_dev.txt
index b960c76e..1fbd064c 100644
--- a/askbot_requirements_dev.txt
+++ b/askbot_requirements_dev.txt
@@ -1,5 +1,5 @@
akismet
-django==1.3.1
+django==1.4.2
Jinja2
Coffin>=0.3
South>=0.7.1
@@ -21,3 +21,7 @@ python-openid
pystache==0.3.1
pylint
pytz
+sanction
+django-tinymce
+longerusername
+beautifulsoup4
diff --git a/group_messaging/models.py b/group_messaging/models.py
deleted file mode 100644
index 62f720cf..00000000
--- a/group_messaging/models.py
+++ /dev/null
@@ -1,249 +0,0 @@
-"""models for the ``group_messaging`` app
-"""
-import datetime
-from django.db import models
-from django.contrib.auth.models import Group
-from django.contrib.auth.models import User
-
-MAX_TITLE_LENGTH = 80
-MAX_SENDERS_INFO_LENGTH = 64
-
-#dummy parse message function
-parse_message = lambda v: v
-
-GROUP_NAME_TPL = '_personal_%s'
-
-def get_personal_group_by_user_id(user_id):
- return Group.objects.get(name=GROUP_NAME_TPL % user_id)
-
-
-def get_personal_groups_for_users(users):
- """for a given list of users return their personal groups"""
- group_names = [(GROUP_NAME_TPL % user.id) for user in users]
- return Group.objects.filter(name__in=group_names)
-
-
-def get_personal_group(user):
- """returns personal group for the user"""
- return get_personal_group_by_user_id(user.id)
-
-
-def create_personal_group(user):
- """creates a personal group for the user"""
- group = Group(name=GROUP_NAME_TPL % user.id)
- group.save()
- return group
-
-
-class LastVisitTime(models.Model):
- """just remembers when a user has
- last visited a given thread
- """
- user = models.ForeignKey(User)
- message = models.ForeignKey('Message')
- at = models.DateTimeField(auto_now_add=True)
-
- class Meta:
- unique_together = ('user', 'message')
-
-
-class SenderListManager(models.Manager):
- """model manager for the :class:`SenderList`"""
-
- def get_senders_for_user(self, user=None):
- """returns query set of :class:`User`"""
- user_groups = user.groups.all()
- lists = self.filter(recipient__in=user_groups)
- user_ids = lists.values_list(
- 'senders__id', flat=True
- ).distinct()
- return User.objects.filter(id__in=user_ids)
-
-class SenderList(models.Model):
- """a model to store denormalized data
- about who sends messages to any given person
- sender list is populated automatically
- as new messages are created
- """
- recipient = models.ForeignKey(Group, unique=True)
- senders = models.ManyToManyField(User)
- objects = SenderListManager()
-
-
-class MessageMemo(models.Model):
- """A bridge between message recipients and messages
- these records are only created when user sees a message.
- The idea is that using groups as recipients, we can send
- messages to massive numbers of users, without cluttering
- the database.
-
- Instead we'll be creating a "seen" message after user
- reads the message.
- """
- SEEN = 0
- ARCHIVED = 1
- STATUS_CHOICES = (
- (SEEN, 'seen'),
- (ARCHIVED, 'archived')
- )
- user = models.ForeignKey(User)
- message = models.ForeignKey('Message')
- status = models.SmallIntegerField(
- choices=STATUS_CHOICES, default=SEEN
- )
-
- class Meta:
- unique_together = ('user', 'message')
-
-
-class MessageManager(models.Manager):
- """model manager for the :class:`Message`"""
-
- def get_threads_for_user(self, user):
- user_groups = user.groups.all()
- return self.filter(
- root=None,
- message_type=Message.STORED,
- recipients__in=user_groups
- )
-
- def create(self, **kwargs):
- """creates a message"""
- root = kwargs.get('root', None)
- if root is None:
- parent = kwargs.get('parent', None)
- if parent:
- if parent.root:
- root = parent.root
- else:
- root = parent
- kwargs['root'] = root
-
- headline = kwargs.get('headline', kwargs['text'])
- kwargs['headline'] = headline[:MAX_TITLE_LENGTH]
- kwargs['html'] = parse_message(kwargs['text'])
-
- message = super(MessageManager, self).create(**kwargs)
- #creator of message saw it by definition
- #crate a "seen" memo for the sender, because we
- #don't want to inform the user about his/her own post
- sender = kwargs['sender']
- MessageMemo.objects.create(
- message=message, user=sender, status=MessageMemo.SEEN
- )
- return message
-
-
- def create_thread(self, sender=None, recipients=None, text=None):
- """creates a stored message and adds recipients"""
- message = self.create(
- message_type=Message.STORED,
- sender=sender,
- senders_info=sender.username,
- text=text,
- )
- message.add_recipients(recipients)
- return message
-
- def create_response(self, sender=None, text=None, parent=None):
- message = self.create(
- parent=parent,
- message_type=Message.STORED,
- sender=sender,
- text=text,
- )
- #recipients are parent's recipients + sender
- #creator of response gets memo in the "read" status
- recipients = set(parent.recipients.all())
- senders_group = get_personal_group(parent.sender)
- recipients.add(senders_group)
- message.add_recipients(recipients)
- #add author of the parent as a recipient to parent
- parent.add_recipients([senders_group])
- #mark last active timestamp for the root message
- #so that we know that this thread was most recently
- #updated
- message.update_root_info()
- return message
-
-
-class Message(models.Model):
- """the message model allowing users to send
- messages to other users and groups, via
- personal groups.
- """
- STORED = 0
- TEMPORARY = 1
- ONE_TIME = 2
- MESSAGE_TYPE_CHOICES = (
- (STORED, 'email-like message, stored in the inbox'),
- (ONE_TIME, 'will be shown just once'),
- (TEMPORARY, 'will be shown until certain time')
- )
-
- message_type = models.SmallIntegerField(
- choices=MESSAGE_TYPE_CHOICES,
- default=STORED,
- )
-
- sender = models.ForeignKey(User, related_name='sent_messages')
-
- senders_info = models.CharField(
- max_length=MAX_SENDERS_INFO_LENGTH,
- default=''
- )#comma-separated list of a few names
-
- recipients = models.ManyToManyField(Group)
-
- root = models.ForeignKey(
- 'self', null=True,
- blank=True, related_name='descendants'
- )
-
- parent = models.ForeignKey(
- 'self', null=True,
- blank=True, related_name='children'
- )
-
- headline = models.CharField(max_length=MAX_TITLE_LENGTH)
-
- text = models.TextField(
- null=True, blank=True,
- help_text='source text for the message, e.g. in markdown format'
- )
-
- html = models.TextField(
- null=True, blank=True,
- help_text='rendered html of the message'
- )
-
- sent_at = models.DateTimeField(auto_now_add=True)
- last_active_at = models.DateTimeField(auto_now_add=True)
- active_until = models.DateTimeField(blank=True, null=True)
-
- objects = MessageManager()
-
- def add_recipients(self, recipients):
- """adds recipients to the message
- and updates the sender lists for all recipients
- todo: sender lists may be updated in a lazy way - per user
- """
- self.recipients.add(*recipients)
- for recipient in recipients:
- sender_list, created = SenderList.objects.get_or_create(recipient=recipient)
- sender_list.senders.add(self.sender)
-
- def update_root_info(self):
- """Update the last active at timestamp and
- the contributors info, if relevant.
- Root object will be saved to the database.
- """
- self.root.last_active_at = datetime.datetime.now()
- senders_names = self.root.senders_info.split(',')
-
- if self.sender.username in senders_names:
- senders_names.remove(self.sender.username)
- senders_names.insert(0, self.sender.username)
-
- self.root.senders_info = (','.join(senders_names))[:64]
- self.root.save()
diff --git a/group_messaging/tests.py b/group_messaging/tests.py
deleted file mode 100644
index c8401dc1..00000000
--- a/group_messaging/tests.py
+++ /dev/null
@@ -1,118 +0,0 @@
-from django.test import TestCase
-from django.contrib.auth.models import User, Group
-from group_messaging.models import Message
-from group_messaging.models import MessageMemo
-from group_messaging.models import SenderList
-from group_messaging.models import get_personal_group
-from group_messaging.models import create_personal_group
-
-MESSAGE_TEXT = 'test message text'
-
-def create_user(name):
- """creates a user and a personal group,
- returns the created user"""
- user = User.objects.create_user(name, name + '@example.com')
- #note that askbot will take care of three lines below automatically
- try:
- group = get_personal_group(user)
- except Group.DoesNotExist:
- group = create_personal_group(user)
- group_name = '_personal_%d' % user.id
- group, created = Group.objects.get_or_create(name=group_name)
- user.groups.add(group)
- return user
-
-class ModelTests(TestCase):
- """test cases for the `private_messaging` models"""
-
- def setUp(self):
- self.sender = create_user('sender')
- self.recipient = create_user('recipient')
-
- def create_thread(self, recipients):
- return Message.objects.create_thread(
- sender=self.sender, recipients=recipients,
- text=MESSAGE_TEXT
- )
-
- def create_thread_for_user(self, user):
- group = get_personal_group(user)
- return self.create_thread([group])
-
- def test_create_thread_for_user(self):
- """the basic create thread with one recipient
- tests that the recipient is there"""
- message = self.create_thread_for_user(self.recipient)
- #message type is stored
- self.assertEqual(message.message_type, Message.STORED)
- #recipient is in the list of recipients
- recipients = set(message.recipients.all())
- recipient_group = get_personal_group(self.recipient)
- #sender_group = get_personal_group(self.sender) #maybe add this too
- expected_recipients = set([recipient_group])
- self.assertEqual(recipients, expected_recipients)
- #self.assertRaises(
- # MessageMemo.DoesNotExist,
- # MessageMemo.objects.get,
- # message=message
- #)
- #make sure that the original senders memo to the root
- #message is marke ad seen
- memos = MessageMemo.objects.filter(
- message=message,
- user=self.sender
- )
- self.assertEquals(memos.count(), 1)
- self.assertEqual(memos[0].status, MessageMemo.SEEN)
-
- def test_get_senders_for_user(self):
- """this time send thread to a real group test that
- member of the group has updated the sender list"""
- group = Group.objects.create(name='somegroup')
- self.recipient.groups.add(group)
- message = self.create_thread([group])
- senders = SenderList.objects.get_senders_for_user(self.recipient)
- self.assertEqual(set(senders), set([self.sender]))
-
- def test_create_thread_response(self):
- """create a thread with one response,
- then load thread for the user
- test that only the root message is retrieved"""
- root_message = self.create_thread_for_user(self.recipient)
- response = Message.objects.create_response(
- sender=self.recipient,
- text='some response',
- parent=root_message
- )
- self.assertEqual(response.message_type, Message.STORED)
-
- #assert that there is only one "seen" memo for the response
- memos = MessageMemo.objects.filter(message=response)
- self.assertEqual(memos.count(), 1)
- self.assertEqual(memos[0].user, self.recipient)
- self.assertEqual(memos[0].status, MessageMemo.SEEN)
-
- #assert that recipients are the two people who are part of
- #this conversation
- recipients = set(response.recipients.all())
- sender_group = get_personal_group(self.sender)
- recipient_group = get_personal_group(self.recipient)
- expected_recipients = set([sender_group, recipient_group])
- self.assertEqual(recipients, expected_recipients)
-
- def test_get_threads_for_user(self):
- root_message = self.create_thread_for_user(self.recipient)
- threads = set(Message.objects.get_threads_for_user(self.sender))
- self.assertEqual(threads, set([]))
- threads = set(Message.objects.get_threads_for_user(self.recipient))
- self.assertEqual(threads, set([root_message]))
-
- response = Message.objects.create_response(
- sender=self.recipient,
- text='some response',
- parent=root_message
- )
- threads = set(Message.objects.get_threads_for_user(self.sender))
- self.assertEqual(threads, set([root_message]))
- threads = set(Message.objects.get_threads_for_user(self.recipient))
- self.assertEqual(threads, set([root_message]))
diff --git a/setup.py b/setup.py
index e148704b..7867f6f8 100644
--- a/setup.py
+++ b/setup.py
@@ -124,8 +124,9 @@ print """**************************************************************
* Thanks for installing Askbot. *
* *
* To start deploying type: askbot-setup *
-* Please take a look at the manual askbot/doc/INSTALL *
+* *
+* Please take a look at the manual http://askbot.org/doc/ *
* And please do not hesitate to ask your questions at *
-* at http://askbot.org *
+* at http://askbot.org/en/questions/ *
* *
**************************************************************"""