summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-04-25 17:15:26 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-04-25 17:15:26 -0400
commitcc8337da9046bff5243672e20f1dea9c18b00da6 (patch)
tree77ade69869105f1838df5e8616bb994844507cec
parent3122fb8a2599944e623c8e21f285a9e4dd9e132a (diff)
parent02510a462392dd2e9e46e945d51efb374e0dc06f (diff)
downloadaskbot-cc8337da9046bff5243672e20f1dea9c18b00da6.tar.gz
askbot-cc8337da9046bff5243672e20f1dea9c18b00da6.tar.bz2
askbot-cc8337da9046bff5243672e20f1dea9c18b00da6.zip
merged newer ui branch to master
-rw-r--r--README2
-rwxr-xr-xdjango_authopenid/views.py18
-rw-r--r--forum/LICENSE (renamed from LICENSE)0
-rwxr-xr-xforum/const.py41
-rw-r--r--forum/cron/README (renamed from cron/README)0
-rwxr-xr-xforum/cron/multi_award_badges (renamed from cron/multi_award_badges)0
-rwxr-xr-xforum/cron/multi_award_badges_virtualenv (renamed from cron/multi_award_badges_virtualenv)0
-rwxr-xr-xforum/cron/once_award_badges (renamed from cron/once_award_badges)0
-rwxr-xr-xforum/cron/once_award_badges_virtualenv (renamed from cron/once_award_badges_virtualenv)0
-rw-r--r--forum/cron/send_email_alerts (renamed from cron/send_email_alerts)0
-rw-r--r--forum/cron/send_email_alerts_virtualenv (renamed from cron/send_email_alerts_virtualenv)0
-rw-r--r--forum/documentation/HOW_TO_DEBUG (renamed from HOW_TO_DEBUG)0
-rw-r--r--forum/documentation/INSTALL (renamed from INSTALL)33
-rw-r--r--forum/documentation/INSTALL.pip (renamed from INSTALL.pip)0
-rw-r--r--forum/documentation/INSTALL.webfaction (renamed from INSTALL.webfaction)0
-rw-r--r--forum/documentation/ROADMAP.rst (renamed from ROADMAP.rst)0
-rw-r--r--forum/documentation/TODO.rst (renamed from TODO.rst)0
-rw-r--r--forum/documentation/UPGRADE24
-rw-r--r--forum/documentation/WISH_LIST (renamed from WISH_LIST)0
-rw-r--r--forum/documentation/askbot-requirements.txt (renamed from askbot-requirements.txt)0
-rwxr-xr-xforum/forms.py119
-rw-r--r--forum/importers/__init__.py (renamed from stackexchange/__init__.py)0
-rw-r--r--forum/importers/stackexchange/ANOMALIES (renamed from stackexchange/ANOMALIES)0
-rw-r--r--forum/importers/stackexchange/README (renamed from stackexchange/README)0
-rw-r--r--forum/importers/stackexchange/__init__.py (renamed from stackexchange/management/__init__.py)0
-rw-r--r--forum/importers/stackexchange/management/__init__.py (renamed from stackexchange/management/commands/__init__.py)0
-rw-r--r--forum/importers/stackexchange/management/commands/__init__.py0
-rw-r--r--forum/importers/stackexchange/management/commands/load_stackexchange.py (renamed from stackexchange/management/commands/load_stackexchange.py)4
-rw-r--r--forum/importers/stackexchange/models.py (renamed from stackexchange/models.py)0
-rw-r--r--forum/importers/stackexchange/parse_models.py (renamed from stackexchange/parse_models.py)0
-rw-r--r--forum/middleware/view_log.py74
-rw-r--r--forum/migrations/0001_initial.py780
-rw-r--r--forum/migrations/0002_auto__add_field_answer_text__chg_field_answer_html__add_field_question.py368
-rw-r--r--forum/migrations/0003_copy_denorm_text_record_to_posts_for_fulltext_search.py354
-rw-r--r--forum/migrations/0004_install_full_text_indexes_for_mysql.py389
-rw-r--r--forum/migrations/__init__.py0
-rwxr-xr-xforum/models/__init__.py3
-rwxr-xr-xforum/models/answer.py5
-rwxr-xr-xforum/models/base.py40
-rwxr-xr-xforum/models/question.py150
-rwxr-xr-xforum/models/tag.py4
-rw-r--r--forum/search/README5
-rw-r--r--forum/search/__init__.py0
-rw-r--r--forum/search/indexer.py9
-rw-r--r--forum/search/sphinx/README4
-rw-r--r--forum/search/sphinx/sphinx.conf (renamed from sphinx/sphinx.conf)0
-rw-r--r--forum/search/state_manager.py152
-rw-r--r--forum/skins/default/media/images/logo.gifbin1496 -> 2272 bytes
-rwxr-xr-xforum/skins/default/media/style/style.css174
-rw-r--r--forum/skins/default/templates/about.html2
-rw-r--r--forum/skins/default/templates/ask.html2
-rw-r--r--forum/skins/default/templates/ask_form.html66
-rw-r--r--forum/skins/default/templates/base.html16
-rw-r--r--forum/skins/default/templates/base_content.html1
-rw-r--r--forum/skins/default/templates/book.html2
-rw-r--r--forum/skins/default/templates/faq.html2
-rw-r--r--forum/skins/default/templates/feedback.html2
-rw-r--r--forum/skins/default/templates/header.html68
-rw-r--r--forum/skins/default/templates/index.html7
-rw-r--r--forum/skins/default/templates/index_.html7
-rw-r--r--forum/skins/default/templates/input_bar.html45
-rw-r--r--forum/skins/default/templates/question.html15
-rw-r--r--forum/skins/default/templates/question_list.html2
-rw-r--r--forum/skins/default/templates/question_summary_list_roll.html2
-rw-r--r--forum/skins/default/templates/questions.html245
-rw-r--r--forum/skins/default/templates/tag_selector.html9
-rw-r--r--forum/skins/default/templates/tags.html9
-rw-r--r--forum/skins/default/templates/user.html2
-rw-r--r--forum/skins/default/templates/user_reputation.html7
-rw-r--r--forum/skins/default/templates/user_stats.html2
-rw-r--r--forum/skins/default/templates/users.html2
-rw-r--r--forum/skins/default/templates/users_questions.html2
-rw-r--r--forum/sql_scripts/091111_upgrade_evgeny.sql (renamed from sql_scripts/091111_upgrade_evgeny.sql)0
-rw-r--r--forum/sql_scripts/091208_upgrade_evgeny.sql (renamed from sql_scripts/091208_upgrade_evgeny.sql)0
-rw-r--r--forum/sql_scripts/091208_upgrade_evgeny_1.sql (renamed from sql_scripts/091208_upgrade_evgeny_1.sql)0
-rw-r--r--forum/sql_scripts/100108_upgrade_ef.sql (renamed from sql_scripts/100108_upgrade_ef.sql)0
-rw-r--r--forum/sql_scripts/badges.sql (renamed from sql_scripts/badges.sql)0
-rw-r--r--forum/sql_scripts/cnprog.xml (renamed from sql_scripts/cnprog.xml)0
-rw-r--r--forum/sql_scripts/cnprog_new_install.sql (renamed from sql_scripts/cnprog_new_install.sql)0
-rw-r--r--forum/sql_scripts/cnprog_new_install_2009_02_28.sql (renamed from sql_scripts/cnprog_new_install_2009_02_28.sql)0
-rw-r--r--forum/sql_scripts/cnprog_new_install_2009_03_31.sql (renamed from sql_scripts/cnprog_new_install_2009_03_31.sql)0
-rw-r--r--forum/sql_scripts/cnprog_new_install_2009_04_07.sql (renamed from sql_scripts/cnprog_new_install_2009_04_07.sql)0
-rw-r--r--forum/sql_scripts/cnprog_new_install_2009_04_09.sql (renamed from sql_scripts/cnprog_new_install_2009_04_09.sql)0
-rw-r--r--forum/sql_scripts/drop-all-tables.sh (renamed from sql_scripts/drop-all-tables.sh)0
-rw-r--r--forum/sql_scripts/drop-auth.sql (renamed from sql_scripts/drop-auth.sql)0
-rw-r--r--forum/sql_scripts/pg_fts_install.sql (renamed from sql_scripts/pg_fts_install.sql)0
-rw-r--r--forum/sql_scripts/update_2009_01_13_001.sql (renamed from sql_scripts/update_2009_01_13_001.sql)0
-rw-r--r--forum/sql_scripts/update_2009_01_13_002.sql (renamed from sql_scripts/update_2009_01_13_002.sql)0
-rw-r--r--forum/sql_scripts/update_2009_01_18_001.sql (renamed from sql_scripts/update_2009_01_18_001.sql)0
-rw-r--r--forum/sql_scripts/update_2009_01_24.sql (renamed from sql_scripts/update_2009_01_24.sql)0
-rw-r--r--forum/sql_scripts/update_2009_01_25_001.sql (renamed from sql_scripts/update_2009_01_25_001.sql)0
-rw-r--r--forum/sql_scripts/update_2009_02_26_001.sql (renamed from sql_scripts/update_2009_02_26_001.sql)0
-rw-r--r--forum/sql_scripts/update_2009_04_10_001.sql (renamed from sql_scripts/update_2009_04_10_001.sql)0
-rw-r--r--forum/sql_scripts/update_2009_07_05_EF.sql (renamed from sql_scripts/update_2009_07_05_EF.sql)0
-rw-r--r--forum/sql_scripts/update_2009_12_24_001.sql (renamed from sql_scripts/update_2009_12_24_001.sql)0
-rw-r--r--forum/sql_scripts/update_2009_12_27_001.sql (renamed from sql_scripts/update_2009_12_27_001.sql)0
-rw-r--r--forum/sql_scripts/update_2009_12_27_002.sql (renamed from sql_scripts/update_2009_12_27_002.sql)0
-rwxr-xr-xforum/sql_scripts/update_2010_01_23.sql (renamed from sql_scripts/update_2010_01_23.sql)0
-rw-r--r--forum/sql_scripts/update_2010_02_22.sql (renamed from sql_scripts/update_2010_02_22.sql)0
-rwxr-xr-xforum/templatetags/extra_tags.py77
-rwxr-xr-xforum/utils/decorators.py1
-rw-r--r--forum/views/readers.py351
-rwxr-xr-xforum/views/users.py15
-rwxr-xr-xforum/views/writers.py10
-rw-r--r--[-rwxr-xr-x]forum_modules/pgfulltext/DISABLED0
-rw-r--r--[-rwxr-xr-x]forum_modules/pgfulltext/__init__.py0
-rw-r--r--[-rwxr-xr-x]forum_modules/pgfulltext/handlers.py0
-rw-r--r--[-rwxr-xr-x]forum_modules/pgfulltext/management.py0
-rw-r--r--[-rwxr-xr-x]forum_modules/pgfulltext/pg_fts_install.sql0
-rw-r--r--[-rwxr-xr-x]forum_modules/sphinxfulltext/DISABLED0
-rw-r--r--[-rwxr-xr-x]forum_modules/sphinxfulltext/__init__.py0
-rw-r--r--[-rwxr-xr-x]forum_modules/sphinxfulltext/dependencies.py0
-rw-r--r--[-rwxr-xr-x]forum_modules/sphinxfulltext/handlers.py0
-rw-r--r--[-rwxr-xr-x]forum_modules/sphinxfulltext/models.py0
-rw-r--r--[-rwxr-xr-x]forum_modules/sphinxfulltext/settings.py0
-rw-r--r--locale/en/LC_MESSAGES/django.mobin27146 -> 27175 bytes
-rw-r--r--locale/en/LC_MESSAGES/django.po2
-rw-r--r--locale/ru/LC_MESSAGES/django.mobin0 -> 674 bytes
-rw-r--r--locale/ru/LC_MESSAGES/django.po3600
-rw-r--r--settings.py4
120 files changed, 6816 insertions, 513 deletions
diff --git a/README b/README
index 62064c76..56da61c5 100644
--- a/README
+++ b/README
@@ -2,6 +2,8 @@ This is Askbot project - open source Q&A system
Demo site is http://askbot.org/meta
+All documentation is in the directory forum/documentation
+
askbot-devel repository is open to anyone who wants to help develop Askbot - just drop us a note
Askbot is based on code of CNPROG, originally created by Mike Chen and Sailing Cai and some code written for OSQA
diff --git a/django_authopenid/views.py b/django_authopenid/views.py
index 3c794a0d..4f7d3efa 100755
--- a/django_authopenid/views.py
+++ b/django_authopenid/views.py
@@ -71,6 +71,7 @@ from forum.utils.forms import get_next_url
EXTERNAL_LOGIN_APP = settings.LOAD_EXTERNAL_LOGIN_APP()
+#todo: decouple from forum
def login(request,user):
from django.contrib.auth import login as _login
from forum.models import user_logged_in #custom signal
@@ -80,14 +81,27 @@ def login(request,user):
#1) get old session key
session_key = request.session.session_key
- #2) login and get new session key
+ #2) get old search state
+ search_state = None
+ if 'search_state' in request.session:
+ search_state = request.session['search_state']
+
+ #3) login and get new session key
_login(request,user)
- #3) send signal with old session key as argument
+ #4) transfer search_state to new session if found
+ if search_state:
+ search_state.set_logged_in()
+ request.session['search_state'] = search_state
+ #5) send signal with old session key as argument
logging.debug('logged in user %s with session key %s' % (user.username, session_key))
user_logged_in.send(user=user,session_key=session_key,sender=None)
+#todo: uncouple this from forum
def logout(request):
from django.contrib.auth import logout as _logout#for login I've added wrapper below - called login
+ if 'search_state' in request.session:
+ request.session['search_state'].set_logged_out()
+ request.session.modified = True
_logout(request)
if settings.USE_EXTERNAL_LEGACY_LOGIN == True:
EXTERNAL_LOGIN_APP.api.logout(request)
diff --git a/LICENSE b/forum/LICENSE
index 803781c5..803781c5 100644
--- a/LICENSE
+++ b/forum/LICENSE
diff --git a/forum/const.py b/forum/const.py
index 4c107572..bc9a7a8f 100755
--- a/forum/const.py
+++ b/forum/const.py
@@ -32,6 +32,46 @@ TYPE_REPUTATION = (
(-8, 'lose_by_upvote_canceled'),
)
+#do not translate these!!!
+POST_SORT_METHODS = (
+ ('latest', _('newest')),
+ ('oldest', _('oldest')),
+ ('active', _('active')),
+ ('inactive', _('inactive')),
+ ('hottest', _('hottest')),
+ ('coldest', _('coldest')),
+ ('mostvoted', _('most voted')),
+ ('leastvoted', _('least voted')),
+ ('relevant', _('relevance')),
+ )
+#todo: add assertion here that all sort methods are unique
+#because they are keys to the hash used in implementations of Q.run_advanced_search
+
+DEFAULT_POST_SORT_METHOD = 'active'
+POST_SCOPE_LIST = (
+ ('all', _('all')),
+ ('unanswered', _('unanswered')),
+ ('favorite', _('favorite')),
+ )
+DEFAULT_POST_SCOPE = 'all'
+DEFAULT_QUESTIONS_PAGE_SIZE = 30
+PAGE_SIZES = (10,30,50)
+
+UNANSWERED_MEANING_LIST = ('NO_ANSWERS','NO_UPVOTED_ANSWERS','NO_ACCEPTED_ANSWERS')
+UNANSWERED_MEANING = 'NO_ACCEPTED_ANSWERS'
+assert(UNANSWERED_MEANING in UNANSWERED_MEANING_LIST)
+
+#todo:
+#this probably needs to be language-specific
+#and selectable/changeable from the admin interface
+#however it will be hard to expect that people will type
+#correct regexes - plus this must be an anchored regex
+#to do full string match
+TAG_REGEX = r'^[a-z0-9\+\.\-]+$'
+TAG_SPLIT_REGEX = r'[ ,]+'
+MAX_TAG_LENGTH = 20 #default 20 chars
+MAX_TAGS_PER_POST = 5 #no more than five tags
+
TYPE_ACTIVITY_ASK_QUESTION=1
TYPE_ACTIVITY_ANSWER=2
TYPE_ACTIVITY_COMMENT_QUESTION=3
@@ -91,3 +131,4 @@ CONST = {
#how to filter questions by tags in email digests?
TAG_EMAIL_FILTER_CHOICES = (('ignored', _('exclude ignored tags')),('interesting',_('allow only selected tags')))
MAX_ALERTS_PER_EMAIL = 7
+USERS_PAGE_SIZE = 28
diff --git a/cron/README b/forum/cron/README
index d5573150..d5573150 100644
--- a/cron/README
+++ b/forum/cron/README
diff --git a/cron/multi_award_badges b/forum/cron/multi_award_badges
index 3d768772..3d768772 100755
--- a/cron/multi_award_badges
+++ b/forum/cron/multi_award_badges
diff --git a/cron/multi_award_badges_virtualenv b/forum/cron/multi_award_badges_virtualenv
index 4230fb22..4230fb22 100755
--- a/cron/multi_award_badges_virtualenv
+++ b/forum/cron/multi_award_badges_virtualenv
diff --git a/cron/once_award_badges b/forum/cron/once_award_badges
index 069656ca..069656ca 100755
--- a/cron/once_award_badges
+++ b/forum/cron/once_award_badges
diff --git a/cron/once_award_badges_virtualenv b/forum/cron/once_award_badges_virtualenv
index 0011981c..0011981c 100755
--- a/cron/once_award_badges_virtualenv
+++ b/forum/cron/once_award_badges_virtualenv
diff --git a/cron/send_email_alerts b/forum/cron/send_email_alerts
index 7581a88c..7581a88c 100644
--- a/cron/send_email_alerts
+++ b/forum/cron/send_email_alerts
diff --git a/cron/send_email_alerts_virtualenv b/forum/cron/send_email_alerts_virtualenv
index 2f1b64d0..2f1b64d0 100644
--- a/cron/send_email_alerts_virtualenv
+++ b/forum/cron/send_email_alerts_virtualenv
diff --git a/HOW_TO_DEBUG b/forum/documentation/HOW_TO_DEBUG
index fbbdb1f7..fbbdb1f7 100644
--- a/HOW_TO_DEBUG
+++ b/forum/documentation/HOW_TO_DEBUG
diff --git a/INSTALL b/forum/documentation/INSTALL
index 1eb9607c..73714566 100644
--- a/INSTALL
+++ b/forum/documentation/INSTALL
@@ -74,6 +74,10 @@ and is significantly modified. http://code.google.com/p/django-authopenid/
no need to install this library
B. INSTALLATION
+
+NOTE: If you want to upgrade software, not install from scratch -
+ take a look into forum/documentation/UPGRADE
+
-----------------------------------------------
0. Make sure you have all above python libraries installed.
@@ -108,9 +112,13 @@ DATABASE_PASSWORD
DATABASE_ENGINE
If you set these up, and your database is ready (see section 2),
-run:
+run (note that application 'forum' is under control of south migration system:
+
+python manage.py syncdb #create tables for anything not under control of migration system
+python manage.py migrate forum #run migration command - will apply all migrations in sequence
+
+Now you are ready to test your installation:
-python manage.py syncdb
python manage.py runserver `hostname -i`:8000
(choose another port number if you wish)
@@ -121,10 +129,19 @@ please post them at http://askbot.org/meta
Prepare your database by using the same database/account
configuration from above.
-e.g,
+
+If your host has database manager in the control panel - you
+can use that or you can create database by typing commands manually
+
+on MySQL the commands are:
+
create database askbot DEFAULT CHARACTER SET UTF8 COLLATE utf8_general_ci;
grant all on askbot.* to 'askbot'@'localhost';
-And then run "python manage.py syncdb" to synchronize your database.
+
+And then run :
+
+python manage.py syncdb
+python manage.py migrate
3. Running Askbot on the development server
@@ -241,10 +258,10 @@ WSGIPythonEggs /var/python/eggs #must be readable and writable by apache
This function at the moment requires Django 1.1
- edit paths in the file cron/send_email_alerts
- set up a cron job to call cron/send_email_alerts once or twice a day
+ edit paths in the file forum/cron/send_email_alerts
+ set up a cron job to call forum/cron/send_email_alerts once or twice a day
subscription sender may be tested manually in shell
- by calling cron/send_email_alerts
+ by calling forum/cron/send_email_alerts
7. Sitemap
Sitemap will be available at /<settings_local.FORUM_SCRIPT_ALIAS>sitemap.xml
@@ -258,7 +275,7 @@ https://www.google.com/webmasters/tools/
8. Miscellaneous
-There are some demo scripts under sql_scripts folder,
+There are some demo scripts under forum/sql_scripts folder,
including badges and test accounts for CNProg.com. You
don't need them to run your sample.
diff --git a/INSTALL.pip b/forum/documentation/INSTALL.pip
index 2f817ff8..2f817ff8 100644
--- a/INSTALL.pip
+++ b/forum/documentation/INSTALL.pip
diff --git a/INSTALL.webfaction b/forum/documentation/INSTALL.webfaction
index a449ffe6..a449ffe6 100644
--- a/INSTALL.webfaction
+++ b/forum/documentation/INSTALL.webfaction
diff --git a/ROADMAP.rst b/forum/documentation/ROADMAP.rst
index c79e0ae4..c79e0ae4 100644
--- a/ROADMAP.rst
+++ b/forum/documentation/ROADMAP.rst
diff --git a/TODO.rst b/forum/documentation/TODO.rst
index f202a3f7..f202a3f7 100644
--- a/TODO.rst
+++ b/forum/documentation/TODO.rst
diff --git a/forum/documentation/UPGRADE b/forum/documentation/UPGRADE
new file mode 100644
index 00000000..538b75a0
--- /dev/null
+++ b/forum/documentation/UPGRADE
@@ -0,0 +1,24 @@
+if you are upgrading this software, then
+
+* first download the newer version and write it over the old one.
+
+for the database migrations you will need to use django package called "south"
+
+Install it (if you don't have it yet) with:
+
+ easy_install South
+
+* 'south' must already be in the list of INSTALLED_APPS
+ otherwise you must have downloaded wrong version of Askbot
+
+if you are using south the very first time, then type:
+
+ python manage.py migrate forum 0001_initial --fake
+
+otherwise skip above step.
+
+Finally run
+
+ python manage.py migrate forum --auto
+
+then all relevant schema and data migrations will be applied
diff --git a/WISH_LIST b/forum/documentation/WISH_LIST
index 2b53662c..2b53662c 100644
--- a/WISH_LIST
+++ b/forum/documentation/WISH_LIST
diff --git a/askbot-requirements.txt b/forum/documentation/askbot-requirements.txt
index 66a37fbe..66a37fbe 100644
--- a/askbot-requirements.txt
+++ b/forum/documentation/askbot-requirements.txt
diff --git a/forum/forms.py b/forum/forms.py
index e16db2c6..4139abb8 100755
--- a/forum/forms.py
+++ b/forum/forms.py
@@ -2,8 +2,10 @@ import re
from datetime import date
from django import forms
from models import *
-from const import *
+from const import * #todo: clean out import * thing
+from forum import const
from django.utils.translation import ugettext as _
+from django.utils.translation import ungettext
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from forum.utils.forms import NextUrlField, UserNameField, SetPasswordForm
@@ -59,22 +61,34 @@ class TagNamesField(forms.CharField):
if len(data) < 1:
raise forms.ValidationError(_('tags are required'))
- split_re = re.compile(r'[ ,]+')
- list = split_re.split(data)
- list_temp = []
- if len(list) > 5:
- raise forms.ValidationError(_('please use 5 tags or less'))
- for tag in list:
- if len(tag) > 20:
- raise forms.ValidationError(_('tags must be shorter than 20 characters'))
- #take tag regex from settings
- tagname_re = re.compile(r'[a-z0-9\w._#-]+',re.UNICODE)
- if not tagname_re.match(tag):
- raise forms.ValidationError(_('please use letters, numbers, and characters \'.-_#\''))
- # only keep one same tag
- if tag not in list_temp and len(tag.strip()) > 0:
- list_temp.append(tag)
- return u' '.join(list_temp)
+ split_re = re.compile(const.TAG_SPLIT_REGEX)
+ tag_strings = split_re.split(data)
+ out_tag_list = []
+ tag_count = len(tag_strings)
+ if tag_count > const.MAX_TAGS_PER_POST:
+ msg = ungettext(
+ 'please use %(tag_count)d tag or less',#odd but have to use to pluralize
+ 'please use %(tag_count)d tags or less',
+ tag_count) % {'tag_count':tag_count}
+ raise forms.ValidationError(msg)
+ for tag in tag_strings:
+ tag_length = len(tag)
+ if tag_length > const.MAX_TAG_LENGTH:
+ #singular form is odd in english, but required for pluralization
+ #in other languages
+ msg = ungettext('each tag must be shorter than %(max_chars)d character',#odd but added for completeness
+ 'each tag must be shorter than %(max_shars)d characters',
+ tag_length) % {'max_chars':tag_length}
+ raise forms.ValidationError(msg)
+
+ #todo - this needs to come from settings
+ tagname_re = re.compile(const.TAG_REGEX, re.UNICODE)
+ if not tagname_re.search(tag):
+ raise forms.ValidationError(_('use-these-chars-in-tags'))
+ #only keep unique tags
+ if tag not in out_tag_list:
+ out_tag_list.append(tag)
+ return u' '.join(out_tag_list)
class WikiField(forms.BooleanField):
def __init__(self, *args, **kwargs):
@@ -113,6 +127,77 @@ class ModerateUserForm(forms.ModelForm):
model = User
fields = ('is_approved',)
+class AdvancedSearchForm(forms.Form):
+ #nothing must be required in this form
+ #it is used by the main questions view
+ scope = forms.ChoiceField(choices=const.POST_SCOPE_LIST, required=False)
+ sort = forms.ChoiceField(choices=const.POST_SORT_METHODS, required=False)
+ query = forms.CharField(max_length=256, required=False)
+ reset_tags = forms.BooleanField(required=False)
+ reset_author = forms.BooleanField(required=False)
+ reset_query = forms.BooleanField(required=False)
+ start_over = forms.BooleanField(required=False)
+ tags = forms.CharField(max_length=256,required=False)
+ author = forms.IntegerField(required=False)
+ page_size = forms.ChoiceField(choices=const.PAGE_SIZES, required=False)
+ page = forms.IntegerField(required=False)
+
+ def clean_tags(self):
+ if 'tags' in self.cleaned_data:
+ tags_input = self.cleaned_data['tags'].strip()
+ split_re = re.compile(TAG_SPLIT_REGEX)
+ tag_strings = split_re.split(tags_input)
+ tagname_re = re.compile(const.TAG_REGEX, re.UNICODE)
+ out = set()
+ for s in tag_strings:
+ if tagname_re.search(s):
+ out.add(s)
+ if len(out) > 0:
+ self.cleaned_data['tags'] = out
+ else:
+ self.cleaned_data['tags'] = None
+ return self.cleaned_data['tags']
+
+ def clean_query(self):
+ if 'query' in self.cleaned_data:
+ q = self.cleaned_data['query'].strip()
+ if q == '':
+ q = None
+ self.cleaned_data['query'] = q
+ return self.cleaned_data['query']
+
+ def clean_page_size(self):
+ if 'page_size' in self.cleaned_data:
+ if self.cleaned_data['page_size'] == '':
+ self.cleaned_data['page_size'] = None
+ return self.cleaned_data['page_size']
+
+ def clean(self):
+ #todo rewrite
+ if self.cleaned_data['scope'] == '':
+ del self.cleaned_data['scope']
+ if self.cleaned_data['tags'] is None:
+ del self.cleaned_data['tags']
+ if self.cleaned_data['sort'] == '':
+ del self.cleaned_data['sort']
+ if self.cleaned_data['query'] == None:
+ del self.cleaned_data['query']
+ if self.cleaned_data['reset_tags'] == False:
+ del self.cleaned_data['reset_tags']
+ if self.cleaned_data['reset_author'] == False:
+ del self.cleaned_data['reset_author']
+ if self.cleaned_data['reset_query'] == False:
+ del self.cleaned_data['reset_query']
+ if self.cleaned_data['start_over'] == False:
+ del self.cleaned_data['start_over']
+ if self.cleaned_data['author'] is None:
+ del self.cleaned_data['author']
+ if self.cleaned_data['page'] is None:
+ del self.cleaned_data['page']
+ if self.cleaned_data['page_size'] is None:
+ del self.cleaned_data['page_size']
+ return self.cleaned_data
+
class NotARobotForm(forms.Form):
recaptcha = ReCaptchaField()
diff --git a/stackexchange/__init__.py b/forum/importers/__init__.py
index e69de29b..e69de29b 100644
--- a/stackexchange/__init__.py
+++ b/forum/importers/__init__.py
diff --git a/stackexchange/ANOMALIES b/forum/importers/stackexchange/ANOMALIES
index 05a7dbdb..05a7dbdb 100644
--- a/stackexchange/ANOMALIES
+++ b/forum/importers/stackexchange/ANOMALIES
diff --git a/stackexchange/README b/forum/importers/stackexchange/README
index 598a8555..598a8555 100644
--- a/stackexchange/README
+++ b/forum/importers/stackexchange/README
diff --git a/stackexchange/management/__init__.py b/forum/importers/stackexchange/__init__.py
index e69de29b..e69de29b 100644
--- a/stackexchange/management/__init__.py
+++ b/forum/importers/stackexchange/__init__.py
diff --git a/stackexchange/management/commands/__init__.py b/forum/importers/stackexchange/management/__init__.py
index e69de29b..e69de29b 100644
--- a/stackexchange/management/commands/__init__.py
+++ b/forum/importers/stackexchange/management/__init__.py
diff --git a/forum/importers/stackexchange/management/commands/__init__.py b/forum/importers/stackexchange/management/commands/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/forum/importers/stackexchange/management/commands/__init__.py
diff --git a/stackexchange/management/commands/load_stackexchange.py b/forum/importers/stackexchange/management/commands/load_stackexchange.py
index 9cfc7192..ee22e33a 100644
--- a/stackexchange/management/commands/load_stackexchange.py
+++ b/forum/importers/stackexchange/management/commands/load_stackexchange.py
@@ -4,11 +4,11 @@ from django.template.defaultfilters import slugify #todo: adopt unicode-aware sl
import os
import re
import sys
-import stackexchange.parse_models as se_parser
+import forum.importers.stackexchange.parse_models as se_parser
from xml.etree import ElementTree as et
from django.db import models
import forum.models as askbot
-import stackexchange.models as se
+import forum.importers.stackexchange.models as se
from forum.forms import EditUserEmailFeedsForm
from forum.utils.html import sanitize_html
from django.conf import settings
diff --git a/stackexchange/models.py b/forum/importers/stackexchange/models.py
index a30a9859..a30a9859 100644
--- a/stackexchange/models.py
+++ b/forum/importers/stackexchange/models.py
diff --git a/stackexchange/parse_models.py b/forum/importers/stackexchange/parse_models.py
index 64796e57..64796e57 100644
--- a/stackexchange/parse_models.py
+++ b/forum/importers/stackexchange/parse_models.py
diff --git a/forum/middleware/view_log.py b/forum/middleware/view_log.py
new file mode 100644
index 00000000..bf0b9fbb
--- /dev/null
+++ b/forum/middleware/view_log.py
@@ -0,0 +1,74 @@
+import logging
+from django.conf import settings
+from forum.views.readers import questions as questions_view
+from forum.views.commands import vote
+from django.views.static import serve
+from forum.views.writers import delete_comment, question_comments, answer_comments
+from forum.views.readers import question, question_revisions, answer_revisions
+
+#todo: the list is getting bigger and bigger - maybe there is a better way to
+#trigger reset of sarch state?
+IGNORED_VIEWS = (serve, vote, delete_comment,
+ question_comments, answer_comments,
+ question_revisions, answer_revisions)
+
+class ViewLog(object):
+ """must be modified only in this middlware
+ however, can be read anywhere else
+ """
+ def __init__(self):
+ self.views = []
+ self.depth = 3 #todo maybe move this to const.py
+ def set_current(self, view_name):
+ thi
+
+ def get_previous(self, num):
+ if num > self.depth - 1:
+ raise Exception("view log depth exceeded")
+ elif num < 0:
+ raise Exception("num must be positive");
+ elif num <= len(self.views) - 1:
+ return self.views[num]
+ else:
+ return None
+
+ def set_current(self, view_name):
+ self.views.insert(0, view_name)
+ if len(self.views) > self.depth:
+ self.views.pop()
+
+ def __str__(self):
+ return str(self.views) + ' depth=%d' % self.depth
+
+class ViewLogMiddleware(object):
+ def process_view(self, request, view_func, view_args, view_kwargs):
+ if view_func == questions_view:
+ view_str = 'questions'
+ elif view_func in IGNORED_VIEWS:
+ return
+ else:
+ view_str = view_func.__name__
+ if view_str == 'wrap':
+ return
+
+ if settings.DEBUG == True:
+ #todo: dependency!
+ from debug_toolbar.views import debug_media as debug_media_view
+ if view_func == debug_media_view:
+ return
+ else:
+ view_str = view_func.__name__
+
+ if request.user.is_authenticated():
+ user_name = request.user.username
+ else:
+ user_name = request.META['REMOTE_ADDR']
+ logging.debug('user %s, view %s' % (request.user.username, view_str))
+
+ if 'view_log' in request.session:
+ view_log = request.session['view_log']
+ else:
+ view_log = ViewLog()
+
+ view_log.set_current(view_str)
+ request.session['view_log'] = view_log
diff --git a/forum/migrations/0001_initial.py b/forum/migrations/0001_initial.py
new file mode 100644
index 00000000..e6350446
--- /dev/null
+++ b/forum/migrations/0001_initial.py
@@ -0,0 +1,780 @@
+# 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 model 'Vote'
+ db.create_table(u'vote', (
+ ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
+ ('voted_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='votes', to=orm['auth.User'])),
+ ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
+ ('vote', self.gf('django.db.models.fields.SmallIntegerField')()),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('forum', ['Vote'])
+
+ # Adding unique constraint on 'Vote', fields ['content_type', 'object_id', 'user']
+ db.create_unique(u'vote', ['content_type_id', 'object_id', 'user_id'])
+
+ # Adding model 'FlaggedItem'
+ db.create_table(u'flagged_item', (
+ ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
+ ('flagged_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='flaggeditems', to=orm['auth.User'])),
+ ))
+ db.send_create_signal('forum', ['FlaggedItem'])
+
+ # Adding unique constraint on 'FlaggedItem', fields ['content_type', 'object_id', 'user']
+ db.create_unique(u'flagged_item', ['content_type_id', 'object_id', 'user_id'])
+
+ # Adding model 'Comment'
+ db.create_table(u'comment', (
+ ('comment', self.gf('django.db.models.fields.CharField')(max_length=300)),
+ ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='comments', to=orm['auth.User'])),
+ ))
+ db.send_create_signal('forum', ['Comment'])
+
+ # Adding model 'Tag'
+ db.create_table(u'tag', (
+ ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)),
+ ('deleted', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('created_by', self.gf('django.db.models.fields.related.ForeignKey')(related_name='created_tags', to=orm['auth.User'])),
+ ('deleted_by', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='deleted_tags', null=True, to=orm['auth.User'])),
+ ('used_count', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ('deleted_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('forum', ['Tag'])
+
+ # Adding model 'MarkedTag'
+ db.create_table('forum_markedtag', (
+ ('reason', self.gf('django.db.models.fields.CharField')(max_length=16)),
+ ('tag', self.gf('django.db.models.fields.related.ForeignKey')(related_name='user_selections', to=orm['forum.Tag'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='tag_selections', to=orm['auth.User'])),
+ ))
+ db.send_create_signal('forum', ['MarkedTag'])
+
+ # Adding model 'Question'
+ db.create_table(u'question', (
+ ('wiki', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('vote_up_count', self.gf('django.db.models.fields.IntegerField')(default=0)),
+ ('answer_accepted', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('offensive_flag_count', self.gf('django.db.models.fields.SmallIntegerField')(default=0)),
+ ('closed_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('deleted_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('last_activity_by', self.gf('django.db.models.fields.related.ForeignKey')(related_name='last_active_in_questions', to=orm['auth.User'])),
+ ('view_count', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ('locked_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('score', self.gf('django.db.models.fields.IntegerField')(default=0)),
+ ('author', self.gf('django.db.models.fields.related.ForeignKey')(related_name='questions', to=orm['auth.User'])),
+ ('comment_count', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ('html', self.gf('django.db.models.fields.TextField')()),
+ ('vote_down_count', self.gf('django.db.models.fields.IntegerField')(default=0)),
+ ('closed', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('last_edited_by', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='last_edited_questions', null=True, to=orm['auth.User'])),
+ ('favourite_count', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ('deleted', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('summary', self.gf('django.db.models.fields.CharField')(max_length=180)),
+ ('answer_count', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ('last_activity_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('closed_by', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='closed_questions', null=True, to=orm['auth.User'])),
+ ('close_reason', self.gf('django.db.models.fields.SmallIntegerField')(null=True, blank=True)),
+ ('locked', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('tagnames', self.gf('django.db.models.fields.CharField')(max_length=125)),
+ ('locked_by', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='locked_questions', null=True, to=orm['auth.User'])),
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('deleted_by', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='deleted_questions', null=True, to=orm['auth.User'])),
+ ('wikified_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=300)),
+ ('last_edited_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ))
+ db.send_create_signal('forum', ['Question'])
+
+ # Adding M2M table for field followed_by on 'Question'
+ db.create_table(u'question_followed_by', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('question', models.ForeignKey(orm['forum.question'], null=False)),
+ ('user', models.ForeignKey(orm['auth.user'], null=False))
+ ))
+ db.create_unique(u'question_followed_by', ['question_id', 'user_id'])
+
+ # Adding M2M table for field tags on 'Question'
+ db.create_table(u'question_tags', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('question', models.ForeignKey(orm['forum.question'], null=False)),
+ ('tag', models.ForeignKey(orm['forum.tag'], null=False))
+ ))
+ db.create_unique(u'question_tags', ['question_id', 'tag_id'])
+
+ # Adding model 'QuestionView'
+ db.create_table('forum_questionview', (
+ ('when', self.gf('django.db.models.fields.DateTimeField')()),
+ ('who', self.gf('django.db.models.fields.related.ForeignKey')(related_name='question_views', to=orm['auth.User'])),
+ ('question', self.gf('django.db.models.fields.related.ForeignKey')(related_name='viewed', to=orm['forum.Question'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('forum', ['QuestionView'])
+
+ # Adding model 'FavoriteQuestion'
+ db.create_table(u'favorite_question', (
+ ('question', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['forum.Question'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='user_favorite_questions', to=orm['auth.User'])),
+ ))
+ db.send_create_signal('forum', ['FavoriteQuestion'])
+
+ # Adding model 'QuestionRevision'
+ db.create_table(u'question_revision', (
+ ('author', self.gf('django.db.models.fields.related.ForeignKey')(related_name='questionrevisions', to=orm['auth.User'])),
+ ('tagnames', self.gf('django.db.models.fields.CharField')(max_length=125)),
+ ('text', self.gf('django.db.models.fields.TextField')()),
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=300)),
+ ('question', self.gf('django.db.models.fields.related.ForeignKey')(related_name='revisions', to=orm['forum.Question'])),
+ ('revised_at', self.gf('django.db.models.fields.DateTimeField')()),
+ ('summary', self.gf('django.db.models.fields.CharField')(max_length=300, blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('revision', self.gf('django.db.models.fields.PositiveIntegerField')()),
+ ))
+ db.send_create_signal('forum', ['QuestionRevision'])
+
+ # Adding model 'AnonymousQuestion'
+ db.create_table('forum_anonymousquestion', (
+ ('wiki', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('ip_addr', self.gf('django.db.models.fields.IPAddressField')(max_length=15)),
+ ('author', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True)),
+ ('tagnames', self.gf('django.db.models.fields.CharField')(max_length=125)),
+ ('text', self.gf('django.db.models.fields.TextField')()),
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=300)),
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('summary', self.gf('django.db.models.fields.CharField')(max_length=180)),
+ ('session_key', self.gf('django.db.models.fields.CharField')(max_length=40)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('forum', ['AnonymousQuestion'])
+
+ # Adding model 'Answer'
+ db.create_table(u'answer', (
+ ('wiki', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('vote_up_count', self.gf('django.db.models.fields.IntegerField')(default=0)),
+ ('offensive_flag_count', self.gf('django.db.models.fields.SmallIntegerField')(default=0)),
+ ('deleted_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('locked_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('score', self.gf('django.db.models.fields.IntegerField')(default=0)),
+ ('author', self.gf('django.db.models.fields.related.ForeignKey')(related_name='answers', to=orm['auth.User'])),
+ ('question', self.gf('django.db.models.fields.related.ForeignKey')(related_name='answers', to=orm['forum.Question'])),
+ ('comment_count', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ('html', self.gf('django.db.models.fields.TextField')()),
+ ('vote_down_count', self.gf('django.db.models.fields.IntegerField')(default=0)),
+ ('last_edited_by', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='last_edited_answers', null=True, to=orm['auth.User'])),
+ ('accepted_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('deleted', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('accepted', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('locked', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('locked_by', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='locked_answers', null=True, to=orm['auth.User'])),
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('deleted_by', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='deleted_answers', null=True, to=orm['auth.User'])),
+ ('wikified_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ('last_edited_at', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
+ ))
+ db.send_create_signal('forum', ['Answer'])
+
+ # Adding model 'AnswerRevision'
+ db.create_table(u'answer_revision', (
+ ('author', self.gf('django.db.models.fields.related.ForeignKey')(related_name='answerrevisions', to=orm['auth.User'])),
+ ('text', self.gf('django.db.models.fields.TextField')()),
+ ('revised_at', self.gf('django.db.models.fields.DateTimeField')()),
+ ('summary', self.gf('django.db.models.fields.CharField')(max_length=300, blank=True)),
+ ('answer', self.gf('django.db.models.fields.related.ForeignKey')(related_name='revisions', to=orm['forum.Answer'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('revision', self.gf('django.db.models.fields.PositiveIntegerField')()),
+ ))
+ db.send_create_signal('forum', ['AnswerRevision'])
+
+ # Adding model 'AnonymousAnswer'
+ db.create_table('forum_anonymousanswer', (
+ ('wiki', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('ip_addr', self.gf('django.db.models.fields.IPAddressField')(max_length=15)),
+ ('author', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True)),
+ ('text', self.gf('django.db.models.fields.TextField')()),
+ ('question', self.gf('django.db.models.fields.related.ForeignKey')(related_name='anonymous_answers', to=orm['forum.Question'])),
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('summary', self.gf('django.db.models.fields.CharField')(max_length=180)),
+ ('session_key', self.gf('django.db.models.fields.CharField')(max_length=40)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('forum', ['AnonymousAnswer'])
+
+ # Adding model 'Activity'
+ db.create_table(u'activity', (
+ ('is_auditted', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
+ ('active_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('activity_type', self.gf('django.db.models.fields.SmallIntegerField')()),
+ ))
+ db.send_create_signal('forum', ['Activity'])
+
+ # Adding model 'EmailFeedSetting'
+ db.create_table('forum_emailfeedsetting', (
+ ('reported_at', self.gf('django.db.models.fields.DateTimeField')(null=True)),
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
+ ('subscriber', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ('feed_type', self.gf('django.db.models.fields.CharField')(max_length=16)),
+ ('frequency', self.gf('django.db.models.fields.CharField')(default='n', max_length=8)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('forum', ['EmailFeedSetting'])
+
+ # Adding model 'ValidationHash'
+ db.create_table('forum_validationhash', (
+ ('hash_code', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)),
+ ('seed', self.gf('django.db.models.fields.CharField')(max_length=12)),
+ ('expiration', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime(2010, 4, 25, 13, 14, 41, 581000))),
+ ('type', self.gf('django.db.models.fields.CharField')(max_length=12)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ))
+ db.send_create_signal('forum', ['ValidationHash'])
+
+ # Adding unique constraint on 'ValidationHash', fields ['user', 'type']
+ db.create_unique('forum_validationhash', ['user_id', 'type'])
+
+ # Adding model 'AuthKeyUserAssociation'
+ db.create_table('forum_authkeyuserassociation', (
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='auth_keys', to=orm['auth.User'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('key', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)),
+ ('provider', self.gf('django.db.models.fields.CharField')(max_length=64)),
+ ))
+ db.send_create_signal('forum', ['AuthKeyUserAssociation'])
+
+ # Adding model 'Badge'
+ db.create_table(u'badge', (
+ ('multiple', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('description', self.gf('django.db.models.fields.CharField')(max_length=300)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('awarded_count', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ('type', self.gf('django.db.models.fields.SmallIntegerField')()),
+ ('slug', self.gf('django.db.models.fields.SlugField')(db_index=True, max_length=50, blank=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=50)),
+ ))
+ db.send_create_signal('forum', ['Badge'])
+
+ # Adding unique constraint on 'Badge', fields ['name', 'type']
+ db.create_unique(u'badge', ['name', 'type'])
+
+ # Adding model 'Award'
+ db.create_table(u'award', (
+ ('awarded_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('notified', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
+ ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='award_user', to=orm['auth.User'])),
+ ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
+ ('badge', self.gf('django.db.models.fields.related.ForeignKey')(related_name='award_badge', to=orm['forum.Badge'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('forum', ['Award'])
+
+ # Adding model 'Repute'
+ db.create_table(u'repute', (
+ ('positive', self.gf('django.db.models.fields.SmallIntegerField')(default=0)),
+ ('question', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['forum.Question'])),
+ ('negative', self.gf('django.db.models.fields.SmallIntegerField')(default=0)),
+ ('reputation_type', self.gf('django.db.models.fields.SmallIntegerField')()),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ('reputed_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('reputation', self.gf('django.db.models.fields.IntegerField')(default=1)),
+ ))
+ db.send_create_signal('forum', ['Repute'])
+
+ # Adding model 'Book'
+ db.create_table(u'book', (
+ ('publication', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('short_name', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('author', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('cover_img', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('price', self.gf('django.db.models.fields.DecimalField')(max_digits=6, decimal_places=2)),
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')()),
+ ('pages', self.gf('django.db.models.fields.SmallIntegerField')()),
+ ('tagnames', self.gf('django.db.models.fields.CharField')(max_length=125)),
+ ('published_at', self.gf('django.db.models.fields.DateTimeField')()),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('last_edited_at', self.gf('django.db.models.fields.DateTimeField')()),
+ ))
+ db.send_create_signal('forum', ['Book'])
+
+ # Adding M2M table for field questions on 'Book'
+ db.create_table('book_question', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('book', models.ForeignKey(orm['forum.book'], null=False)),
+ ('question', models.ForeignKey(orm['forum.question'], null=False))
+ ))
+ db.create_unique('book_question', ['book_id', 'question_id'])
+
+ # Adding model 'BookAuthorInfo'
+ db.create_table(u'book_author_info', (
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')()),
+ ('book', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['forum.Book'])),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ('blog_url', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('last_edited_at', self.gf('django.db.models.fields.DateTimeField')()),
+ ))
+ db.send_create_signal('forum', ['BookAuthorInfo'])
+
+ # Adding model 'BookAuthorRss'
+ db.create_table(u'book_author_rss', (
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('url', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('added_at', self.gf('django.db.models.fields.DateTimeField')()),
+ ('book', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['forum.Book'])),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ('rss_created_at', self.gf('django.db.models.fields.DateTimeField')()),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('forum', ['BookAuthorRss'])
+
+
+ def backwards(self, orm):
+
+ # Deleting model 'Vote'
+ db.delete_table(u'vote')
+
+ # Removing unique constraint on 'Vote', fields ['content_type', 'object_id', 'user']
+ db.delete_unique(u'vote', ['content_type_id', 'object_id', 'user_id'])
+
+ # Deleting model 'FlaggedItem'
+ db.delete_table(u'flagged_item')
+
+ # Removing unique constraint on 'FlaggedItem', fields ['content_type', 'object_id', 'user']
+ db.delete_unique(u'flagged_item', ['content_type_id', 'object_id', 'user_id'])
+
+ # Deleting model 'Comment'
+ db.delete_table(u'comment')
+
+ # Deleting model 'Tag'
+ db.delete_table(u'tag')
+
+ # Deleting model 'MarkedTag'
+ db.delete_table('forum_markedtag')
+
+ # Deleting model 'Question'
+ db.delete_table(u'question')
+
+ # Removing M2M table for field followed_by on 'Question'
+ db.delete_table('question_followed_by')
+
+ # Removing M2M table for field tags on 'Question'
+ db.delete_table('question_tags')
+
+ # Deleting model 'QuestionView'
+ db.delete_table('forum_questionview')
+
+ # Deleting model 'FavoriteQuestion'
+ db.delete_table(u'favorite_question')
+
+ # Deleting model 'QuestionRevision'
+ db.delete_table(u'question_revision')
+
+ # Deleting model 'AnonymousQuestion'
+ db.delete_table('forum_anonymousquestion')
+
+ # Deleting model 'Answer'
+ db.delete_table(u'answer')
+
+ # Deleting model 'AnswerRevision'
+ db.delete_table(u'answer_revision')
+
+ # Deleting model 'AnonymousAnswer'
+ db.delete_table('forum_anonymousanswer')
+
+ # Deleting model 'Activity'
+ db.delete_table(u'activity')
+
+ # Deleting model 'EmailFeedSetting'
+ db.delete_table('forum_emailfeedsetting')
+
+ # Deleting model 'ValidationHash'
+ db.delete_table('forum_validationhash')
+
+ # Removing unique constraint on 'ValidationHash', fields ['user', 'type']
+ db.delete_unique('forum_validationhash', ['user_id', 'type'])
+
+ # Deleting model 'AuthKeyUserAssociation'
+ db.delete_table('forum_authkeyuserassociation')
+
+ # Deleting model 'Badge'
+ db.delete_table(u'badge')
+
+ # Removing unique constraint on 'Badge', fields ['name', 'type']
+ db.delete_unique(u'badge', ['name', 'type'])
+
+ # Deleting model 'Award'
+ db.delete_table(u'award')
+
+ # Deleting model 'Repute'
+ db.delete_table(u'repute')
+
+ # Deleting model 'Book'
+ db.delete_table(u'book')
+
+ # Removing M2M table for field questions on 'Book'
+ db.delete_table('book_question')
+
+ # Deleting model 'BookAuthorInfo'
+ db.delete_table(u'book_author_info')
+
+ # Deleting model 'BookAuthorRss'
+ db.delete_table(u'book_author_rss')
+
+
+ models = {
+ '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']", 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'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'}),
+ 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
+ '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']", 'blank': 'True'}),
+ 'hide_ignored_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+ 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ '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'}),
+ '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'}),
+ 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'tag_filter_setting': ('django.db.models.fields.CharField', [], {'default': "'ignored'", 'max_length': '16'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+ 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'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'})
+ },
+ 'forum.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', 'blank': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Question']"}),
+ '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', 'blank': 'True'})
+ },
+ 'forum.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'}),
+ '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', 'blank': 'True'})
+ },
+ 'forum.answer': {
+ 'Meta': {'object_name': 'Answer', 'db_table': "u'answer'"},
+ 'accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': "orm['auth.User']"}),
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'html': ('django.db.models.fields.TextField', [], {}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ '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_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': "orm['forum.Question']"}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ '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', 'blank': 'True'}),
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'forum.answerrevision': {
+ 'Meta': {'object_name': 'AnswerRevision', 'db_table': "u'answer_revision'"},
+ 'answer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Answer']"}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answerrevisions'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'revised_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {})
+ },
+ 'forum.authkeyuserassociation': {
+ 'Meta': {'object_name': 'AuthKeyUserAssociation'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'provider': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_keys'", 'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Badge']"}),
+ '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', 'blank': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_user'", 'to': "orm['auth.User']"})
+ },
+ 'forum.badge': {
+ 'Meta': {'unique_together': "(('name', 'type'),)", 'object_name': 'Badge', 'db_table': "u'badge'"},
+ 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'through': "'Award'", 'to': "orm['auth.User']"}),
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '50', 'blank': 'True'}),
+ 'type': ('django.db.models.fields.SmallIntegerField', [], {})
+ },
+ 'forum.book': {
+ 'Meta': {'object_name': 'Book', 'db_table': "u'book'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'author': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'cover_img': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'pages': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'price': ('django.db.models.fields.DecimalField', [], {'max_digits': '6', 'decimal_places': '2'}),
+ 'publication': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'published_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'questions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'book'", 'db_table': "'book_question'", 'to': "orm['forum.Question']"}),
+ 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.bookauthorinfo': {
+ 'Meta': {'object_name': 'BookAuthorInfo', 'db_table': "u'book_author_info'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'blog_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Book']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.bookauthorrss': {
+ 'Meta': {'object_name': 'BookAuthorRss', 'db_table': "u'book_author_rss'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Book']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'rss_created_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.comment': {
+ 'Meta': {'object_name': 'Comment', 'db_table': "u'comment'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'comment': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['auth.User']"})
+ },
+ 'forum.emailfeedsetting': {
+ 'Meta': {'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', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.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'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['auth.User']"})
+ },
+ 'forum.flaggeditem': {
+ 'Meta': {'unique_together': "(('content_type', 'object_id', 'user'),)", 'object_name': 'FlaggedItem', 'db_table': "u'flagged_item'"},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'flagged_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", 'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Tag']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['auth.User']"})
+ },
+ 'forum.question': {
+ 'Meta': {'object_name': 'Question', 'db_table': "u'question'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'answer_accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'questions'", 'to': "orm['auth.User']"}),
+ 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'closed_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'favorite_questions'", 'through': "'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_questions'", 'to': "orm['auth.User']"}),
+ 'html': ('django.db.models.fields.TextField', [], {}),
+ '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': "'last_active_in_questions'", 'to': "orm['auth.User']"}),
+ '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_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'questions'", 'to': "orm['forum.Tag']"}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'view_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ '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', 'blank': 'True'}),
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'forum.questionrevision': {
+ 'Meta': {'object_name': 'QuestionRevision', 'db_table': "u'question_revision'"},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'questionrevisions'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Question']"}),
+ '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', [], {'max_length': '125'}),
+ 'text': ('django.db.models.fields.TextField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'})
+ },
+ 'forum.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['forum.Question']"}),
+ 'when': ('django.db.models.fields.DateTimeField', [], {}),
+ 'who': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'question_views'", 'to': "orm['auth.User']"})
+ },
+ 'forum.repute': {
+ 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"},
+ '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['forum.Question']"}),
+ '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']"})
+ },
+ 'forum.tag': {
+ 'Meta': {'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', 'blank': '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_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'}),
+ 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
+ },
+ 'forum.validationhash': {
+ 'Meta': {'unique_together': "(('user', 'type'),)", 'object_name': 'ValidationHash'},
+ 'expiration': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 25, 13, 14, 41, 714642)'}),
+ 'hash_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'seed': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.vote': {
+ 'Meta': {'unique_together': "(('content_type', 'object_id', 'user'),)", 'object_name': 'Vote', 'db_table': "u'vote'"},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ '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'})
+ }
+ }
+
+ complete_apps = ['forum']
diff --git a/forum/migrations/0002_auto__add_field_answer_text__chg_field_answer_html__add_field_question.py b/forum/migrations/0002_auto__add_field_answer_text__chg_field_answer_html__add_field_question.py
new file mode 100644
index 00000000..d703c161
--- /dev/null
+++ b/forum/migrations/0002_auto__add_field_answer_text__chg_field_answer_html__add_field_question.py
@@ -0,0 +1,368 @@
+# 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 'Answer.text'
+ db.add_column(u'answer', 'text', self.gf('django.db.models.fields.TextField')(null=True), keep_default=False)
+
+ # Changing field 'Answer.html'
+ db.alter_column(u'answer', 'html', self.gf('django.db.models.fields.TextField')(null=True))
+
+ # Adding field 'Question.text'
+ db.add_column(u'question', 'text', self.gf('django.db.models.fields.TextField')(null=True), keep_default=False)
+
+ # Changing field 'Question.html'
+ db.alter_column(u'question', 'html', self.gf('django.db.models.fields.TextField')(null=True))
+
+
+ def backwards(self, orm):
+
+ # Deleting field 'Answer.text'
+ db.delete_column(u'answer', 'text')
+
+ # Changing field 'Answer.html'
+ db.alter_column(u'answer', 'html', self.gf('django.db.models.fields.TextField')())
+
+ # Deleting field 'Question.text'
+ db.delete_column(u'question', 'text')
+
+ # Changing field 'Question.html'
+ db.alter_column(u'question', 'html', self.gf('django.db.models.fields.TextField')())
+
+
+ models = {
+ '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']", 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'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'}),
+ 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
+ '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']", 'blank': 'True'}),
+ 'hide_ignored_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+ 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ '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'}),
+ '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'}),
+ 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'tag_filter_setting': ('django.db.models.fields.CharField', [], {'default': "'ignored'", 'max_length': '16'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+ 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'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'})
+ },
+ 'forum.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', 'blank': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Question']"}),
+ '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', 'blank': 'True'})
+ },
+ 'forum.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'}),
+ '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', 'blank': 'True'})
+ },
+ 'forum.answer': {
+ 'Meta': {'object_name': 'Answer', 'db_table': "u'answer'"},
+ 'accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': "orm['auth.User']"}),
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'html': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ '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_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': "orm['forum.Question']"}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ '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', 'blank': 'True'}),
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'forum.answerrevision': {
+ 'Meta': {'object_name': 'AnswerRevision', 'db_table': "u'answer_revision'"},
+ 'answer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Answer']"}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answerrevisions'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'revised_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {})
+ },
+ 'forum.authkeyuserassociation': {
+ 'Meta': {'object_name': 'AuthKeyUserAssociation'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'provider': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_keys'", 'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Badge']"}),
+ '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', 'blank': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_user'", 'to': "orm['auth.User']"})
+ },
+ 'forum.badge': {
+ 'Meta': {'unique_together': "(('name', 'type'),)", 'object_name': 'Badge', 'db_table': "u'badge'"},
+ 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'through': "'Award'", 'to': "orm['auth.User']"}),
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '50', 'blank': 'True'}),
+ 'type': ('django.db.models.fields.SmallIntegerField', [], {})
+ },
+ 'forum.book': {
+ 'Meta': {'object_name': 'Book', 'db_table': "u'book'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'author': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'cover_img': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'pages': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'price': ('django.db.models.fields.DecimalField', [], {'max_digits': '6', 'decimal_places': '2'}),
+ 'publication': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'published_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'questions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'book'", 'db_table': "'book_question'", 'to': "orm['forum.Question']"}),
+ 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.bookauthorinfo': {
+ 'Meta': {'object_name': 'BookAuthorInfo', 'db_table': "u'book_author_info'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'blog_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Book']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.bookauthorrss': {
+ 'Meta': {'object_name': 'BookAuthorRss', 'db_table': "u'book_author_rss'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Book']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'rss_created_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.comment': {
+ 'Meta': {'object_name': 'Comment', 'db_table': "u'comment'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'comment': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['auth.User']"})
+ },
+ 'forum.emailfeedsetting': {
+ 'Meta': {'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', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.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'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['auth.User']"})
+ },
+ 'forum.flaggeditem': {
+ 'Meta': {'unique_together': "(('content_type', 'object_id', 'user'),)", 'object_name': 'FlaggedItem', 'db_table': "u'flagged_item'"},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'flagged_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", 'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Tag']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['auth.User']"})
+ },
+ 'forum.question': {
+ 'Meta': {'object_name': 'Question', 'db_table': "u'question'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'answer_accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'questions'", 'to': "orm['auth.User']"}),
+ 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'closed_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'favorite_questions'", 'through': "'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_questions'", 'to': "orm['auth.User']"}),
+ 'html': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ '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': "'last_active_in_questions'", 'to': "orm['auth.User']"}),
+ '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_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'questions'", 'to': "orm['forum.Tag']"}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'view_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ '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', 'blank': 'True'}),
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'forum.questionrevision': {
+ 'Meta': {'object_name': 'QuestionRevision', 'db_table': "u'question_revision'"},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'questionrevisions'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Question']"}),
+ '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', [], {'max_length': '125'}),
+ 'text': ('django.db.models.fields.TextField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'})
+ },
+ 'forum.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['forum.Question']"}),
+ 'when': ('django.db.models.fields.DateTimeField', [], {}),
+ 'who': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'question_views'", 'to': "orm['auth.User']"})
+ },
+ 'forum.repute': {
+ 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"},
+ '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['forum.Question']"}),
+ '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']"})
+ },
+ 'forum.tag': {
+ 'Meta': {'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', 'blank': '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_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'}),
+ 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
+ },
+ 'forum.validationhash': {
+ 'Meta': {'unique_together': "(('user', 'type'),)", 'object_name': 'ValidationHash'},
+ 'expiration': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 25, 16, 21, 32, 856067)'}),
+ 'hash_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'seed': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.vote': {
+ 'Meta': {'unique_together': "(('content_type', 'object_id', 'user'),)", 'object_name': 'Vote', 'db_table': "u'vote'"},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ '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'})
+ }
+ }
+
+ complete_apps = ['forum']
diff --git a/forum/migrations/0003_copy_denorm_text_record_to_posts_for_fulltext_search.py b/forum/migrations/0003_copy_denorm_text_record_to_posts_for_fulltext_search.py
new file mode 100644
index 00000000..3e79b9d2
--- /dev/null
+++ b/forum/migrations/0003_copy_denorm_text_record_to_posts_for_fulltext_search.py
@@ -0,0 +1,354 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from forum.models import Question, Answer
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+ for q in orm.Question.objects.all():
+ r = q.revisions.all()[0] #cannot use get_latest_revision()
+ q.text = r.text
+ q.save()
+ for a in orm.Answer.objects.all():
+ r = a.revisions.all()[0]
+ a.text = r.text
+ a.save()
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+ pass#there's no need to clean data here, just delete columns
+
+ models = {
+ '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']", 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'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'}),
+ 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
+ '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']", 'blank': 'True'}),
+ 'hide_ignored_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+ 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ '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'}),
+ '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'}),
+ 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'tag_filter_setting': ('django.db.models.fields.CharField', [], {'default': "'ignored'", 'max_length': '16'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+ 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'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'})
+ },
+ 'forum.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', 'blank': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Question']"}),
+ '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', 'blank': 'True'})
+ },
+ 'forum.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'}),
+ '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', 'blank': 'True'})
+ },
+ 'forum.answer': {
+ 'Meta': {'object_name': 'Answer', 'db_table': "u'answer'"},
+ 'accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': "orm['auth.User']"}),
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'html': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ '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_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': "orm['forum.Question']"}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ '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', 'blank': 'True'}),
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'forum.answerrevision': {
+ 'Meta': {'object_name': 'AnswerRevision', 'db_table': "u'answer_revision'"},
+ 'answer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Answer']"}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answerrevisions'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'revised_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {})
+ },
+ 'forum.authkeyuserassociation': {
+ 'Meta': {'object_name': 'AuthKeyUserAssociation'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'provider': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_keys'", 'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Badge']"}),
+ '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', 'blank': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_user'", 'to': "orm['auth.User']"})
+ },
+ 'forum.badge': {
+ 'Meta': {'unique_together': "(('name', 'type'),)", 'object_name': 'Badge', 'db_table': "u'badge'"},
+ 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'through': "'Award'", 'to': "orm['auth.User']"}),
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '50', 'blank': 'True'}),
+ 'type': ('django.db.models.fields.SmallIntegerField', [], {})
+ },
+ 'forum.book': {
+ 'Meta': {'object_name': 'Book', 'db_table': "u'book'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'author': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'cover_img': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'pages': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'price': ('django.db.models.fields.DecimalField', [], {'max_digits': '6', 'decimal_places': '2'}),
+ 'publication': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'published_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'questions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'book'", 'db_table': "'book_question'", 'to': "orm['forum.Question']"}),
+ 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.bookauthorinfo': {
+ 'Meta': {'object_name': 'BookAuthorInfo', 'db_table': "u'book_author_info'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'blog_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Book']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.bookauthorrss': {
+ 'Meta': {'object_name': 'BookAuthorRss', 'db_table': "u'book_author_rss'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Book']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'rss_created_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.comment': {
+ 'Meta': {'object_name': 'Comment', 'db_table': "u'comment'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'comment': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['auth.User']"})
+ },
+ 'forum.emailfeedsetting': {
+ 'Meta': {'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', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.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'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['auth.User']"})
+ },
+ 'forum.flaggeditem': {
+ 'Meta': {'unique_together': "(('content_type', 'object_id', 'user'),)", 'object_name': 'FlaggedItem', 'db_table': "u'flagged_item'"},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'flagged_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", 'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Tag']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['auth.User']"})
+ },
+ 'forum.question': {
+ 'Meta': {'object_name': 'Question', 'db_table': "u'question'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'answer_accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'questions'", 'to': "orm['auth.User']"}),
+ 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'closed_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'favorite_questions'", 'through': "'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_questions'", 'to': "orm['auth.User']"}),
+ 'html': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ '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': "'last_active_in_questions'", 'to': "orm['auth.User']"}),
+ '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_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'questions'", 'to': "orm['forum.Tag']"}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'view_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ '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', 'blank': 'True'}),
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'forum.questionrevision': {
+ 'Meta': {'object_name': 'QuestionRevision', 'db_table': "u'question_revision'"},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'questionrevisions'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Question']"}),
+ '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', [], {'max_length': '125'}),
+ 'text': ('django.db.models.fields.TextField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'})
+ },
+ 'forum.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['forum.Question']"}),
+ 'when': ('django.db.models.fields.DateTimeField', [], {}),
+ 'who': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'question_views'", 'to': "orm['auth.User']"})
+ },
+ 'forum.repute': {
+ 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"},
+ '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['forum.Question']"}),
+ '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']"})
+ },
+ 'forum.tag': {
+ 'Meta': {'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', 'blank': '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_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'}),
+ 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
+ },
+ 'forum.validationhash': {
+ 'Meta': {'unique_together': "(('user', 'type'),)", 'object_name': 'ValidationHash'},
+ 'expiration': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 25, 16, 24, 24, 604164)'}),
+ 'hash_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'seed': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.vote': {
+ 'Meta': {'unique_together': "(('content_type', 'object_id', 'user'),)", 'object_name': 'Vote', 'db_table': "u'vote'"},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ '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'})
+ }
+ }
+
+ complete_apps = ['forum']
diff --git a/forum/migrations/0004_install_full_text_indexes_for_mysql.py b/forum/migrations/0004_install_full_text_indexes_for_mysql.py
new file mode 100644
index 00000000..0c52c442
--- /dev/null
+++ b/forum/migrations/0004_install_full_text_indexes_for_mysql.py
@@ -0,0 +1,389 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from forum.models import Question, Answer
+
+Q_INDEX_NAME = 'askbot_question_full_text_index'
+A_INDEX_NAME = 'askbot_answer_full_text_index'
+Q_TABLE_NAME = Question._meta.db_table
+A_TABLE_NAME = Answer._meta.db_table
+
+def get_create_full_text_index_sql(index_name, table_name, column_list):
+ column_sql = '(%s)' % ','.join(column_list)
+ sql = 'CREATE FULLTEXT INDEX %s on %s %s' % (index_name, table_name, column_sql)
+ return sql
+
+def get_drop_index_sql(index_name, table_name):
+ return 'ALTER TABLE %s DROP INDEX %s' % (table_name, index_name)
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ """install fulltext indices for mysql
+ will work only for MyISAM engine
+ and will probably fail otherwise
+ """
+ if db.backend_name == 'mysql':
+ #todo: extract column names by introspection
+ question_index_sql = get_create_full_text_index_sql(
+ Q_INDEX_NAME,
+ Q_TABLE_NAME,
+ ('title','text','tagnames',)
+ )
+ db.execute(question_index_sql)
+
+ answer_index_sql = get_create_full_text_index_sql(
+ A_INDEX_NAME,
+ A_TABLE_NAME,
+ ('text',)
+ )
+ db.execute(answer_index_sql)
+
+ def backwards(self, orm):
+ "code for removal of full text indices in mysql"
+ if db.backend_name == 'mysql':
+ db.execute(
+ get_drop_index_sql(
+ Q_INDEX_NAME,
+ Q_TABLE_NAME,
+ )
+ )
+ db.execute(
+ get_drop_index_sql(
+ A_INDEX_NAME,
+ A_TABLE_NAME,
+ )
+ )
+
+ models = {
+ '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']", 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'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'}),
+ 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
+ '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']", 'blank': 'True'}),
+ 'hide_ignored_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
+ 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ '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'}),
+ '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'}),
+ 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'tag_filter_setting': ('django.db.models.fields.CharField', [], {'default': "'ignored'", 'max_length': '16'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+ 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'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'})
+ },
+ 'forum.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', 'blank': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Question']"}),
+ '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', 'blank': 'True'})
+ },
+ 'forum.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'}),
+ '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', 'blank': 'True'})
+ },
+ 'forum.answer': {
+ 'Meta': {'object_name': 'Answer', 'db_table': "u'answer'"},
+ 'accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': "orm['auth.User']"}),
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'html': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ '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_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_answers'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answers'", 'to': "orm['forum.Question']"}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ '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', 'blank': 'True'}),
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'forum.answerrevision': {
+ 'Meta': {'object_name': 'AnswerRevision', 'db_table': "u'answer_revision'"},
+ 'answer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Answer']"}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'answerrevisions'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'revised_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {})
+ },
+ 'forum.authkeyuserassociation': {
+ 'Meta': {'object_name': 'AuthKeyUserAssociation'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'provider': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_keys'", 'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Badge']"}),
+ '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', 'blank': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_user'", 'to': "orm['auth.User']"})
+ },
+ 'forum.badge': {
+ 'Meta': {'unique_together': "(('name', 'type'),)", 'object_name': 'Badge', 'db_table': "u'badge'"},
+ 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'through': "'Award'", 'to': "orm['auth.User']"}),
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '50', 'blank': 'True'}),
+ 'type': ('django.db.models.fields.SmallIntegerField', [], {})
+ },
+ 'forum.book': {
+ 'Meta': {'object_name': 'Book', 'db_table': "u'book'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'author': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'cover_img': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'pages': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'price': ('django.db.models.fields.DecimalField', [], {'max_digits': '6', 'decimal_places': '2'}),
+ 'publication': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'published_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'questions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'book'", 'db_table': "'book_question'", 'to': "orm['forum.Question']"}),
+ 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.bookauthorinfo': {
+ 'Meta': {'object_name': 'BookAuthorInfo', 'db_table': "u'book_author_info'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'blog_url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Book']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.bookauthorrss': {
+ 'Meta': {'object_name': 'BookAuthorRss', 'db_table': "u'book_author_rss'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'book': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Book']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'rss_created_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'url': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.comment': {
+ 'Meta': {'object_name': 'Comment', 'db_table': "u'comment'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'comment': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['auth.User']"})
+ },
+ 'forum.emailfeedsetting': {
+ 'Meta': {'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', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.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'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['auth.User']"})
+ },
+ 'forum.flaggeditem': {
+ 'Meta': {'unique_together': "(('content_type', 'object_id', 'user'),)", 'object_name': 'FlaggedItem', 'db_table': "u'flagged_item'"},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'flagged_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", 'to': "orm['auth.User']"})
+ },
+ 'forum.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['forum.Tag']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['auth.User']"})
+ },
+ 'forum.question': {
+ 'Meta': {'object_name': 'Question', 'db_table': "u'question'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'answer_accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'questions'", 'to': "orm['auth.User']"}),
+ 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'closed_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'favorite_questions'", 'through': "'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_questions'", 'to': "orm['auth.User']"}),
+ 'html': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ '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': "'last_active_in_questions'", 'to': "orm['auth.User']"}),
+ '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_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_questions'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'questions'", 'to': "orm['forum.Tag']"}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'view_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ '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', 'blank': 'True'}),
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'forum.questionrevision': {
+ 'Meta': {'object_name': 'QuestionRevision', 'db_table': "u'question_revision'"},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'questionrevisions'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Question']"}),
+ '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', [], {'max_length': '125'}),
+ 'text': ('django.db.models.fields.TextField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'})
+ },
+ 'forum.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['forum.Question']"}),
+ 'when': ('django.db.models.fields.DateTimeField', [], {}),
+ 'who': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'question_views'", 'to': "orm['auth.User']"})
+ },
+ 'forum.repute': {
+ 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"},
+ '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['forum.Question']"}),
+ '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']"})
+ },
+ 'forum.tag': {
+ 'Meta': {'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', 'blank': '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_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'}),
+ 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
+ },
+ 'forum.validationhash': {
+ 'Meta': {'unique_together': "(('user', 'type'),)", 'object_name': 'ValidationHash'},
+ 'expiration': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 25, 19, 13, 13, 325125)'}),
+ 'hash_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'seed': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'forum.vote': {
+ 'Meta': {'unique_together': "(('content_type', 'object_id', 'user'),)", 'object_name': 'Vote', 'db_table': "u'vote'"},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ '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'})
+ }
+ }
+
+ complete_apps = ['forum']
diff --git a/forum/migrations/__init__.py b/forum/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/forum/migrations/__init__.py
diff --git a/forum/models/__init__.py b/forum/models/__init__.py
index 2349c9e3..d0d2d4a7 100755
--- a/forum/models/__init__.py
+++ b/forum/models/__init__.py
@@ -5,6 +5,8 @@ from meta import Vote, Comment, FlaggedItem
from user import Activity, ValidationHash, EmailFeedSetting, AuthKeyUserAssociation
from repute import Badge, Award, Repute
from django.core.urlresolvers import reverse
+from forum.search.indexer import create_fulltext_indexes
+from django.db.models.signals import post_syncdb
import re
from base import *
@@ -440,6 +442,7 @@ tags_updated.connect(record_update_tags, sender=Question)
post_save.connect(record_favorite_question, sender=FavoriteQuestion)
user_updated.connect(record_user_full_updated, sender=User)
user_logged_in.connect(post_stored_anonymous_content)
+#post_syncdb.connect(create_fulltext_indexes)
Question = Question
QuestionRevision = QuestionRevision
diff --git a/forum/models/answer.py b/forum/models/answer.py
index 25a885ee..3de6cfc4 100755
--- a/forum/models/answer.py
+++ b/forum/models/answer.py
@@ -16,6 +16,7 @@ class AnswerManager(models.Manager):
author = author,
added_at = added_at,
wiki = wiki,
+ text = text,
html = sanitize_html(markdowner.convert(text)),
)
if answer.wiki:
@@ -94,6 +95,7 @@ class Answer(Content, DeletableContent):
self.last_edited_at = edited_at
self.last_edited_by = edited_by
self.html = sanitize_html(markdowner.convert(text))
+ self.text = text
#todo: bug wiki has no effect here
self.save()
@@ -136,9 +138,6 @@ class Answer(Content, DeletableContent):
else:
return None
- def get_latest_revision(self):
- return self.revisions.all()[0]
-
def get_question_title(self):
return self.question.title
diff --git a/forum/models/base.py b/forum/models/base.py
index 52fc8522..fcec47b4 100755
--- a/forum/models/base.py
+++ b/forum/models/base.py
@@ -89,30 +89,31 @@ class Content(models.Model):
"""
Base class for Question and Answer
"""
- author = models.ForeignKey(User, related_name='%(class)ss')
- added_at = models.DateTimeField(default=datetime.datetime.now)
+ author = models.ForeignKey(User, related_name='%(class)ss')
+ added_at = models.DateTimeField(default=datetime.datetime.now)
- wiki = models.BooleanField(default=False)
- wikified_at = models.DateTimeField(null=True, blank=True)
+ wiki = models.BooleanField(default=False)
+ wikified_at = models.DateTimeField(null=True, blank=True)
- locked = models.BooleanField(default=False)
- locked_by = models.ForeignKey(User, null=True, blank=True, related_name='locked_%(class)ss')
- locked_at = models.DateTimeField(null=True, blank=True)
+ locked = models.BooleanField(default=False)
+ locked_by = models.ForeignKey(User, null=True, blank=True, related_name='locked_%(class)ss')
+ locked_at = models.DateTimeField(null=True, blank=True)
- score = models.IntegerField(default=0)
- vote_up_count = models.IntegerField(default=0)
- vote_down_count = models.IntegerField(default=0)
+ score = models.IntegerField(default=0)
+ vote_up_count = models.IntegerField(default=0)
+ vote_down_count = models.IntegerField(default=0)
- comment_count = models.PositiveIntegerField(default=0)
+ comment_count = models.PositiveIntegerField(default=0)
offensive_flag_count = models.SmallIntegerField(default=0)
- last_edited_at = models.DateTimeField(null=True, blank=True)
- last_edited_by = models.ForeignKey(User, null=True, blank=True, related_name='last_edited_%(class)ss')
+ last_edited_at = models.DateTimeField(null=True, blank=True)
+ last_edited_by = models.ForeignKey(User, null=True, blank=True, related_name='last_edited_%(class)ss')
- html = models.TextField()
- comments = generic.GenericRelation(Comment)
- votes = generic.GenericRelation(Vote)
- flagged_items = generic.GenericRelation(FlaggedItem)
+ html = models.TextField(null=True)
+ text = models.TextField(null=True) #denormalized copy of latest revision
+ comments = generic.GenericRelation(Comment)
+ votes = generic.GenericRelation(Vote)
+ flagged_items = generic.GenericRelation(FlaggedItem)
class Meta:
abstract = True
@@ -141,7 +142,10 @@ class Content(models.Model):
self.comment_count = self.comment_count + 1
self.save()
- def post_get_last_update_info(self):
+ def get_latest_revision(self):
+ return self.revisions.all()[0]
+
+ def post_get_last_update_info(self):#todo: rename this subroutine
when = self.added_at
who = self.author
if self.last_edited_at and self.last_edited_at > when:
diff --git a/forum/models/question.py b/forum/models/question.py
index 9860eb24..683f7a3c 100755
--- a/forum/models/question.py
+++ b/forum/models/question.py
@@ -1,28 +1,49 @@
-from base import *
+from base import * #todo maybe remove *
from tag import Tag
+#todo: make uniform import for consts
from forum.const import CONST
+from forum import const
from forum.utils.html import sanitize_html
from markdown2 import Markdown
from django.utils.html import strip_tags
import datetime
+from django.conf import settings
+from django.utils.datastructures import SortedDict
+from forum.models.tag import MarkedTag
+from django.db.models import Q
+
markdowner = Markdown(html4tags=True)
from forum.utils.lists import LazyList
+#todo: too bad keys are duplicated see const sort methods
+QUESTION_ORDER_BY_MAP = {
+ 'latest': '-added_at',
+ 'oldest': 'added_at',
+ 'active': '-last_activity_at',
+ 'inactive': 'last_activity_at',
+ 'hottest': '-answer_count',
+ 'coldest': 'answer_count',
+ 'mostvoted': '-score',
+ 'leastvoted': 'score',
+ 'relevant': None #this is a special case
+}
+
class QuestionManager(models.Manager):
def create_new(self, title=None,author=None,added_at=None, wiki=False,tagnames=None, text=None):
html = sanitize_html(markdowner.convert(text))
summary = strip_tags(html)[:120]
question = Question(
- title = title,
- author = author,
- added_at = added_at,
+ title = title,
+ author = author,
+ added_at = added_at,
last_activity_at = added_at,
last_activity_by = author,
- wiki = wiki,
- tagnames = tagnames,
- html = html,
- summary = summary
+ wiki = wiki,
+ tagnames = tagnames,
+ html = html,
+ text = text,
+ summary = summary
)
if question.wiki:
question.last_edited_by = question.author
@@ -39,6 +60,115 @@ class QuestionManager(models.Manager):
)
return question
+ def run_advanced_search(
+ self,
+ request_user = None,
+ scope_selector = const.DEFAULT_POST_SCOPE,#unanswered/all/favorite (for logged in)
+ search_query = None,
+ tag_selector = None,
+ author_selector = None,#???question or answer author or just contributor
+ sort_method = const.DEFAULT_POST_SORT_METHOD
+ ):
+ """all parameters are guaranteed to be clean
+ however may not relate to database - in that case
+ a relvant filter will be silently dropped
+ """
+
+ qs = self.filter(deleted=False)#todo - add a possibility to see deleted questions
+
+ #return metadata
+ meta_data = {}
+ if tag_selector:
+ for tag in tag_selector:
+ qs = qs.filter(tags__name = tag)
+
+ if search_query:
+ try:
+ qs = qs.filter( Q(title__search = search_query) \
+ | Q(text__search = search_query) \
+ | Q(tagnames__search = search_query) \
+ | Q(answers__text__search = search_query)
+ )
+ except:
+ #fallback to dumb title match search
+ qs = qs.extra(
+ where=['title like %s'],
+ params=['%' + search_query + '%']
+ )
+
+ if scope_selector:
+ if scope_selector == 'unanswered':
+ if const.UNANSWERED_MEANING == 'NO_ANSWERS':
+ qs = qs.filter(answer_count=0)#todo: expand for different meanings of this
+ elif const.UNANSWERED_MEANING == 'NO_ACCEPTED_ANSWERS':
+ qs = qs.filter(answer_accepted=False)
+ elif const.UNANSWERED_MEANING == 'NO_UPVOTED_ANSWERS':
+ raise NotImplementedError()
+ else:
+ raise Exception('UNANSWERED_MEANING setting is wrong')
+ elif scope_selector == 'favorite':
+ qs = qs.filter(favorited_by = request_user)
+
+ #user contributed questions & answers
+ if author_selector:
+ try:
+ u = User.objects.get(id=int(author_selector))
+ qs = qs.filter(Q(author=u, deleted=False) | Q(answers__author=u, answers__deleted=False))
+ meta_data['author_name'] = u.username
+ except User.DoesNotExist:
+ meta_data['author_name'] = None
+
+ #get users tag filters
+ if request_user and request_user.is_authenticated():
+ uid_str = str(request_user.id)
+ #mark questions tagged with interesting tags
+ qs = qs.extra(
+ select = SortedDict([
+ (
+ 'interesting_score',
+ 'SELECT COUNT(1) FROM forum_markedtag, question_tags '
+ + 'WHERE forum_markedtag.user_id = %s '
+ + 'AND forum_markedtag.tag_id = question_tags.tag_id '
+ + 'AND forum_markedtag.reason = \'good\' '
+ + 'AND question_tags.question_id = question.id'
+ ),
+ ]),
+ select_params = (uid_str,),
+ )
+ if request_user.hide_ignored_questions:
+ #exclude ignored tags if the user wants to
+ ignored_tags = Tag.objects.filter(user_selections__reason='bad',
+ user_selections__user = request_user)
+ qs = qs.exclude(tags__in=ignored_tags)
+ else:
+ #annotate questions tagged with ignored tags
+ qs = qs.extra(
+ select = SortedDict([
+ (
+ 'ignored_score',
+ 'SELECT COUNT(1) FROM forum_markedtag, question_tags '
+ + 'WHERE forum_markedtag.user_id = %s '
+ + 'AND forum_markedtag.tag_id = question_tags.tag_id '
+ + 'AND forum_markedtag.reason = \'bad\' '
+ + 'AND question_tags.question_id = question.id'
+ )
+ ]),
+ select_params = (uid_str, )
+ )
+ # get the list of interesting and ignored tags (interesting_tag_names, ignored_tag_names) = (None, None)
+ pt = MarkedTag.objects.filter(user=request_user)
+ meta_data['interesting_tag_names'] = pt.filter(reason='good').values_list('tag__name', flat=True)
+ meta_data['ignored_tag_names'] = pt.filter(reason='bad').values_list('tag__name', flat=True)
+
+ qs = qs.select_related(depth=1)
+ #todo: fix orderby here
+ orderby = QUESTION_ORDER_BY_MAP[sort_method]
+ if orderby:
+ #relevance will be ignored here
+ qs = qs.order_by(orderby)
+ qs = qs.distinct()
+ return qs, meta_data
+
def update_tags(self, question, tagnames, user):
"""
Updates Tag associations for a question to match the given
@@ -216,6 +346,7 @@ class Question(Content, DeletableContent):
self.tagnames = tags
self.summary = question_summary
self.html = html
+ self.text = text
#wiki is an eternal trap whence there is no exit
if self.wiki == False and wiki == True:
@@ -310,9 +441,6 @@ class Question(Content, DeletableContent):
def get_revision_url(self):
return reverse('question_revisions', args=[self.id])
- def get_latest_revision(self):
- return self.revisions.all()[0]
-
def get_last_update_info(self):
when, who = self.post_get_last_update_info()
diff --git a/forum/models/tag.py b/forum/models/tag.py
index 8d26d6f4..e13baf9b 100755
--- a/forum/models/tag.py
+++ b/forum/models/tag.py
@@ -49,6 +49,8 @@ class TagManager(models.Manager):
def get_tags_by_questions(self, questions):
question_ids = []
+ if len(questions) == 0:
+ return []
for question in questions:
question_ids.append(question.id)
@@ -82,4 +84,4 @@ class MarkedTag(models.Model):
reason = models.CharField(max_length=16, choices=TAG_MARK_REASONS)
class Meta:
- app_label = 'forum' \ No newline at end of file
+ app_label = 'forum'
diff --git a/forum/search/README b/forum/search/README
new file mode 100644
index 00000000..c15dc221
--- /dev/null
+++ b/forum/search/README
@@ -0,0 +1,5 @@
+module dealing with search functions
+at this time only question and answer search
+
+that among other things contains
+available full text search implementations
diff --git a/forum/search/__init__.py b/forum/search/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/forum/search/__init__.py
diff --git a/forum/search/indexer.py b/forum/search/indexer.py
new file mode 100644
index 00000000..c7c45c59
--- /dev/null
+++ b/forum/search/indexer.py
@@ -0,0 +1,9 @@
+from django.conf import settings
+from django.db import connection
+
+def create_fulltext_indexes():
+ if settings.DATABASE_ENGINE == 'mysql':
+ cursor = connection.cursor()
+ cursor.execute('ALTER TABLE question ADD FULLTEXT (title, text, tagnames)')
+ cursor.execute('ALTER TABLE answer ADD FULLTEXT (title, text, tagnames)')
+
diff --git a/forum/search/sphinx/README b/forum/search/sphinx/README
new file mode 100644
index 00000000..8c008a23
--- /dev/null
+++ b/forum/search/sphinx/README
@@ -0,0 +1,4 @@
+This directory contains sample configuration for sphinx search
+
+Sphinx is a full text search engine for MySQL (only) with full
+word stemming in English and Russion (other languages are not supported)
diff --git a/sphinx/sphinx.conf b/forum/search/sphinx/sphinx.conf
index bf4bdc8b..bf4bdc8b 100644
--- a/sphinx/sphinx.conf
+++ b/forum/search/sphinx/sphinx.conf
diff --git a/forum/search/state_manager.py b/forum/search/state_manager.py
new file mode 100644
index 00000000..cb1908c6
--- /dev/null
+++ b/forum/search/state_manager.py
@@ -0,0 +1,152 @@
+#search state manager object
+#that lives in the session and takes care of the state
+#persistece during the search session
+from forum import const
+import logging
+
+ACTIVE_COMMANDS = (
+ 'sort', 'search', 'query',
+ 'reset_query', 'reset_author', 'reset_tags',
+ 'tags', 'scope', 'page_size', 'start_over',
+ 'page'
+)
+
+def some_in(what, where):
+ for element in what:
+ if element in where:
+ return True
+ return False
+
+class SearchState(object):
+ def __init__(self):
+ self.scope= const.DEFAULT_POST_SCOPE
+ self.query = None
+ self.tags = None
+ self.author = None
+ self.sort = const.DEFAULT_POST_SORT_METHOD
+ self.page_size = const.DEFAULT_QUESTIONS_PAGE_SIZE
+ self.page = 1
+ self.logged_in = False
+ logging.debug('new search state initialized')
+
+ def __str__(self):
+ out = 'scope=%s\n' % self.scope
+ out += 'query=%s\n' % self.query
+ if self.tags:
+ out += 'tags=%s\n' % ','.join(self.tags)
+ out += 'author=%s\n' % self.author
+ out += 'sort=%s\n' % self.sort
+ out += 'page_size=%d\n' % self.page_size
+ out += 'page=%d\n' % self.page
+ out += 'logged_in=%s\n' % str(self.logged_in)
+ return out
+
+ def set_logged_out(self):
+ if self.scope == 'favorite':
+ self.scope = None
+ self.logged_in = False
+
+ def set_logged_in(self):
+ self.logged_in = True
+
+ def reset(self):
+ #re-initialize, but keep login state
+ is_logged_in = self.logged_in
+ self.__init__()
+ self.logged_in = is_logged_in
+
+ def update_value(self, key, store):
+ if key in store:
+ old_value = getattr(self, key)
+ new_value = store[key]
+ if new_value != old_value:
+ setattr(self, key, new_value)
+ self.reset_page()
+
+ def relax_stickiness(self, input, view_log):
+ if view_log.get_previous(1) == 'questions':
+ if not some_in(ACTIVE_COMMANDS, input):
+ self.reset()
+ #todo also relax if 'all' scope was clicked twice
+
+ def update_from_user_input(self,input,raw_input = {}):
+ #todo: this function will probably not
+ #fit the case of multiple parameters entered at the same tiem
+ if 'start_over' in input:
+ self.reset()
+
+ if 'page' in input:
+ self.page = input['page']
+ #special case - on page flip no other input is accepted
+ return
+
+ if 'page_size' in input:
+ self.update_value('page_size',input)
+ self.reset_page()#todo may be smarter here - start with ~same q
+ #same as with page - return right away
+ return
+
+ if 'scope' in input:
+ if input['scope'] == 'favorite' and self.logged_in == False:
+ self.reset_scope()
+ else:
+ self.update_value('scope',input)
+
+ if 'tags' in input:
+ if self.tags:
+ old_tags = self.tags.copy()
+ self.tags = self.tags.union(input['tags'])
+ if self.tags != old_tags:
+ self.reset_page()
+ else:
+ self.tags = input['tags']
+
+ #all resets just return
+ if 'reset_tags' in input:
+ if self.tags:
+ self.tags = None
+ self.reset_page()
+ return
+
+ #todo: handle case of deleting tags one-by-one
+ if 'reset_author' in input:
+ if self.author:
+ self.author = None
+ self.reset_page()
+ return
+
+ if 'reset_query' in input:
+ self.reset_query()
+ return
+
+ self.update_value('author',input)
+
+ if 'query' in input:
+ self.update_value('query',input)
+ self.sort = 'relevant'
+ elif 'search' in raw_input:#a case of use nulling search query by hand
+ self.reset_query()
+ return
+
+
+ if 'sort' in input:
+ if input['sort'] == 'relevant' and self.query is None:
+ self.reset_sort()
+ else:
+ self.update_value('sort',input)
+
+ def reset_page(self):
+ self.page = 1
+
+ def reset_query(self):
+ if self.query:
+ self.query = None
+ self.reset_page()
+ if self.sort == 'relevant':
+ self.reset_sort()
+
+ def reset_sort(self):
+ self.sort = const.DEFAULT_POST_SORT_METHOD
+
+ def reset_scope(self):
+ self.scope = const.DEFAULT_POST_SCOPE
diff --git a/forum/skins/default/media/images/logo.gif b/forum/skins/default/media/images/logo.gif
index e4d2b957..03eb79f4 100644
--- a/forum/skins/default/media/images/logo.gif
+++ b/forum/skins/default/media/images/logo.gif
Binary files differ
diff --git a/forum/skins/default/media/style/style.css b/forum/skins/default/media/style/style.css
index 93c979ce..3f51e619 100755
--- a/forum/skins/default/media/style/style.css
+++ b/forum/skins/default/media/style/style.css
@@ -204,7 +204,6 @@ blockquote {
background-color: #F5F5F5;
}
-/*页面布局*/
#wrapper {
width: 960px;
margin: auto;
@@ -218,7 +217,7 @@ blockquote {
}
#room {
- padding: 10px 0 10px 0;
+ padding: 0 0 10px 0;
background-color: #FFF;
border-bottom: 1px solid #777;
}
@@ -251,16 +250,15 @@ blockquote {
/*#licenseLogo {position:absolute;top:10px;right:10px;}*/
-/*顶部及导航栏*/
+/* why is this called top? - this contains links like login, faq, etc */
#top {
position: absolute;
top: 0px;
- right: 0px;
+ right: 250px;
height: 20px;
text-align: right;
padding: 3px;
background-color: #ffffff;
- width: 500px;
}
/*#header {width:960px;}*/
@@ -270,13 +268,24 @@ blockquote {
margin-left: 20px;
text-decoration: underline;
font-size: 12px;
- color: #333333;
+ color: #555555;
}
#logo {
- padding: 5px 0px 0px 0px;
+ padding: 0px 0px 0px 10px;
+ height: 90px;
+ width: 70px;
+}
+
+#logoContainer {
+}
+#navTabContainer {
+ width: 600px;
+ padding-left: 10px;
+ text-align: left;
}
+/* navBar includes logo, main tabs and links like logout, about, faq */
#navBar {
float: clear;
position: relative;
@@ -285,7 +294,7 @@ blockquote {
}
#navBar .nav {
- margin: 20px 0px 0px 16px; /*letter-spacing:1px; */
+ margin: 20px 0px 0px 0px; /*letter-spacing:1px; */
}
#navBar .nav a {
@@ -300,8 +309,8 @@ blockquote {
height: 25px;
line-height: 30px;
margin-left: 10px;
- font-size: 14px;
- font-weight: 400;
+ font-size: 18px;
+ font-weight: 100;
text-decoration: none;
display: block;
float: left;
@@ -325,7 +334,7 @@ blockquote {
}
#navBar .nav a.special {
- font-size: 14px;
+ font-size: 18px;
color: #B02B2C;
font-weight: bold;
text-decoration: none;
@@ -335,35 +344,78 @@ blockquote {
text-decoration: underline;
}
+/* todo: this is probably not used any more */
#navBar .nav div.focus {
float: right;
padding-right: 0px;
}
-/*搜索栏*/
#searchBar {
- width: 958px;
- background-color: #888a85; /*#e9b96e;*/
+ display:inline-block;
+ background-color: #cccccc;/*888a85; /*#e9b96e;*/
border: 1px solid #aaaaaa;
- padding: 4px 0 0 0;
+ padding: 4px 7px 5px 5px;
}
-/* #B02B2C */
-#searchBar .content {
+#searchBar .searchInput {
+ font-size: 24px;
+ line-height: 24px;
+ height: 36px;
+ width: 598px;
+ margin: 0px;
+ padding: 5px 0 0 5px;
}
-#searchBar .searchInput {
- font-size: 13px;
- height: 18px;
- width: 400px;
+#searchBar .searchInputCancelable {
+ font-size: 24px;
+ line-height: 24px;
+ height: 36px;
+ width: 552px;
+ padding: 5px 0 0 5px;
+ margin: 0px;
}
#searchBar .searchBtn {
- font-size: 14px;
- height: 26px;
- width: 80px;
+ font-size: 20px;
+ color: #666666;
+ height: 40px;
+ line-height: 22px;
+ text-align: center;
+ margin-top:1px;
+ padding-bottom: 4px;
+}
+
+#searchBar .cancelSearchBtn {
+ font-size: 20px;
+ color: #666666;
+ height: 40px;
+ width: 40px;
+ line-height: 22px;
+ padding-bottom: 4px;
+ margin-top:1px;
+ text-align: center;
}
+#askFormBar {
+ display:inline-block;
+ background-color: #e3e3e3;/*888a85; /*#e9b96e;*/
+ border: 1px solid #aaaaaa;
+ padding: 4px 7px 5px 5px;
+}
+#askFormBar p {
+ width: 685px;
+ margin:0 0 5px 0;
+}
+#askFormBar .questionTitleInput {
+ font-size: 24px;
+ line-height: 24px;
+ height: 36px;
+ width: 680px;
+ margin: 0px;
+ padding: 5px 0 0 5px;
+}
+
+
#searchBar .options {
padding: 3px 0 3px 0;
font-size: 100%;
@@ -499,7 +551,7 @@ blockquote {
.short-summary {
position: relative;
padding: 3px 5px 5px 10px;
- border-top: 1px dotted #ccccce;
+ border-top: 1px dashed #ccccce;
overflow: hidden;
width: 700px;
float: left;
@@ -552,6 +604,10 @@ blockquote {
font-weight: 800;
}
+.evenMore a {
+ text-decoration: underline;
+}
+
.questions-count {
font-size: 32px;
font-family: sans-serif;
@@ -623,13 +679,16 @@ blockquote {
}
.boxC {
- background: #cacdc6; /*f9f7ed;*/
+ background: white /*#cacdc6; /*f9f7ed;*/
padding: 10px;
margin-bottom: 8px;
+ margin-left: 10px;
+ /*
border-top: 1px solid #eeeeec;
border-left: 1px solid #eeeeec;
border-right: 1px solid #a9aca5;
border-bottom: 1px solid #babdb6;
+ */
}
.boxC p {
@@ -846,6 +905,7 @@ a:hover.medal {
width: 100%;
clear: both;
margin-bottom: 3px;
+ margin-top: 3px;
}
.tabsA {
@@ -866,7 +926,16 @@ a:hover.medal {
height: 20px;
}
-.tabsA a.on, .tabsA a:hover, .tabsB a.on, .tabsB a:hover {
+.tabsC {
+ background-color: #FFF;
+ float: left;
+ position: relative;
+ display: block;
+ font-weight: bold;
+ height: 20px;
+}
+
+.tabsA a.on, .tabsA a:hover, .tabsB a.on, .tabsB a:hover , .tabsC a.on, tabsC a:hover {
background: #fff;
color: #a40000;
border-top: 1px solid #babdb6;
@@ -879,7 +948,7 @@ a:hover.medal {
padding: 0px 11px 0px 11px;
}
-.tabsA a {
+.tabsA a, .tabsC a{
background: #f9f7eb;
border-top: 1px solid #eeeeec;
border-left: 1px solid #eeeeec;
@@ -895,6 +964,12 @@ a:hover.medal {
text-decoration: none;
}
+.tabsA .label, .tabsC .label {
+ float: left;
+ font-weight: bold;
+ margin: 8px 4px 0 4px;
+}
+
.tabsB a {
background: #eee;
border: 1px solid #eee;
@@ -920,7 +995,6 @@ a:hover.medal {
}
.headQuestions {
- float: left;
height: 23px;
line-height: 23px;
margin: 5px 0 0 5px;
@@ -951,6 +1025,7 @@ a:hover.medal {
padding-left: 24px;
}
+/* todo: make this class applicable to all headers it is actually uses in tags.html too */
.headUsers {
float: left;
height: 23px;
@@ -1486,13 +1561,18 @@ span.form-error {
font-size: 100%;
min-height: 200px;
line-height: 18px;
+ width: 697px;
+ margin:0;
+}
+
+#id_title {
width: 100%;
}
.wmd-preview {
- margin-top: 10px;
+ margin: 10px 0 0 0;
padding: 6px;
- width: 100%;
+ width: 691px;
background-color: #F5F5F5;
min-height: 20px;
}
@@ -1680,7 +1760,6 @@ ins .post-tag {
}
.narrow .stats {
- background: transparent none repeat scroll 0 0;
float: left;
height: 48px;
margin: 0 0 0 7px;
@@ -1689,6 +1768,11 @@ ins .post-tag {
font-family: Arial;
}
+/* todo: remove this hack? */
+.user-stats-table .narrow {
+ width: 660px;
+}
+
.stats div {
font-size: 11px;
text-align: center;
@@ -2497,15 +2581,16 @@ p.signup_p {
}
.karma-diagram {
- width:550px;
- height:250px;
+ width:390px;
+ height:300px;
float:left;
+ margin-right:10px;
}
.karma-details {
float:right;
- width:385px;
- height:300px;
+ width:300px;
+ height:250px;
overflow-y:auto;
word-wrap:break-word;
}
@@ -2525,3 +2610,20 @@ p.signup_p {
color:red;
padding:5px;
}
+
+.search-result-summary {
+ font-weight: bold;
+ font-size:18px;
+ line-height:30px;
+ margin:0px 0px 0px 5px;
+ padding:0px;
+}
+.search-tips {
+ font-size:12px;
+ line-height:12px;
+ margin:0 0 5px 5px;
+ padding:0px;
+}
+.search-tips a {
+ text-decoration: underline;
+}
diff --git a/forum/skins/default/templates/about.html b/forum/skins/default/templates/about.html
index 66dcc3fd..686141b3 100644
--- a/forum/skins/default/templates/about.html
+++ b/forum/skins/default/templates/about.html
@@ -1,4 +1,4 @@
-{% extends "base_content.html" %}
+{% extends "base.html" %}
<!-- template about.html -->
{% load i18n %}
{% load extra_tags %}
diff --git a/forum/skins/default/templates/ask.html b/forum/skins/default/templates/ask.html
index 083b01d9..4278f4cb 100644
--- a/forum/skins/default/templates/ask.html
+++ b/forum/skins/default/templates/ask.html
@@ -56,6 +56,7 @@
</script>
{% endblock %}
+{% comment %}
{% block content %}
<div id="main-bar" class="headNormal">
{% trans "Ask a question" %}
@@ -124,6 +125,7 @@
</div>
</div>
{% endblock %}
+{% endcomment %}
{% block sidebar %}
{% include "question_edit_tips.html" %}
diff --git a/forum/skins/default/templates/ask_form.html b/forum/skins/default/templates/ask_form.html
new file mode 100644
index 00000000..25e9fe6c
--- /dev/null
+++ b/forum/skins/default/templates/ask_form.html
@@ -0,0 +1,66 @@
+{% load i18n %}
+{% load smart_if %}
+<div id="askform">
+ <form id="fmask" action="" method="post" >
+ <div class="form-item">
+ {% comment %}
+ <label for="id_title" ><strong>{{ form.title.label_tag }}:</strong></label>
+ {% endcomment %}
+ <div id="askFormBar">
+ {% if not request.user.is_authenticated %}
+ <p>{% trans "login to post question info" %}</p>
+ {% else %}
+ {% ifequal settings.EMAIL_VALIDATION 'on' %}
+ {% if not request.user.email_isvalid %}
+ {% blocktrans with request.user.email as email %}must have valid {{email}} to post,
+ see {{email_validation_faq_url}}
+ {% endblocktrans %}
+ {% endif %}
+ {% endifequal %}
+ {% endif %}
+ <input id="id_title" class="questionTitleInput" name="title"
+ value="{% if form.initial.title %}{{form.initial.title}}{% endif %}"/>
+ </div>
+ {{ form.title.errors }}
+ <span class="form-error"></span><br/>
+ <div class="title-desc">
+ {{ form.title.help_text }}
+ </div>
+ </div>
+
+ <div class="form-item">
+ <div id="wmd-button-bar" class="wmd-panel"></div>
+ {{ form.text }}
+
+ <div class="preview-toggle">
+ <table>
+ <tr>
+ <td>
+ <span id="pre-collapse" title="{% trans "Toggle the real time Markdown editor preview" %}">{% trans "toggle preview" %}</span>
+ </td>
+ {% if settings.WIKI_ON %}
+ <td style="text-align:right;">
+ {{ form.wiki }} <span style="font-weight:normal;cursor:help" title="{{form.wiki.help_text}}">{{ form.wiki.label_tag }} </span>
+ </td>
+ {% endif %}
+ </tr>
+
+ </table>
+ </div>
+ <div id="previewer" class="wmd-preview"></div>
+ <span class="form-error"></span>
+ </div>
+ <div class="form-item">
+ <strong>{{ form.tags.label_tag }}:</strong> {% trans "(required)" %} <span class="form-error"></span><br/>
+ {{ form.tags }} {{ form.tags.errors }}
+ </div>
+ <p class="title-desc">
+ {{ form.tags.help_text }}
+ </p>
+ {% if not request.user.is_authenticated %}
+ <input type="submit" value="{% trans "Login/signup to post your question" %}" class="submit" />
+ {% else %}
+ <input type="submit" value="{% trans "Ask your question" %}" class="submit" />
+ {% endif %}
+ </form>
+</div>
diff --git a/forum/skins/default/templates/base.html b/forum/skins/default/templates/base.html
index 1018da50..0b85e7fb 100644
--- a/forum/skins/default/templates/base.html
+++ b/forum/skins/default/templates/base.html
@@ -2,6 +2,7 @@
<!-- template base.html -->
{% load extra_filters %}
{% load extra_tags %}
+{% load smart_if %}
{% load i18n %}
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
@@ -36,7 +37,19 @@
});
</script>
{% endif %}
-
+ {% if active_tab != "tags" and active_tab != "users" %}
+ <script type="text/javascript">
+ $('#nav_ask').click(
+ function(){
+ alert('hullo');
+ var starting_title = $('#keywords').attr('value');
+ alert('tittle is ' + starting_title);
+ window.location.href = $(this).attr('href') + '?'
+ + starting_title;
+ }
+ );
+ </script>
+ {% endif %}
{% block forejs %}
{% endblock %}
</head>
@@ -55,6 +68,7 @@
<div id="wrapper">
<div id="room">
<div id="CALeft">
+ {% include "input_bar.html" %}
{% block content%}
{% endblock%}
diff --git a/forum/skins/default/templates/base_content.html b/forum/skins/default/templates/base_content.html
index 1bae0afd..284007d8 100644
--- a/forum/skins/default/templates/base_content.html
+++ b/forum/skins/default/templates/base_content.html
@@ -55,6 +55,7 @@
<div id="wrapper">
<div id="room">
<div id="CAFull">
+ {% include "input_bar.html" %}
{% block content%}
{% endblock%}
diff --git a/forum/skins/default/templates/book.html b/forum/skins/default/templates/book.html
index 8574fa73..528b800d 100644
--- a/forum/skins/default/templates/book.html
+++ b/forum/skins/default/templates/book.html
@@ -122,7 +122,7 @@
</h3>
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url tag_questions tag|urlencode %}" title="{% "see questions tagged with" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}" title="{% blocktrans %}see questions tagged '{{ tag }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
<div class="started">
diff --git a/forum/skins/default/templates/faq.html b/forum/skins/default/templates/faq.html
index ca963237..cc790ccc 100644
--- a/forum/skins/default/templates/faq.html
+++ b/forum/skins/default/templates/faq.html
@@ -1,4 +1,4 @@
-{% extends "base_content.html" %}
+{% extends "base.html" %}
<!-- template faq.html -->
{% load extra_tags %}
{% load humanize %}
diff --git a/forum/skins/default/templates/feedback.html b/forum/skins/default/templates/feedback.html
index 38bb48ff..af4f635f 100644
--- a/forum/skins/default/templates/feedback.html
+++ b/forum/skins/default/templates/feedback.html
@@ -1,4 +1,4 @@
-{% extends "base_content.html" %}
+{% extends "base.html" %}
<!-- template about.html -->
{% load i18n %}
{% load extra_tags %}
diff --git a/forum/skins/default/templates/header.html b/forum/skins/default/templates/header.html
index 099bfb85..0a1a3296 100644
--- a/forum/skins/default/templates/header.html
+++ b/forum/skins/default/templates/header.html
@@ -1,5 +1,6 @@
<!-- template header.html -->
{% load extra_tags %}
+{% load smart_if %}
{% load i18n %}
<div id="roof">
<div id="navBar">
@@ -13,53 +14,34 @@
<a href="{% url about %}">{% trans "about" %}</a>
<a href="{% url faq %}">{% trans "faq" %}</a>
</div>
- <table width="100%" border="0" cellspacing="0" cellpadding="0">
+ <table border="0" cellspacing="0" cellpadding="0">
<tr>
- <td width="23%">
- <div id="logo">
- <a href="{% url index %}">
- <img src="{% media "/media/images/logo.png" %}" title="{% trans "back to home page" %}" alt="{{settings.APP_TITLE}} logo"/>
- </a>
- </div>
- </td>
- <td width="77%" valign="bottom">
- <div class="nav">
- <a id="nav_questions" href="{% url questions %}" >{% trans "questions" %}</a>
- <a id="nav_tags" href="{% url tags %}">{% trans "tags" %}</a>
- <a id="nav_users" href="{% url users %}">{% trans "users" %}</a>
- {% if settings.BOOKS_ON %}
- <a id="nav_books" href="{% url books %}">{% trans "books" %}</a>
- {% endif %}
- <a id="nav_badges" href="{% url badges %}">{% trans "badges" %}</a>
- <a id="nav_unanswered" href="{% url unanswered %}">{% trans "unanswered questions" %}</a>
- <div class="focus">
- <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a>
- </div>
+ <td id="logoContainer">
+ <div id="logo">
+ <a href="{% url questions %}?start_over=true"><img
+ src="{% media "/media/images/logo.gif" %}" title="{% trans "back to home page" %}" alt="{{settings.APP_TITLE}} logo"/></a>
+ </div>
+ </td>
+ <td id="navTabContainer" valign="bottom" align="left">
+ <div class="nav">
+ <a id="nav_questions" href="{% url questions %}" >{% trans "questions" %}</a>
+ <a id="nav_tags" href="{% url tags %}">{% trans "tags" %}</a>
+ <a id="nav_users" href="{% url users %}">{% trans "users" %}</a>
+ {% if settings.BOOKS_ON %}
+ <a id="nav_books" href="{% url books %}">{% trans "books" %}</a>
+ {% endif %}
+ <a id="nav_badges" href="{% url badges %}">{% trans "badges" %}</a>
+ <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a>
+ {% comment %}
+ <a id="nav_unanswered" href="{% url unanswered %}">{% trans "unanswered questions" %}</a>
+ <div class="focus">
+ <a id="nav_ask" href="{% url ask %}" class="special">{% trans "ask a question" %}</a>
</div>
-
- </td>
+ {% endcomment %}
+ </div>
+ </td>
</tr>
</table>
</div>
- <div id="searchBar">
- <table width="100%" border="0" cellpadding="0" cellspacing="0" class="content">
- <tr>
- <td align="center" valign="middle">
- <form action="{% url search %}" method="get">
- <div>
- <input type="text" class="searchInput" value="{{ keywords }}" name="q" id="keywords" />
- <input type="submit" name="Submit" value="{% trans "search" %}" class="searchBtn" />
- </div>
- <div class="options">
- <input id="type-question" type="radio" value="question" name="t"
- checked="checked" /><label for="type-question">{% trans "questions" %}</label>
- <input id="type-tag" type="radio" value="tag" name="t" /><label for="type-tag">{% trans "tags" %}</label>
- <input id="type-user" type="radio" value="user" name="t" /><label for="type-user">{% trans "users" %}</label>
- </div>
- </form>
- </td>
- </tr>
- </table>
- </div>
</div>
<!-- end template header.html -->
diff --git a/forum/skins/default/templates/index.html b/forum/skins/default/templates/index.html
index 8a885dd4..f94f84fc 100644
--- a/forum/skins/default/templates/index.html
+++ b/forum/skins/default/templates/index.html
@@ -23,7 +23,7 @@
{% endblock %}
{% block content %}
<div class="tabBar">
- <div class="headQuestions">{% trans "Questions" %}</div>
+ <div class="headUsers">{% trans "Questions" %}</div>
<div class="tabsA">
<a id="latest" href="{% url questions %}?sort=latest" title="{% trans "last updated questions" %}" >{% trans "newest" %}</a>
<a id="hottest" href="{% url questions %}?sort=hottest" title="{% trans "hottest questions" %}" >{% trans "hottest" %}</a>
@@ -57,11 +57,12 @@
{% cache 60 recent_tags %}
{% for tag in tags %}
<a rel="tag"
- title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>
+ title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}"
+ href="{% url questions %}?tags={{tag.name|urlencode}}">{{ tag.name }}</a>
{% endfor %}
{% endcache %}
</div>
- <div class="more"><a href="{% url tags %}">{% trans "popular tags" %} </a> </div>
+ <div class="more"><a href="{% url tags %}">{% trans "see all tags" %}</a> </div>
</div>
</div>
{% if awards %}
diff --git a/forum/skins/default/templates/index_.html b/forum/skins/default/templates/index_.html
index 5e4cf533..36531f62 100644
--- a/forum/skins/default/templates/index_.html
+++ b/forum/skins/default/templates/index_.html
@@ -22,7 +22,7 @@
{% endblock %}
{% block content %}
<div class="tabBar">
- <div class="headQuestions">{% trans "Questions" %}</div>
+ <div class="headUsers">{% trans "Questions" %}</div>
<div class="tabsA">
<a id="latest" href="{% url index %}?sort=latest" title="{% trans "last updated questions" %}" >{% trans "newest" %}</a>
<a id="hottest" href="{% url index %}?sort=hottest" title="{% trans "hottest questions" %}" >{% trans "hottest" %}</a>
@@ -60,7 +60,7 @@
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}' {% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}" title="{% blocktrans %}see questions tagged '{{ tag }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
</div>
@@ -87,7 +87,8 @@
<div class="tags">
{% for tag in tags %}
<a rel="tag"
- title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>
+ title="{% blocktrans with tag.name as tagname %}see questions tagged '{{tagname}}'{% endblocktrans %}"
+ href="{% url questions %}?tags={{tag.name|urlencode}}">{{ tag.name }}</a>
{% endfor %}
</div>
<div class="more"><a href="{% url tags %}">{% trans "popular tags" %} »</a> </div>
diff --git a/forum/skins/default/templates/input_bar.html b/forum/skins/default/templates/input_bar.html
new file mode 100644
index 00000000..59236350
--- /dev/null
+++ b/forum/skins/default/templates/input_bar.html
@@ -0,0 +1,45 @@
+{% load i18n %}
+{% load smart_if %}
+{% if active_tab != "ask" %}
+<div id="searchBar">
+ {% comment %}url action depends on which tab is active{% endcomment %}
+ <form
+ {% if active_tab == "tags" or active_tab == "users" %}
+ action="{% url search %}"
+ {% else %}
+ action="{% url questions %}"
+ {% endif %}
+ method="get">
+ {% comment %} class was searchInput {% endcomment %}
+ <input
+ {% if query %}
+ class="searchInputCancelable"
+ {% else %}
+ class="searchInput"
+ {% endif %}
+ type="text"
+ value="{{ query|default_if_none:"" }}"
+ name="query"
+ id="keywords"/>
+ {% if query %}{% comment %}query is only defined by questions view{% endcomment %}
+ <input type="button"
+ value="x"
+ name="reset_query"
+ {% comment %}todo - make sure it works on Enter keypress{% endcomment %}
+ onclick="window.location.href='{% url questions %}?reset_query=true'"
+ value="true"
+ class="cancelSearchBtn"/>
+ {% endif %}
+ <input type="submit" value="{% trans "search" %}" name="search" class="searchBtn" default />
+ {% if active_tab == "tags" %}
+ <input type="hidden" name="t" value="tag"/>
+ {% else %}
+ {% if active_tab == "users" %}
+ <input type="hidden" name="t" value="user"/>
+ {% endif %}
+ {% endif %}
+ </form>
+</div>
+{% else %}
+ {% include "ask_form.html" %}
+{% endif %}
diff --git a/forum/skins/default/templates/question.html b/forum/skins/default/templates/question.html
index 1c542c8b..79ff9a5b 100644
--- a/forum/skins/default/templates/question.html
+++ b/forum/skins/default/templates/question.html
@@ -128,10 +128,12 @@
{{ question.html|safe }}
</div>
<div id="question-controls" class="post-controls">
+ {% comment %}todo: here we have important case to reset search state{% endcomment %}
<div id="question-tags" class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url tag_questions tag|urlencode %}" class="post-tag"
- title="{% blocktrans with tag as tagname %}see questions tagged '{{ tagname }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}&start_over=true"
+ class="post-tag"
+ title="{% blocktrans %}see questions tagged '{{tag}}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
{% joinitems using '<span class="action-link-separator">|</span>' %}
@@ -224,7 +226,7 @@
<hr/>
<div class="tabBar">
<a name="sort-top"></a>
- <div class="headQuestions">
+ <div class="headUsers">
{% blocktrans count answers|length as counter %}
One Answer:
{% plural %}
@@ -474,9 +476,10 @@
</p>
<p class="tags" >
{% for tag in tags %}
- <a href="{% url tag_questions tag.name|urlencode %}"
- title="{% trans "see questions tagged"%}'{{tag.name}}'{% trans "using tags" %}"
- rel="tag">{{ tag.name }}</a> <span class="tag-number">&#215;{{ tag.used_count|intcomma }}</span><br/>
+ <a href="{% url questions %}?tags={{tag.name|urlencode}}&start_over=true"
+ title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{tag_name}}'{% endblocktrans %}"
+ rel="tag">{{ tag.name }}</a>
+ <span class="tag-number">&#215;{{ tag.used_count|intcomma }}</span><br/>
{% endfor %}
</p>
<p>
diff --git a/forum/skins/default/templates/question_list.html b/forum/skins/default/templates/question_list.html
index 53633691..38ac254a 100644
--- a/forum/skins/default/templates/question_list.html
+++ b/forum/skins/default/templates/question_list.html
@@ -16,7 +16,7 @@
</div>
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}' {% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}" title="{% blocktrans %}see questions tagged '{{ tag }}'{%endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
</div>
diff --git a/forum/skins/default/templates/question_summary_list_roll.html b/forum/skins/default/templates/question_summary_list_roll.html
index 57685d6d..f2432a24 100644
--- a/forum/skins/default/templates/question_summary_list_roll.html
+++ b/forum/skins/default/templates/question_summary_list_roll.html
@@ -49,7 +49,7 @@
<div class="tags">
{% for tag in question.tagname_list %}
- <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}" title="{% blocktrans %}see questions tagged '{{ tag }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
</div>
diff --git a/forum/skins/default/templates/questions.html b/forum/skins/default/templates/questions.html
index 366727d1..f864180f 100644
--- a/forum/skins/default/templates/questions.html
+++ b/forum/skins/default/templates/questions.html
@@ -10,9 +10,11 @@
<script type="text/javascript">
var tags = {{ tags_autocomplete|safe }};
$().ready(function(){
- var tab_id = "{{ tab_id }}";
- $("#"+tab_id).attr('className',"on");
- var on_tab = {% if is_unanswered %}'#nav_unanswered'{% else %}'#nav_questions'{% endif %};
+ var sort_tab_id = "{{ sort }}";
+ $("#"+sort_tab_id).attr('className',"on");
+ var scope_tab_id = "{{ scope }}";
+ $("#"+scope_tab_id).attr('className',"on");
+ var on_tab = '#nav_questions';
$(on_tab).attr('className','on');
Hilite.exact = false;
Hilite.elementid = "listA";
@@ -24,7 +26,8 @@
{% endblock %}
{% block content %}
<div class="tabBar">
- <div class="headQuestions">
+ {% comment %}
+ <div class="headUsers">
{% if searchtag %}
{% trans "Found by tags" %}
{% else %}
@@ -42,75 +45,197 @@
{% endif %}
{% endif %}
{% endif %}
+ </div><br/>
+ {% endcomment %}
+ <div class="tabsC">
+ <span class="label">{% trans "In:" %}</span>
+ <a id="all" class="off" href="?scope=all" title="{% trans "see all questions" %}">{% trans "all" %}</a>
+ <a id="unanswered" class="off" href="?scope=unanswered&sort=coldest" title="{% trans "see unanswered questions" %}">{% trans "unanswered" %}</a>
+ {% if request.user.is_authenticated %}
+ <a id="favorite" class="off" href="?scope=favorite" title="{% trans "see your favorite questions" %}">{% trans "favorite" %}</a>
+ {% endif %}
</div>
<div class="tabsA">
- <a id="latest" href="{% if is_search %}{{ search_uri }}&{% else %}?{% endif %}sort=latest" class="off" title="{% trans "most recently asked questions" %}">{% trans "newest" %}</a>
- <a id="active" href="{% if is_search %}{{ search_uri }}&{% else %}?{% endif %}sort=active" class="off" title="{% trans "most recently updated questions" %}">{% trans "active" %}</a>
- <a id="hottest" href="{% if is_search %}{{ search_uri }}&{% else %}?{% endif %}sort=hottest" class="off" title="{% trans "hottest questions" %}">{% trans "hottest" %}</a>
- <a id="mostvoted" href="{% if is_search %}{{ search_uri }}&{% else %}?{% endif %}sort=mostvoted" class="off" title="{% trans "most voted questions" %}">{% trans "most voted" %}</a>
+ <span class="label">{% trans "Sort by:" %}</span>
+ {% if sort == "oldest" %}
+ <a id="oldest"
+ href="?sort=latest"
+ class="off"
+ title="{% trans "click to see the newest questions" %}">{% trans "oldest" %}</a>
+ {% else %}
+ {% if sort == "latest" %}
+ <a id="latest"
+ href="?sort=oldest"
+ class="off"
+ title="{% trans "click to see the oldest questions" %}">{% trans "newest" %}</a>
+ {% else %}
+ <a id="latest"
+ href="?sort=latest"
+ class="off"
+ title="{% trans "click to see the newest questions" %}">{% trans "newest" %}</a>
+ {% endif %}
+ {% endif %}
+
+ {% if sort == "inactive" %}
+ <a id="inactive"
+ href="?sort=active"
+ class="off"
+ title="{% trans "click to see the most recently updated questions" %}">{% trans "inactive" %}</a>
+ {% else %}
+ {% if sort == "active" %}
+ <a id="active"
+ href="?sort=inactive"
+ class="off"
+ title="{% trans "click to see the least recently updated questions" %}">{% trans "active" %}</a>
+ {% else %}
+ <a id="active"
+ href="?sort=active"
+ class="off"
+ title="{% trans "click to see the most recently updated questions" %}">{% trans "active" %}</a>
+ {% endif %}
+ {% endif %}
+
+ {% if sort == "coldest" %}
+ <a id="coldest"
+ href="?sort=hottest"
+ class="off"
+ title="{% trans "click to see hottest questions" %}">{% trans "less answers" %}</a>
+ {% else %}
+ {% if sort == "hottest" %}
+ <a id="hottest"
+ href="?sort=coldest"
+ class="off"
+ title="{% trans "click to see coldest questions" %}">{% trans "more answers" %}</a>
+ {% else %}
+ <a id="hottest"
+ href="?sort=hottest"
+ class="off"
+ title="{% trans "click to see hottest questions" %}">{% trans "more answers" %}</a>
+ {% endif %}
+ {% endif %}
+
+ {% if sort == "leastvoted" %}
+ <a id="leastvoted"
+ href="?sort=mostvoted"
+ class="off"
+ title="{% trans "click to see most voted questions" %}">{% trans "unpopular" %}</a>
+ {% else %}
+ {% if sort == "mostvoted" %}
+ <a id="mostvoted"
+ href="?sort=leastvoted"
+ class="off"
+ title="{% trans "click to see least voted questions" %}">{% trans "popular" %}</a>
+ {% else %}
+ <a id="mostvoted"
+ href="?sort=mostvoted"
+ class="off"
+ title="{% trans "click to see most voted questions" %}">{% trans "popular" %}</a>
+ {% endif %}
+ {% endif %}
</div>
</div>
+{% if questions_count > 0 %}
+ <div style="clear:both">
+ <p class="search-result-summary">
+ {% if author_name or search_tags or query %}
+ {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} One question found{% plural %}{{q_num}} questions found{% endblocktrans %}
+ {% else %}
+ {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} {{q_num}} question{% plural %}{{q_num}} questions{% endblocktrans %}
+ {% endif %}
+ {% joinitems using ', ' %}
+ {% if author_name %}
+ {% blocktrans %}with {{author_name}}'s contributions{% endblocktrans %}
+ {% endif %}
+ {% separator %}
+ {% if search_tags %}
+ {% trans "tagged" %}
+ "{{ search_tags|join:"\", \"" }}"
+ {% endif %}
+ {% endjoinitems %}
+ </p>
+ {% if author_name or search_tags or query %}
+ <p class="search-tips">{% trans "Search tips:" %}
+ {% ifmany query search_tags author_name %}
+ {% joinitems using ', ' ' or ' %}
+ {% if author_name %}
+ <a href="{% url questions %}?reset_author=true">{% trans "reset author" %}</a>
+ {% endif %}
+ {% separator %}
+ {% if search_tags %}
+ <a href="{% url questions %}?reset_tags=true">{% trans "reset tags" %}</a>
+ {% endif %}
+ {% separator %}
+ {% ifmany query search_tags author_name %}
+ <a href="{% url questions %}?start_over=true">{% trans "start over" %}</a>
+ {% endifmany %}
+ {% endjoinitems %}
+ {% else %}
+ <a href="{% url questions %}?start_over=true">{% trans "start over" %}</a>
+ {% endifmany %}
+ {% trans " - to expand, or dig in by adding more tags and revising the query." %}
+ </p>
+ {% else %}
+ <p class="search-tips">{% trans "Search tip:" %} {% trans "add tags and a query to focus your search" %}</p>
+ {% endif %}
+
+ </div>
+{% endif %}
<div id="listA">
{% include "question_list.html" %}
- {% if searchtitle %}
+ {% comment %}todo: fix css here{% endcomment %}
{% if questions_count == 0 %}
- <p class="evenMore" style="padding-top:30px;text-align:center;">
- {% trans "Did not find anything?" %}
+ {% comment %}todo: add tips to widen selection{% endcomment%}
+ <p class="evenMore" style="padding-top:30px;text-align:center;">
+ {% if scope == "unanswered" %}
+ {% trans "There are no unanswered questions here" %}
+ {% endif %}
+ {% if scope == "favorite" %}
+ {% trans "No favorite questions here. " %}
+ {% trans "Please start (bookmark) some questions when you visit them" %}
+ {% endif %}
+ </p>
+ {% if query or search_tags or author_name %}
+ <p class="evenMore" style="text-align:center">
+ {% trans "You can expand your search by " %}
+ {% ifmany query search_tags author_name %}
+ {% joinitems using ', ' ' or ' %}
+ {% if author_name %}
+ <a href="{% url questions %}?reset_author=true">{% trans "resetting author" %}</a>
+ {% endif %}
+ {% separator %}
+ {% if search_tags %}
+ <a href="{% url questions %}?reset_tags=true">{% trans "resetting tags" %}</a>
+ {% endif %}
+ {% separator %}
+ {% ifmany query search_tags author_name %}
+ <a href="{% url questions %}?start_over=true">{% trans "starting over" %}</a>
+ {% endifmany %}
+ {% endjoinitems %}
+ {% else %}
+ <a href="{% url questions %}?start_over=true">{% trans "starting over" %}</a>
+ {% endifmany %}
+ </p>
+ {% endif %}
+ <p class="evenMore" style="text-align:center">
+ <a href="{% url ask %}">{% trans "Please always feel free to ask your question!" %}</a>
+ </p>
{% else %}
- <p class="evenMore" style="padding-left:9px">
- {% trans "Did not find what you were looking for?" %}
+ <p class="evenMore" style="padding-left:9px">
+ {% trans "Did not find what you were looking for?" %}
+ <a href="{% url ask %}">{% trans "Please, post your question!" %}</a>
+ </p>
{% endif %}
- <a href="{% url ask %}">{% trans "Please, post your question!" %}</a>
- </p>
- {% endif %}
</div>
{% endblock %}
-{% block tail %}
- <div class="pager">{% cnprog_paginator context %}</div>
- <div class="pagesize">{% cnprog_pagesize context %}</div>
-{% endblock %}
+ {% block tail %}
+ {% if questions_count > 10 %}{%comment%}todo: remove magic number{%endcomment%}
+ <div class="pager">{% cnprog_paginator context %}</div>
+ <div class="pagesize">{% cnprog_pagesize context %}</div>
+ {% endif %}
+ {% endblock %}
{% block sidebar %}
-<div class="boxC">
- {% if searchtag %}
- {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num and searchtag as tagname %}have total {{q_num}} questions tagged {{tagname}}{% plural %}have total {{q_num}} questions tagged {{tagname}}{% endblocktrans %}
- {% else %}
- {% if searchtitle %}
- {% if settings.USE_SPHINX_SEARCH %}
- {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} have total {{q_num}} questions containing {{searchtitle}} in full text {% plural %} have total {{q_num}} questions containing {{searchtitle}} in full text {% endblocktrans %}
- {% else %}
- {% blocktrans count questions_count as cnt with questions_count|intcomma as q_num %} have total {{q_num}} questions containing {{searchtitle}} {% plural %} have total {{q_num}} questions containing {{searchtitle}} {% endblocktrans %}
- {% endif %}
- {% else %}
- {% if is_unanswered %}
- {% blocktrans count questions as cnt with questions_count|intcomma as q_num %} have total {{q_num}} unanswered questions {% plural %} have total {{q_num}} unanswered questions {% endblocktrans %}
- {% else %}
- {% blocktrans count questions as cnt with questions_count|intcomma as q_num %} have total {{q_num}} questions {% plural %} have total {{q_num}} questions {% endblocktrans %}
- {% endif %}
- {% endif %}
- {% endif %}
- <p class="nomargin">
- {% ifequal tab_id "latest" %}
- {% trans "latest questions info" %}
- {% endifequal %}
-
- {% ifequal tab_id "active" %}
- {% trans "Questions are sorted by the <strong>time of last update</strong>." %}
- {% trans "Most recently answered ones are shown first." %}
- {% endifequal %}
-
- {% ifequal tab_id "hottest" %}
- {% trans "Questions sorted by <strong>number of responses</strong>." %}
- {% trans "Most answered questions are shown first." %}
- {% endifequal %}
-
- {% ifequal tab_id "mostvoted" %}
- {% trans "Questions are sorted by the <strong>number of votes</strong>." %}
- {% trans "Most voted questions are shown first." %}
- {% endifequal %}
- </p>
-</div>
{% if request.user.is_authenticated %}
{% include "tag_selector.html" %}
{% endif %}
@@ -118,7 +243,7 @@
<h3 class="subtitle">{% trans "Related tags" %}</h3>
<div class="tags">
{% for tag in tags %}
- <a rel="tag" title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{ tag_name }}'{% endblocktrans %}" href="{% url tag_questions tag.name|urlencode %}">{{ tag.name }}</a>
+ <a rel="tag" title="{% blocktrans with tag.name as tag_name %}see questions tagged '{{ tag_name }}'{% endblocktrans %}" href="{% url questions %}?tags={{tag.name|urlencode}}">{{ tag.name }}</a>
<span class="tag-number">&#215; {{ tag.used_count|intcomma }}</span>
<br />
{% endfor %}
diff --git a/forum/skins/default/templates/tag_selector.html b/forum/skins/default/templates/tag_selector.html
index 5e3e2ad8..85b858d2 100644
--- a/forum/skins/default/templates/tag_selector.html
+++ b/forum/skins/default/templates/tag_selector.html
@@ -1,5 +1,6 @@
{% load i18n %}
{% load extra_tags %}
+{% comment %}todo - maybe disable navigation from ignored tags here when "hide" is on - with js?{%endcomment%}
<div id="tagSelector" class="boxC">
<h3 class="subtitle">{% trans "Interesting tags" %}</h3>
<div class="tags interesting marked-tags">
@@ -7,8 +8,8 @@
{% spaceless %}
<span class="deletable-tag" id="interesting-tag-{{tag_name}}">
<a rel="tag"
- title="{% blocktrans with tag as tagname %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
- href="{% url tag_questions tag_name|urlencode %}">{{tag_name}}</a>
+ title="{% blocktrans %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
+ href="{% url questions %}?tags={{tag_name|urlencode}}">{{tag_name}}</a>
<img class="delete-icon"
src="{% media "/media/images/close-small-dark.png" %}"
title="{% blocktrans %}remove '{{tag_name}}' from the list of interesting tags{% endblocktrans %}"/>
@@ -24,8 +25,8 @@
{% spaceless %}
<span class="deletable-tag" id="ignored-tag-{{tag_name}}">
<a rel="tag"
- title="{% blocktrans with tag as tagname %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
- href="{% url tag_questions tag_name|urlencode %}">{{tag_name}}</a>
+ title="{% blocktrans %}see questions tagged '{{ tag_name }}'{% endblocktrans %}"
+ href="{% url questions %}?tags={{tag_name|urlencode}}">{{tag_name}}</a>
<img class="delete-icon"
src="{% media "/media/images/close-small-dark.png" %}"
title="{% blocktrans %}remove '{{tag_name}}' from the list of ignored tags{% endblocktrans %}"/>
diff --git a/forum/skins/default/templates/tags.html b/forum/skins/default/templates/tags.html
index 50f90fb1..6627db32 100644
--- a/forum/skins/default/templates/tags.html
+++ b/forum/skins/default/templates/tags.html
@@ -1,4 +1,4 @@
-{% extends "base_content.html" %}
+{% extends "base.html" %}
<!-- tags.html -->
{% load i18n %}
{% load extra_tags %}
@@ -27,7 +27,7 @@
{% block content %}
<!-- Tabs -->
<div class="tabBar">
- <div class="headQuestions">{% trans "Tag list" %}</div>
+ <div class="headUsers">{% trans "Tag list" %}</div>
<div class="tabsA">
<a id="sort_name" href="{% url tags %}?sort=name" class="off" title="{% trans "sorted alphabetically" %}">{% trans "by name" %}</a>
<a id="sort_used" href="{% url tags %}?sort=used" class="off" title="{% trans "sorted by frequency of tag use" %}">{% trans "by popularity" %}</a>
@@ -36,7 +36,7 @@
<div id="searchtags">
<p>
{% if stag %}
- {% trans "All tags matching query" %} '<span class="darkred"><strong>{{ stag }}</strong></span>' {% trans "all tags - make this empty in english" %}:
+ {% blocktrans %}All tags matching '<span class="darkred"><strong>{{ stag }}</strong></span>'{% endblocktrans %}:
{% endif %}
{% if not tags.object_list %}
<span>{% trans "Nothing found" %}</span>
@@ -46,7 +46,8 @@
<ul class="tagsList tags">
{% for tag in tags.object_list %}
<li>
- <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %}'{{ tag }}'{% trans "using tags" %}" rel="tag">
+ <a href="{% url questions %}?tags={{tag|urlencode}}"
+ title="{% blocktrans %}see questions tagged '{{ tag }}'{% endblocktrans %}" rel="tag">
{{ tag }}
</a>&nbsp;
<span class="tag-number">&#215; {{ tag.used_count|intcomma }}</span>
diff --git a/forum/skins/default/templates/user.html b/forum/skins/default/templates/user.html
index 5931f31c..8fd9e267 100644
--- a/forum/skins/default/templates/user.html
+++ b/forum/skins/default/templates/user.html
@@ -1,4 +1,4 @@
-{% extends "base_content.html" %}
+{% extends "base.html" %}
<!-- user.html -->
{% load extra_tags %}
{% load extra_filters %}
diff --git a/forum/skins/default/templates/user_reputation.html b/forum/skins/default/templates/user_reputation.html
index 954fb44d..f6a33d93 100644
--- a/forum/skins/default/templates/user_reputation.html
+++ b/forum/skins/default/templates/user_reputation.html
@@ -4,6 +4,7 @@
{% load extra_filters %}
{% load humanize %}
{% load i18n %}
+{% load smart_if %}
{% block userjs %}
<script type='text/javascript' src='{% media "/media/js/excanvas.min.js" %}'></script>
<script type='text/javascript' src='{% media "/media/js/jquery.flot.min.js" %}'></script>
@@ -24,7 +25,11 @@
{% block usercontent %}
<div class="karma-summary">
<div id="diagram" class="karma-diagram"></div>
- <h3>{% trans "Change in karma per question or answer" %}</h3>
+ {% if view_user.id == user.id %}
+ <h3>{% trans "Your karma change log." %}</h3>
+ {% else %}
+ <h3>{% blocktrans with view_user.username as user_name %}{{user_name}}'s karma change log{% endblocktrans %}</h3>
+ {% endif %}
<div class="karma-details">
{% for rep in reputation %}
<p>
diff --git a/forum/skins/default/templates/user_stats.html b/forum/skins/default/templates/user_stats.html
index 1f462581..482b1228 100644
--- a/forum/skins/default/templates/user_stats.html
+++ b/forum/skins/default/templates/user_stats.html
@@ -98,7 +98,7 @@
{% for tag in user_tags%}
<a rel="tag"
title="{% blocktrans with tag.name as tag_name %}see other questions with {{view_user}}'s contributions tagged '{{ tag_name }}' {% endblocktrans %}"
- href="{% url tag_questions tag|urlencode %}?user={{view_user.username}}">{{tag.name}}</a>
+ href="{% url questions %}?tags={{tag|urlencode}}&author={{view_user.id}}&start_over=true">{{tag.name}}</a>
<span class="tag-number">&#215; {{ tag.user_tag_usage_count|intcomma }}</span><br/>
{% if forloop.counter|divisibleby:"10" %}
</td>
diff --git a/forum/skins/default/templates/users.html b/forum/skins/default/templates/users.html
index 78715e05..f3ccd6e9 100644
--- a/forum/skins/default/templates/users.html
+++ b/forum/skins/default/templates/users.html
@@ -1,4 +1,4 @@
-{% extends "base_content.html" %}
+{% extends "base.html" %}
<!-- users.html -->
{% load extra_tags %}
{% load humanize %}
diff --git a/forum/skins/default/templates/users_questions.html b/forum/skins/default/templates/users_questions.html
index be6aaf7d..99a7f90c 100644
--- a/forum/skins/default/templates/users_questions.html
+++ b/forum/skins/default/templates/users_questions.html
@@ -31,7 +31,7 @@
{% convert2tagname_list question %}
{% for tag in question.tagnames %}
<!--todo - move trans below to blocktrans -->
- <a href="{% url tag_questions tag|urlencode %}" title="{% trans "see questions tagged" %} '{{ tag }}' {% trans "using tags" %}" rel="tag">{{ tag }}</a>
+ <a href="{% url questions %}?tags={{tag|urlencode}}" title="{% blocktrans %}see questions tagged '{{ tag }}'{% endblocktrans %}" rel="tag">{{ tag }}</a>
{% endfor %}
</div>
<div class="started">
diff --git a/sql_scripts/091111_upgrade_evgeny.sql b/forum/sql_scripts/091111_upgrade_evgeny.sql
index cb76ec3c..cb76ec3c 100644
--- a/sql_scripts/091111_upgrade_evgeny.sql
+++ b/forum/sql_scripts/091111_upgrade_evgeny.sql
diff --git a/sql_scripts/091208_upgrade_evgeny.sql b/forum/sql_scripts/091208_upgrade_evgeny.sql
index d9c4289a..d9c4289a 100644
--- a/sql_scripts/091208_upgrade_evgeny.sql
+++ b/forum/sql_scripts/091208_upgrade_evgeny.sql
diff --git a/sql_scripts/091208_upgrade_evgeny_1.sql b/forum/sql_scripts/091208_upgrade_evgeny_1.sql
index b1b4107f..b1b4107f 100644
--- a/sql_scripts/091208_upgrade_evgeny_1.sql
+++ b/forum/sql_scripts/091208_upgrade_evgeny_1.sql
diff --git a/sql_scripts/100108_upgrade_ef.sql b/forum/sql_scripts/100108_upgrade_ef.sql
index 1c9a5c1c..1c9a5c1c 100644
--- a/sql_scripts/100108_upgrade_ef.sql
+++ b/forum/sql_scripts/100108_upgrade_ef.sql
diff --git a/sql_scripts/badges.sql b/forum/sql_scripts/badges.sql
index 5fd03d18..5fd03d18 100644
--- a/sql_scripts/badges.sql
+++ b/forum/sql_scripts/badges.sql
diff --git a/sql_scripts/cnprog.xml b/forum/sql_scripts/cnprog.xml
index 95f9b362..95f9b362 100644
--- a/sql_scripts/cnprog.xml
+++ b/forum/sql_scripts/cnprog.xml
diff --git a/sql_scripts/cnprog_new_install.sql b/forum/sql_scripts/cnprog_new_install.sql
index ac33a6ba..ac33a6ba 100644
--- a/sql_scripts/cnprog_new_install.sql
+++ b/forum/sql_scripts/cnprog_new_install.sql
diff --git a/sql_scripts/cnprog_new_install_2009_02_28.sql b/forum/sql_scripts/cnprog_new_install_2009_02_28.sql
index 80b9fced..80b9fced 100644
--- a/sql_scripts/cnprog_new_install_2009_02_28.sql
+++ b/forum/sql_scripts/cnprog_new_install_2009_02_28.sql
diff --git a/sql_scripts/cnprog_new_install_2009_03_31.sql b/forum/sql_scripts/cnprog_new_install_2009_03_31.sql
index c2c69f36..c2c69f36 100644
--- a/sql_scripts/cnprog_new_install_2009_03_31.sql
+++ b/forum/sql_scripts/cnprog_new_install_2009_03_31.sql
diff --git a/sql_scripts/cnprog_new_install_2009_04_07.sql b/forum/sql_scripts/cnprog_new_install_2009_04_07.sql
index ff9016fa..ff9016fa 100644
--- a/sql_scripts/cnprog_new_install_2009_04_07.sql
+++ b/forum/sql_scripts/cnprog_new_install_2009_04_07.sql
diff --git a/sql_scripts/cnprog_new_install_2009_04_09.sql b/forum/sql_scripts/cnprog_new_install_2009_04_09.sql
index f4424852..f4424852 100644
--- a/sql_scripts/cnprog_new_install_2009_04_09.sql
+++ b/forum/sql_scripts/cnprog_new_install_2009_04_09.sql
diff --git a/sql_scripts/drop-all-tables.sh b/forum/sql_scripts/drop-all-tables.sh
index 1e55cb1f..1e55cb1f 100644
--- a/sql_scripts/drop-all-tables.sh
+++ b/forum/sql_scripts/drop-all-tables.sh
diff --git a/sql_scripts/drop-auth.sql b/forum/sql_scripts/drop-auth.sql
index bc17dce3..bc17dce3 100644
--- a/sql_scripts/drop-auth.sql
+++ b/forum/sql_scripts/drop-auth.sql
diff --git a/sql_scripts/pg_fts_install.sql b/forum/sql_scripts/pg_fts_install.sql
index d0655134..d0655134 100644
--- a/sql_scripts/pg_fts_install.sql
+++ b/forum/sql_scripts/pg_fts_install.sql
diff --git a/sql_scripts/update_2009_01_13_001.sql b/forum/sql_scripts/update_2009_01_13_001.sql
index 165d1125..165d1125 100644
--- a/sql_scripts/update_2009_01_13_001.sql
+++ b/forum/sql_scripts/update_2009_01_13_001.sql
diff --git a/sql_scripts/update_2009_01_13_002.sql b/forum/sql_scripts/update_2009_01_13_002.sql
index c223cb8c..c223cb8c 100644
--- a/sql_scripts/update_2009_01_13_002.sql
+++ b/forum/sql_scripts/update_2009_01_13_002.sql
diff --git a/sql_scripts/update_2009_01_18_001.sql b/forum/sql_scripts/update_2009_01_18_001.sql
index 6f29fa32..6f29fa32 100644
--- a/sql_scripts/update_2009_01_18_001.sql
+++ b/forum/sql_scripts/update_2009_01_18_001.sql
diff --git a/sql_scripts/update_2009_01_24.sql b/forum/sql_scripts/update_2009_01_24.sql
index 45b83935..45b83935 100644
--- a/sql_scripts/update_2009_01_24.sql
+++ b/forum/sql_scripts/update_2009_01_24.sql
diff --git a/sql_scripts/update_2009_01_25_001.sql b/forum/sql_scripts/update_2009_01_25_001.sql
index 16c3487b..16c3487b 100644
--- a/sql_scripts/update_2009_01_25_001.sql
+++ b/forum/sql_scripts/update_2009_01_25_001.sql
diff --git a/sql_scripts/update_2009_02_26_001.sql b/forum/sql_scripts/update_2009_02_26_001.sql
index a6af5931..a6af5931 100644
--- a/sql_scripts/update_2009_02_26_001.sql
+++ b/forum/sql_scripts/update_2009_02_26_001.sql
diff --git a/sql_scripts/update_2009_04_10_001.sql b/forum/sql_scripts/update_2009_04_10_001.sql
index 8148632a..8148632a 100644
--- a/sql_scripts/update_2009_04_10_001.sql
+++ b/forum/sql_scripts/update_2009_04_10_001.sql
diff --git a/sql_scripts/update_2009_07_05_EF.sql b/forum/sql_scripts/update_2009_07_05_EF.sql
index 43c7c2f0..43c7c2f0 100644
--- a/sql_scripts/update_2009_07_05_EF.sql
+++ b/forum/sql_scripts/update_2009_07_05_EF.sql
diff --git a/sql_scripts/update_2009_12_24_001.sql b/forum/sql_scripts/update_2009_12_24_001.sql
index 3d082c2f..3d082c2f 100644
--- a/sql_scripts/update_2009_12_24_001.sql
+++ b/forum/sql_scripts/update_2009_12_24_001.sql
diff --git a/sql_scripts/update_2009_12_27_001.sql b/forum/sql_scripts/update_2009_12_27_001.sql
index e2da7d4d..e2da7d4d 100644
--- a/sql_scripts/update_2009_12_27_001.sql
+++ b/forum/sql_scripts/update_2009_12_27_001.sql
diff --git a/sql_scripts/update_2009_12_27_002.sql b/forum/sql_scripts/update_2009_12_27_002.sql
index a36470bf..a36470bf 100644
--- a/sql_scripts/update_2009_12_27_002.sql
+++ b/forum/sql_scripts/update_2009_12_27_002.sql
diff --git a/sql_scripts/update_2010_01_23.sql b/forum/sql_scripts/update_2010_01_23.sql
index 621207be..621207be 100755
--- a/sql_scripts/update_2010_01_23.sql
+++ b/forum/sql_scripts/update_2010_01_23.sql
diff --git a/sql_scripts/update_2010_02_22.sql b/forum/sql_scripts/update_2010_02_22.sql
index 2778885a..2778885a 100644
--- a/sql_scripts/update_2010_02_22.sql
+++ b/forum/sql_scripts/update_2010_02_22.sql
diff --git a/forum/templatetags/extra_tags.py b/forum/templatetags/extra_tags.py
index 382d19f0..83aeb4c7 100755
--- a/forum/templatetags/extra_tags.py
+++ b/forum/templatetags/extra_tags.py
@@ -304,8 +304,12 @@ class ItemSeparatorNode(template.Node):
return self.content
class JoinItemListNode(template.Node):
- def __init__(self,separator=ItemSeparatorNode("''"), items=()):
+ def __init__(self,separator=ItemSeparatorNode("''"), last_separator=None, items=()):
self.separator = separator
+ if last_separator:
+ self.last_separator = last_separator
+ else:
+ self.last_separator = separator
self.items = items
def render(self,context):
out = []
@@ -314,16 +318,34 @@ class JoinItemListNode(template.Node):
bit = item.render(context)
if not empty_re.search(bit):
out.append(bit)
- return self.separator.render(context).join(out)
+ if len(out) == 1:
+ return out[0]
+ if len(out) > 1:
+ last = out.pop()
+ all_but_last = self.separator.render(context).join(out)
+ return self.last_separator.render(context).join((all_but_last,last))
+ else:
+ assert(len(out)==0)
+ return ''
@register.tag(name="joinitems")
def joinitems(parser,token):
try:
- tagname,junk,sep_token = token.split_contents()
- except ValueError:
- raise template.TemplateSyntaxError("joinitems tag requires 'using \"separator html\"' parameters")
+ tagname, junk, sep_token = token.split_contents()
+ last_sep_token = None
+ except:
+ try:
+ tagname, junk, sep_token, last_sep_token = token.split_contents()
+ except:
+ raise template.TemplateSyntaxError('incorrect usage of joinitems tag first param '
+ 'must be \'using\' second - separator and '
+ 'optional third - last item separator')
if junk == 'using':
sep_node = ItemSeparatorNode(sep_token)
+ if last_sep_token:
+ last_sep_node = ItemSeparatorNode(last_sep_token)
+ else:
+ last_sep_node = None
else:
raise template.TemplateSyntaxError("joinitems tag requires 'using \"separator html\"' parameters")
nodelist = []
@@ -333,7 +355,7 @@ def joinitems(parser,token):
if next.contents == 'endjoinitems':
break
- return JoinItemListNode(separator=sep_node,items=nodelist)
+ return JoinItemListNode(separator=sep_node,last_separator=last_sep_node,items=nodelist)
class BlockMediaUrlNode(template.Node):
def __init__(self,nodelist):
@@ -436,3 +458,46 @@ def question_counter_widget(question):
#returns a dictionary with keys like 'votes_bg', etc
return locals()
+class IsManyNode(template.Node):
+ def __init__(self, test_items, true_nodelist, false_nodelist):
+ self.true_nodelist = true_nodelist
+ self.false_nodelist = false_nodelist
+ self.test_items = test_items
+ def render(self, context):
+ maybe = False
+ for item in self.test_items:
+ is_good = item.resolve(context)
+ if maybe == True and is_good:
+ return self.true_nodelist.render(context)
+ if is_good:
+ maybe = True
+ return self.false_nodelist.render(context)
+
+@register.tag(name='ifmany')
+def ifmany(parser,token):
+ """usage {% ifmany item1 item2 item3 ... itemN %} stuff {% endifmany %}
+ returns content included into the tag if more than one
+ item evaluates to Tru'ish value - that's the idea
+ {% else %} is not supported yet
+ """
+
+ bits = list(token.split_contents())
+ start_tag = bits.pop(0)
+
+ test_items = []
+ for bit in bits:
+ item = parser.compile_filter(bit)
+ test_items.append(item)
+
+ end_tag = 'end' + start_tag
+ else_tag = 'else'
+ true_nodelist = parser.parse((end_tag,else_tag,))
+ token = parser.next_token()
+ if token.contents == else_tag:
+ false_nodelist = parser.parse((end_tag,))
+ token = parser.next_token()
+ else:
+ false_nodelist = template.NodeList()
+
+
+ return IsManyNode(test_items, true_nodelist, false_nodelist)
diff --git a/forum/utils/decorators.py b/forum/utils/decorators.py
index e4e7acb3..440e8312 100755
--- a/forum/utils/decorators.py
+++ b/forum/utils/decorators.py
@@ -22,4 +22,3 @@ def ajax_method(view_func):
json = simplejson.dumps(retval)
return HttpResponse(json,mimetype='application/json')
return wrap
-
diff --git a/forum/views/readers.py b/forum/views/readers.py
index 3f0bef0f..89a9550b 100644
--- a/forum/views/readers.py
+++ b/forum/views/readers.py
@@ -13,7 +13,6 @@ from django.db.models import Q
from django.utils.translation import ugettext as _
from django.template.defaultfilters import slugify
from django.core.urlresolvers import reverse
-from django.utils.datastructures import SortedDict
from django.views.decorators.cache import cache_page
from forum.utils.html import sanitize_html
@@ -24,8 +23,10 @@ from forum.forms import *
from forum.models import *
from forum.auth import *
from forum.const import *
+from forum import const
from forum import auth
from forum.utils.forms import get_next_url
+from forum.search.state_manager import SearchState
# used in index page
#refactor - move these numbers somewhere?
@@ -35,7 +36,6 @@ INDEX_TAGS_SIZE = 25
# used in tags list
DEFAULT_PAGE_SIZE = 60
# used in questions
-QUESTIONS_PAGE_SIZE = 30
# used in answers
ANSWERS_PAGE_SIZE = 10
@@ -54,24 +54,6 @@ def _get_tags_cache_json():#service routine used by views requiring tag list in
tags = simplejson.dumps(tags_list)
return tags
-def _get_and_remember_questions_sort_method(request, view_dic, default):#service routine used by q listing views and question view
- """manages persistence of post sort order
- it is assumed that when user wants newest question -
- then he/she wants newest answers as well, etc.
- how far should this assumption actually go - may be a good question
- """
- if default not in view_dic:
- raise Exception('default value must be in view_dic')
-
- q_sort_method = request.REQUEST.get('sort', None)
- if q_sort_method == None:
- q_sort_method = request.session.get('questions_sort_method', default)
-
- if q_sort_method not in view_dic:
- q_sort_method = default
- request.session['questions_sort_method'] = q_sort_method
- return q_sort_method, view_dic[q_sort_method]
-
#refactor? - we have these
#views that generate a listing of questions in one way or another:
#index, unanswered, questions, search, tag
@@ -81,280 +63,122 @@ def _get_and_remember_questions_sort_method(request, view_dic, default):#service
def index(request):#generates front page - shows listing of questions sorted in various ways
"""index view mapped to the root url of the Q&A site
"""
- view_dic = {
- "latest":"-last_activity_at",
- "hottest":"-answer_count",
- "mostvoted":"-score",
- }
- view_id, orderby = _get_and_remember_questions_sort_method(request, view_dic, 'latest')
-
- pagesize = request.session.get("pagesize",QUESTIONS_PAGE_SIZE)
- try:
- page = int(request.GET.get('page', '1'))
- except ValueError:
- page = 1
-
- qs = Question.objects.exclude(deleted=True).order_by(orderby)
-
- objects_list = Paginator(qs, pagesize)
- questions = objects_list.page(page)
-
- # RISK - inner join queries
- #questions = questions.select_related()
- tags = Tag.objects.get_valid_tags(INDEX_TAGS_SIZE)
-
- awards = Award.objects.get_recent_awards()
-
- (interesting_tag_names, ignored_tag_names) = (None, None)
- if request.user.is_authenticated():
- pt = MarkedTag.objects.filter(user=request.user)
- interesting_tag_names = pt.filter(reason='good').values_list('tag__name', flat=True)
- ignored_tag_names = pt.filter(reason='bad').values_list('tag__name', flat=True)
-
- tags_autocomplete = _get_tags_cache_json()
-
- return render_to_response('index.html', {
- 'interesting_tag_names': interesting_tag_names,
- 'tags_autocomplete': tags_autocomplete,
- 'ignored_tag_names': ignored_tag_names,
- "questions" : questions,
- "tab_id" : view_id,
- "tags" : tags,
- "awards" : awards[:INDEX_AWARD_SIZE],
- "context" : {
- 'is_paginated' : True,
- 'pages': objects_list.num_pages,
- 'page': page,
- 'has_previous': questions.has_previous(),
- 'has_next': questions.has_next(),
- 'previous': questions.previous_page_number(),
- 'next': questions.next_page_number(),
- 'base_url' : request.path + '?sort=%s&' % view_id,
- 'pagesize' : pagesize
- }}, context_instance=RequestContext(request))
+ return HttpResponseRedirect(reverse('questions'))
+#todo: eliminate this from urls
def unanswered(request):#generates listing of unanswered questions
return questions(request, unanswered=True)
-def questions(request, tagname=None, unanswered=False):#a view generating listing of questions, used by 'unanswered' too
+def questions(request):#a view generating listing of questions, used by 'unanswered' too
"""
List of Questions, Tagged questions, and Unanswered questions.
"""
- # template file
- # "questions.html" or maybe index.html in the future
- template_file = "questions.html"
- # Set flag to False by default. If it is equal to True, then need to be saved.
- pagesize_changed = False
- # get pagesize from session, if failed then get default value
- pagesize = request.session.get("pagesize",QUESTIONS_PAGE_SIZE)
- try:
- page = int(request.GET.get('page', '1'))
- except ValueError:
- page = 1
- view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" }
- view_id, orderby = _get_and_remember_questions_sort_method(request,view_dic,'latest')
-
- # check if request is from tagged questions
- qs = Question.objects.exclude(deleted=True)
+ #don't allow to post to this view
+ if request.method == 'POST':
+ raise Http404
- if tagname is not None:
- qs = qs.filter(tags__name = unquote(tagname))
+ #todo: redo SearchState to accept input from
+ #view_log, session and request parameters
+ search_state = request.session.get('search_state', SearchState())
- if unanswered:
- qs = qs.exclude(answer_accepted=True)
+ view_log = request.session['view_log']
- author_name = None
- #user contributed questions & answers
- if 'user' in request.GET:
- try:
- author_name = request.GET['user']
- u = User.objects.get(username=author_name)
- qs = qs.filter(Q(author=u) | Q(answers__author=u))
- except User.DoesNotExist:
- author_name = None
+ if view_log.get_previous(1) != 'questions':
+ if view_log.get_previous(2) != 'questions':
+ #print 'user stepped too far, resetting search state'
+ search_state.reset()
if request.user.is_authenticated():
- uid_str = str(request.user.id)
- qs = qs.extra(
- select = SortedDict([
- (
- 'interesting_score',
- 'SELECT COUNT(1) FROM forum_markedtag, question_tags '
- + 'WHERE forum_markedtag.user_id = %s '
- + 'AND forum_markedtag.tag_id = question_tags.tag_id '
- + 'AND forum_markedtag.reason = \'good\' '
- + 'AND question_tags.question_id = question.id'
- ),
- ]),
- select_params = (uid_str,),
- )
- if request.user.hide_ignored_questions:
- ignored_tags = Tag.objects.filter(user_selections__reason='bad',
- user_selections__user = request.user)
- qs = qs.exclude(tags__in=ignored_tags)
- else:
- qs = qs.extra(
- select = SortedDict([
- (
- 'ignored_score',
- 'SELECT COUNT(1) FROM forum_markedtag, question_tags '
- + 'WHERE forum_markedtag.user_id = %s '
- + 'AND forum_markedtag.tag_id = question_tags.tag_id '
- + 'AND forum_markedtag.reason = \'bad\' '
- + 'AND question_tags.question_id = question.id'
- )
- ]),
- select_params = (uid_str, )
- )
-
- qs = qs.select_related(depth=1).order_by(orderby)
-
- objects_list = Paginator(qs, pagesize)
- questions = objects_list.page(page)
-
- # Get related tags from this page objects
- if questions.object_list.count() > 0:
- related_tags = Tag.objects.get_tags_by_questions(questions.object_list)
- else:
- related_tags = None
- tags_autocomplete = _get_tags_cache_json()
+ search_state.set_logged_in()
+
+ form = AdvancedSearchForm(request.GET)
+ #todo: form is used only for validation...
+ if form.is_valid():
+ search_state.update_from_user_input(
+ form.cleaned_data,
+ request.GET,
+ )
+ #todo: better put these in separately then analyze
+ #what neesd to be done, otherwise there are two routines
+ #that take request.GET I don't like this use of parameters
+ #another weakness is that order of routine calls matters here
+ search_state.relax_stickiness( request.GET, view_log )
+
+ request.session['search_state'] = search_state
+ request.session.modified = True
+
+ #force reset for debugging
+ #search_state.reset()
+ #request.session.modified = True
+
+ #have this call implemented for sphinx, mysql and pgsql
+ (qs, meta_data) = Question.objects.run_advanced_search(
+ request_user = request.user,
+ scope_selector = search_state.scope,#unanswered/all/favorite (for logged in)
+ search_query = search_state.query,
+ tag_selector = search_state.tags,
+ author_selector = search_state.author,
+ sort_method = search_state.sort
+ )
+
+ objects_list = Paginator(qs, search_state.page_size)
+ questions = objects_list.page(search_state.page)
+
+ #todo maybe do this search on query the set instead
+ related_tags = Tag.objects.get_tags_by_questions(questions.object_list)
- # get the list of interesting and ignored tags
- (interesting_tag_names, ignored_tag_names) = (None, None)
- if request.user.is_authenticated():
- pt = MarkedTag.objects.filter(user=request.user)
- interesting_tag_names = pt.filter(reason='good').values_list('tag__name', flat=True)
- ignored_tag_names = pt.filter(reason='bad').values_list('tag__name', flat=True)
+ tags_autocomplete = _get_tags_cache_json()
- return render_to_response(template_file, {
- "questions" : questions,
- "author_name" : author_name,
- "tab_id" : view_id,
- "questions_count" : objects_list.count,
- "tags" : related_tags,
- "tags_autocomplete" : tags_autocomplete,
- "searchtag" : tagname,
- "is_unanswered" : unanswered,
- "interesting_tag_names": interesting_tag_names,
- 'ignored_tag_names': ignored_tag_names,
- "context" : {
+ #todo!!!!
+ #contributors = #User.objects.get_related_to_questions
+
+ #todo: organize variables by type
+ return render_to_response('questions.html', {
+ 'questions' : questions,
+ 'author_name' : meta_data.get('author_name',None),
+ 'tab_id' : search_state.sort,
+ 'questions_count' : objects_list.count,
+ 'tags' : related_tags,
+ 'query': search_state.query,
+ 'search_tags' : search_state.tags,
+ 'tags_autocomplete' : tags_autocomplete,
+ 'is_unanswered' : False,#remove this from template
+ 'interesting_tag_names': meta_data.get('interesting_tag_names',None),
+ 'ignored_tag_names': meta_data.get('ignored_tag_names',None),
+ 'sort': search_state.sort,
+ 'scope': search_state.scope,
+ 'context' : {
'is_paginated' : True,
'pages': objects_list.num_pages,
- 'page': page,
+ 'page': search_state.page,
'has_previous': questions.has_previous(),
'has_next': questions.has_next(),
'previous': questions.previous_page_number(),
'next': questions.next_page_number(),
- 'base_url' : request.path + '?sort=%s&' % view_id,
- 'pagesize' : pagesize
+ 'base_url' : request.path + '?sort=%s&' % search_state.sort,#todo in T sort=>sort_method
+ 'pagesize' : search_state.page_size,#todo in T pagesize -> page_size
}}, context_instance=RequestContext(request))
def search(request): #generates listing of questions matching a search query - including tags and just words
- """generates listing of questions matching a search query
- supports full text search in mysql db using sphinx and internally in postgresql
- falls back on simple partial string matching approach if
- full text search function is not available
+ """redirects to people and tag search pages
+ todo: eliminate this altogether and instead make
+ search "tab" sensitive automatically - the radio-buttons
+ are useless under the search bar
"""
if request.method == "GET":
- keywords = request.GET.get("q")
- search_type = request.GET.get("t")
+ search_type = request.GET.get('t')
+ query = request.GET.get('query')
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
- if keywords is None:
- return HttpResponseRedirect(reverse(index))
if search_type == 'tag':
- return HttpResponseRedirect(reverse('tags') + '?q=%s&page=%s' % (keywords.strip(), page))
- elif search_type == "user":
- return HttpResponseRedirect(reverse('users') + '?q=%s&page=%s' % (keywords.strip(), page))
- elif search_type == "question":
-
- template_file = "questions.html"
- # Set flag to False by default. If it is equal to True, then need to be saved.
- pagesize_changed = False
- # get pagesize from session, if failed then get default value
- user_page_size = request.session.get("pagesize", QUESTIONS_PAGE_SIZE)
- # set pagesize equal to logon user specified value in database
- if request.user.is_authenticated() and request.user.questions_per_page > 0:
- user_page_size = request.user.questions_per_page
-
- try:
- page = int(request.GET.get('page', '1'))
- # get new pagesize from UI selection
- pagesize = int(request.GET.get('pagesize', user_page_size))
- if pagesize <> user_page_size:
- pagesize_changed = True
-
- except ValueError:
- page = 1
- pagesize = user_page_size
-
- # save this pagesize to user database
- if pagesize_changed:
- request.session["pagesize"] = pagesize
- if request.user.is_authenticated():
- user = request.user
- user.questions_per_page = pagesize
- user.save()
-
- view_id = request.GET.get('sort', None)
- view_dic = {"latest":"-added_at", "active":"-last_activity_at", "hottest":"-answer_count", "mostvoted":"-score" }
- try:
- orderby = view_dic[view_id]
- except KeyError:
- view_id = "latest"
- orderby = "-added_at"
-
- def question_search(keywords, orderby):
- objects = Question.objects.filter(deleted=False).extra(where=['title like %s'], params=['%' + keywords + '%']).order_by(orderby)
- # RISK - inner join queries
- return objects.select_related();
-
- from forum.modules import get_handler
-
- question_search = get_handler('question_search', question_search)
-
- objects = question_search(keywords, orderby)
-
- objects_list = Paginator(objects, pagesize)
- questions = objects_list.page(page)
-
- # Get related tags from this page objects
- related_tags = []
- for question in questions.object_list:
- tags = list(question.tags.all())
- for tag in tags:
- if tag not in related_tags:
- related_tags.append(tag)
-
- #if is_search is true in the context, prepend this string to soting tabs urls
- search_uri = "?q=%s&page=%d&t=question" % ("+".join(keywords.split()), page)
-
- return render_to_response(template_file, {
- "questions" : questions,
- "tab_id" : view_id,
- "questions_count" : objects_list.count,
- "tags" : related_tags,
- "searchtag" : None,
- "searchtitle" : keywords,
- "keywords" : keywords,
- "is_unanswered" : False,
- "is_search": True,
- "search_uri": search_uri,
- "context" : {
- 'is_paginated' : True,
- 'pages': objects_list.num_pages,
- 'page': page,
- 'has_previous': questions.has_previous(),
- 'has_next': questions.has_next(),
- 'previous': questions.previous_page_number(),
- 'next': questions.next_page_number(),
- 'base_url' : request.path + '?t=question&q=%s&sort=%s&' % (keywords, view_id),
- 'pagesize' : pagesize
- }}, context_instance=RequestContext(request))
-
+ return HttpResponseRedirect(reverse('tags') + '?q=%s&page=%s' % (query.strip(), page))
+ elif search_type == 'user':
+ return HttpResponseRedirect(reverse('users') + '?q=%s&page=%s' % (query.strip(), page))
+ else:
+ raise Http404
else:
raise Http404
@@ -386,6 +210,7 @@ def tags(request):#view showing a listing of available tags - plain list
tags = objects_list.page(objects_list.num_pages)
return render_to_response('tags.html', {
+ "active_tab": "tags",
"tags" : tags,
"stag" : stag,
"tab_id" : sortby,
diff --git a/forum/views/users.py b/forum/views/users.py
index 705bbbb0..113c46e6 100755
--- a/forum/views/users.py
+++ b/forum/views/users.py
@@ -17,6 +17,7 @@ from forum import auth
import calendar
from django.contrib.contenttypes.models import ContentType
from forum.models import user_updated
+from forum.const import USERS_PAGE_SIZE
from django.conf import settings
question_type = ContentType.objects.get_for_model(Question)
@@ -32,8 +33,6 @@ question_revision_type_id = question_revision_type.id
answer_revision_type_id = answer_revision_type.id
repute_type_id = repute_type.id
-USERS_PAGE_SIZE = 35# refactor - move to some constants file
-
def users(request):
is_paginated = True
sortby = request.GET.get('sort', 'reputation')
@@ -65,11 +64,12 @@ def users(request):
users = objects_list.page(objects_list.num_pages)
return render_to_response('users.html', {
- "users" : users,
- "suser" : suser,
- "keywords" : suser,
- "tab_id" : sortby,
- "context" : {
+ 'active_tab': 'users',
+ 'users' : users,
+ 'suser' : suser,
+ 'keywords' : suser,
+ 'tab_id' : sortby,
+ 'context' : {
'is_paginated' : is_paginated,
'pages': objects_list.num_pages,
'page': page,
@@ -124,6 +124,7 @@ def edit_user(request, id):
if settings.EDITABLE_SCREEN_NAME:
user.username = sanitize_html(form.cleaned_data['username'])
+
user.real_name = sanitize_html(form.cleaned_data['realname'])
user.website = sanitize_html(form.cleaned_data['website'])
user.location = sanitize_html(form.cleaned_data['city'])
diff --git a/forum/views/writers.py b/forum/views/writers.py
index b9b1aad5..57c8e043 100755
--- a/forum/views/writers.py
+++ b/forum/views/writers.py
@@ -132,9 +132,18 @@ def ask(request):#view used to ask a new question
return HttpResponseRedirect(reverse('user_signin_new_question'))
else:
form = AskForm()
+ if 'title' in request.GET:
+ raw_title = request.GET['title']
+ form.initial['title'] = strip_tags(strip_entities(raw_title))
+ else:
+ search_state = request.session.get('search_state',None)
+ if search_state:
+ query = search_state.query
+ form.initial['title'] = query
tags = _get_tags_cache_json()
return render_to_response('ask.html', {
+ 'active_tab': 'ask',
'form' : form,
'tags' : tags,
'email_validation_faq_url':reverse('faq') + '#validate',
@@ -318,7 +327,6 @@ def __generate_comments_json(obj, type, user):#non-view generates json data for
data = simplejson.dumps(json_comments)
return HttpResponse(data, mimetype="application/json")
-
def question_comments(request, id):#ajax handler for loading comments to question
question = get_object_or_404(Question, id=id)
user = request.user
diff --git a/forum_modules/pgfulltext/DISABLED b/forum_modules/pgfulltext/DISABLED
index e69de29b..e69de29b 100755..100644
--- a/forum_modules/pgfulltext/DISABLED
+++ b/forum_modules/pgfulltext/DISABLED
diff --git a/forum_modules/pgfulltext/__init__.py b/forum_modules/pgfulltext/__init__.py
index 8215e1a9..8215e1a9 100755..100644
--- a/forum_modules/pgfulltext/__init__.py
+++ b/forum_modules/pgfulltext/__init__.py
diff --git a/forum_modules/pgfulltext/handlers.py b/forum_modules/pgfulltext/handlers.py
index f4a7a3b2..f4a7a3b2 100755..100644
--- a/forum_modules/pgfulltext/handlers.py
+++ b/forum_modules/pgfulltext/handlers.py
diff --git a/forum_modules/pgfulltext/management.py b/forum_modules/pgfulltext/management.py
index 15ba3bd7..15ba3bd7 100755..100644
--- a/forum_modules/pgfulltext/management.py
+++ b/forum_modules/pgfulltext/management.py
diff --git a/forum_modules/pgfulltext/pg_fts_install.sql b/forum_modules/pgfulltext/pg_fts_install.sql
index 72eca516..72eca516 100755..100644
--- a/forum_modules/pgfulltext/pg_fts_install.sql
+++ b/forum_modules/pgfulltext/pg_fts_install.sql
diff --git a/forum_modules/sphinxfulltext/DISABLED b/forum_modules/sphinxfulltext/DISABLED
index e69de29b..e69de29b 100755..100644
--- a/forum_modules/sphinxfulltext/DISABLED
+++ b/forum_modules/sphinxfulltext/DISABLED
diff --git a/forum_modules/sphinxfulltext/__init__.py b/forum_modules/sphinxfulltext/__init__.py
index e69de29b..e69de29b 100755..100644
--- a/forum_modules/sphinxfulltext/__init__.py
+++ b/forum_modules/sphinxfulltext/__init__.py
diff --git a/forum_modules/sphinxfulltext/dependencies.py b/forum_modules/sphinxfulltext/dependencies.py
index 046ebfc5..046ebfc5 100755..100644
--- a/forum_modules/sphinxfulltext/dependencies.py
+++ b/forum_modules/sphinxfulltext/dependencies.py
diff --git a/forum_modules/sphinxfulltext/handlers.py b/forum_modules/sphinxfulltext/handlers.py
index 226acf72..226acf72 100755..100644
--- a/forum_modules/sphinxfulltext/handlers.py
+++ b/forum_modules/sphinxfulltext/handlers.py
diff --git a/forum_modules/sphinxfulltext/models.py b/forum_modules/sphinxfulltext/models.py
index a188728d..a188728d 100755..100644
--- a/forum_modules/sphinxfulltext/models.py
+++ b/forum_modules/sphinxfulltext/models.py
diff --git a/forum_modules/sphinxfulltext/settings.py b/forum_modules/sphinxfulltext/settings.py
index 564404c6..564404c6 100755..100644
--- a/forum_modules/sphinxfulltext/settings.py
+++ b/forum_modules/sphinxfulltext/settings.py
diff --git a/locale/en/LC_MESSAGES/django.mo b/locale/en/LC_MESSAGES/django.mo
index 65af2080..cac204e1 100644
--- a/locale/en/LC_MESSAGES/django.mo
+++ b/locale/en/LC_MESSAGES/django.mo
Binary files differ
diff --git a/locale/en/LC_MESSAGES/django.po b/locale/en/LC_MESSAGES/django.po
index 23e1d410..e773b46f 100644
--- a/locale/en/LC_MESSAGES/django.po
+++ b/locale/en/LC_MESSAGES/django.po
@@ -1690,7 +1690,7 @@ msgstr ""
#: forum/skins/default/templates/header.html:29
#: forum/skins/default/templates/header.html:57
msgid "users"
-msgstr ""
+msgstr "people"
#: forum/skins/default/templates/header.html:31
msgid "books"
diff --git a/locale/ru/LC_MESSAGES/django.mo b/locale/ru/LC_MESSAGES/django.mo
new file mode 100644
index 00000000..c2241644
--- /dev/null
+++ b/locale/ru/LC_MESSAGES/django.mo
Binary files differ
diff --git a/locale/ru/LC_MESSAGES/django.po b/locale/ru/LC_MESSAGES/django.po
new file mode 100644
index 00000000..8fc6c6c0
--- /dev/null
+++ b/locale/ru/LC_MESSAGES/django.po
@@ -0,0 +1,3600 @@
+# Russian translation of messages for Askbot
+# Copyright (C) 2009 Gang Chen
+# This file is distributed under the same license as the Askbot package.
+# FIRST AUTHOR <evgeny.fadeev@gmail.com>, 2010.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-04-22 03:56-0400\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
+"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n"
+
+#: django_authopenid/forms.py:71 django_authopenid/views.py:132
+msgid "i-names are not supported"
+msgstr ""
+
+#: django_authopenid/forms.py:134
+msgid "Account with this name already exists on the forum"
+msgstr ""
+
+#: django_authopenid/forms.py:135
+msgid "can't have two logins to the same account yet, sorry."
+msgstr ""
+
+#: django_authopenid/forms.py:157
+msgid "Please enter valid username and password (both are case-sensitive)."
+msgstr ""
+
+#: django_authopenid/forms.py:160 django_authopenid/forms.py:210
+msgid "This account is inactive."
+msgstr ""
+
+#: django_authopenid/forms.py:162
+msgid "Login failed."
+msgstr ""
+
+#: django_authopenid/forms.py:164
+msgid "Please enter username and password"
+msgstr ""
+
+#: django_authopenid/forms.py:166
+msgid "Please enter your password"
+msgstr ""
+
+#: django_authopenid/forms.py:168
+msgid "Please enter user name"
+msgstr ""
+
+#: django_authopenid/forms.py:206
+msgid ""
+"Please enter a valid username and password. Note that "
+"both fields are case-sensitive."
+msgstr ""
+
+#: django_authopenid/forms.py:229 forum/authentication/forms.py:60
+msgid "Current password"
+msgstr ""
+
+#: django_authopenid/forms.py:240 forum/authentication/forms.py:71
+msgid ""
+"Old password is incorrect. Please enter the correct "
+"password."
+msgstr ""
+
+#: django_authopenid/forms.py:305
+msgid "Your user name (<i>required</i>)"
+msgstr ""
+
+#: django_authopenid/forms.py:320
+msgid "Incorrect username."
+msgstr ""
+
+#: django_authopenid/urls.py:23 django_authopenid/urls.py:24
+#: django_authopenid/urls.py:25 django_authopenid/urls.py:27
+#: fbconnect/urls.py:12 fbconnect/urls.py:13 fbconnect/urls.py:14
+msgid "signin/"
+msgstr ""
+
+#: django_authopenid/urls.py:24 fbconnect/urls.py:13 fbconnect/urls.py:17
+msgid "newquestion/"
+msgstr ""
+
+#: django_authopenid/urls.py:25 fbconnect/urls.py:14 fbconnect/urls.py:18
+msgid "newanswer/"
+msgstr ""
+
+#: django_authopenid/urls.py:26
+msgid "signout/"
+msgstr ""
+
+#: django_authopenid/urls.py:27
+msgid "complete/"
+msgstr ""
+
+#: django_authopenid/urls.py:29 fbconnect/urls.py:16 fbconnect/urls.py:17
+#: fbconnect/urls.py:18
+msgid "register/"
+msgstr ""
+
+#: django_authopenid/urls.py:30
+msgid "signup/"
+msgstr ""
+
+#: django_authopenid/urls.py:32
+msgid "sendpw/"
+msgstr ""
+
+#: django_authopenid/urls.py:33 django_authopenid/urls.py:37
+msgid "password/"
+msgstr ""
+
+#: django_authopenid/urls.py:33
+msgid "confirm/"
+msgstr ""
+
+#: django_authopenid/urls.py:36
+msgid "account_settings"
+msgstr ""
+
+#: django_authopenid/urls.py:38 django_authopenid/urls.py:39
+#: django_authopenid/urls.py:40 django_authopenid/urls.py:41
+msgid "email/"
+msgstr ""
+
+#: django_authopenid/urls.py:38
+msgid "validate/"
+msgstr ""
+
+#: django_authopenid/urls.py:39
+msgid "change/"
+msgstr ""
+
+#: django_authopenid/urls.py:40
+msgid "sendkey/"
+msgstr ""
+
+#: django_authopenid/urls.py:41
+msgid "verify/"
+msgstr ""
+
+#: django_authopenid/urls.py:42
+msgid "openid/"
+msgstr ""
+
+#: django_authopenid/urls.py:43 forum/urls.py:52 forum/urls.py:56
+msgid "delete/"
+msgstr ""
+
+#: django_authopenid/urls.py:51
+msgid "external-login/forgot-password/"
+msgstr ""
+
+#: django_authopenid/urls.py:54
+msgid "external-login/signup/"
+msgstr ""
+
+#: django_authopenid/views.py:139
+#, python-format
+msgid "OpenID %(openid_url)s is invalid"
+msgstr ""
+
+#: django_authopenid/views.py:614
+msgid "Welcome email subject line"
+msgstr ""
+
+#: django_authopenid/views.py:720
+msgid "Password changed."
+msgstr ""
+
+#: django_authopenid/views.py:732 django_authopenid/views.py:738
+#, python-format
+msgid "your email needs to be validated see %(details_url)s"
+msgstr ""
+
+#: django_authopenid/views.py:759
+msgid "Email verification subject line"
+msgstr ""
+
+#: django_authopenid/views.py:850
+msgid "your email was not changed"
+msgstr ""
+
+#: django_authopenid/views.py:898 django_authopenid/views.py:1056
+#, python-format
+msgid "No OpenID %s found associated in our database"
+msgstr ""
+
+#: django_authopenid/views.py:902 django_authopenid/views.py:1063
+#, python-format
+msgid "The OpenID %s isn't associated to current user logged in"
+msgstr ""
+
+#: django_authopenid/views.py:910
+msgid "Email Changed."
+msgstr ""
+
+#: django_authopenid/views.py:988
+msgid "This OpenID is already associated with another account."
+msgstr ""
+
+#: django_authopenid/views.py:993
+#, python-format
+msgid "OpenID %s is now associated with your account."
+msgstr ""
+
+#: django_authopenid/views.py:1066
+msgid "Account deleted."
+msgstr ""
+
+#: django_authopenid/views.py:1118
+msgid "Request for new password"
+msgstr ""
+
+#: django_authopenid/views.py:1132
+msgid "A new password and the activation link were sent to your email address."
+msgstr ""
+
+#: django_authopenid/views.py:1164
+#, python-format
+msgid ""
+"Could not change password. Confirmation key '%s' is not "
+"registered."
+msgstr ""
+
+#: django_authopenid/views.py:1174
+msgid ""
+"Can not change password. User don't exist anymore in our "
+"database."
+msgstr ""
+
+#: django_authopenid/views.py:1184
+#, python-format
+msgid "Password changed for %s. You may now sign in."
+msgstr ""
+
+#: forum/auth.py:505
+msgid "Your question and all of it's answers have been deleted"
+msgstr ""
+
+#: forum/auth.py:507
+msgid "Your question has been deleted"
+msgstr ""
+
+#: forum/auth.py:510
+msgid "The question and all of it's answers have been deleted"
+msgstr ""
+
+#: forum/auth.py:512
+msgid "The question has been deleted"
+msgstr ""
+
+#: forum/const.py:8
+msgid "duplicate question"
+msgstr ""
+
+#: forum/const.py:9
+msgid "question is off-topic or not relevant"
+msgstr ""
+
+#: forum/const.py:10
+msgid "too subjective and argumentative"
+msgstr ""
+
+#: forum/const.py:11
+msgid "not a real question"
+msgstr ""
+
+#: forum/const.py:12
+msgid "the question is answered, right answer was accepted"
+msgstr ""
+
+#: forum/const.py:13
+msgid "question is not relevant or outdated"
+msgstr ""
+
+#: forum/const.py:14
+msgid "question contains offensive or malicious remarks"
+msgstr ""
+
+#: forum/const.py:15
+msgid "spam or advertising"
+msgstr ""
+
+#: forum/const.py:16
+msgid "too localized"
+msgstr ""
+
+#: forum/const.py:37 forum/skins/default/templates/index.html:28
+#: forum/skins/default/templates/index_.html:27
+#: forum/skins/default/templates/questions.html:70
+#: forum/skins/default/templates/questions.html:75
+msgid "newest"
+msgstr ""
+
+#: forum/const.py:38 forum/skins/default/templates/questions.html:64
+#: forum/skins/default/templates/users.html:28
+msgid "oldest"
+msgstr ""
+
+#: forum/const.py:39 forum/skins/default/templates/questions.html:89
+#: forum/skins/default/templates/questions.html:94
+msgid "active"
+msgstr ""
+
+#: forum/const.py:40 forum/skins/default/templates/questions.html:83
+msgid "inactive"
+msgstr ""
+
+#: forum/const.py:41 forum/skins/default/templates/index.html:29
+#: forum/skins/default/templates/index_.html:28
+msgid "hottest"
+msgstr ""
+
+#: forum/const.py:42
+msgid "coldest"
+msgstr ""
+
+#: forum/const.py:43 forum/skins/default/templates/index.html:30
+#: forum/skins/default/templates/index_.html:29
+msgid "most voted"
+msgstr ""
+
+#: forum/const.py:44
+msgid "least voted"
+msgstr ""
+
+#: forum/const.py:45
+msgid "relevance"
+msgstr ""
+
+#: forum/const.py:52 forum/skins/default/templates/questions.html:52
+msgid "all"
+msgstr ""
+
+#: forum/const.py:53 forum/skins/default/templates/questions.html:53
+msgid "unanswered"
+msgstr ""
+
+#: forum/const.py:54 forum/skins/default/templates/questions.html:55
+msgid "favorite"
+msgstr ""
+
+#: forum/const.py:97
+msgid "question"
+msgstr ""
+
+#: forum/const.py:98 forum/skins/default/templates/book.html:110
+msgid "answer"
+msgstr ""
+
+#: forum/const.py:99
+msgid "commented question"
+msgstr ""
+
+#: forum/const.py:100
+msgid "commented answer"
+msgstr ""
+
+#: forum/const.py:101
+msgid "edited question"
+msgstr ""
+
+#: forum/const.py:102
+msgid "edited answer"
+msgstr ""
+
+#: forum/const.py:103
+msgid "received award"
+msgstr ""
+
+#: forum/const.py:104
+msgid "marked best answer"
+msgstr ""
+
+#: forum/const.py:105
+msgid "upvoted"
+msgstr ""
+
+#: forum/const.py:106
+msgid "downvoted"
+msgstr ""
+
+#: forum/const.py:107
+msgid "canceled vote"
+msgstr ""
+
+#: forum/const.py:108
+msgid "deleted question"
+msgstr ""
+
+#: forum/const.py:109
+msgid "deleted answer"
+msgstr ""
+
+#: forum/const.py:110
+msgid "marked offensive"
+msgstr ""
+
+#: forum/const.py:111
+msgid "updated tags"
+msgstr ""
+
+#: forum/const.py:112
+msgid "selected favorite"
+msgstr ""
+
+#: forum/const.py:113
+msgid "completed user profile"
+msgstr ""
+
+#: forum/const.py:114
+msgid "email update sent to user"
+msgstr ""
+
+#: forum/const.py:118
+msgid "question_answered"
+msgstr ""
+
+#: forum/const.py:119
+msgid "question_commented"
+msgstr ""
+
+#: forum/const.py:120
+msgid "answer_commented"
+msgstr ""
+
+#: forum/const.py:121
+msgid "answer_accepted"
+msgstr ""
+
+#: forum/const.py:125
+msgid "[closed]"
+msgstr ""
+
+#: forum/const.py:126
+msgid "[deleted]"
+msgstr ""
+
+#: forum/const.py:127 forum/views/readers.py:378 forum/views/readers.py:397
+msgid "initial version"
+msgstr ""
+
+#: forum/const.py:128
+msgid "retagged"
+msgstr ""
+
+#: forum/const.py:132
+msgid "exclude ignored tags"
+msgstr ""
+
+#: forum/const.py:132
+msgid "allow only selected tags"
+msgstr ""
+
+#: forum/feed.py:18
+msgid " - "
+msgstr ""
+
+#: forum/feed.py:18
+msgid "latest questions"
+msgstr ""
+
+#: forum/forms.py:23 forum/skins/default/templates/answer_edit_tips.html:35
+#: forum/skins/default/templates/answer_edit_tips.html:39
+#: forum/skins/default/templates/question_edit_tips.html:32
+#: forum/skins/default/templates/question_edit_tips.html:37
+msgid "title"
+msgstr ""
+
+#: forum/forms.py:24
+msgid "please enter a descriptive title for your question"
+msgstr ""
+
+#: forum/forms.py:29
+msgid "title must be > 10 characters"
+msgstr ""
+
+#: forum/forms.py:38
+msgid "content"
+msgstr ""
+
+#: forum/forms.py:44
+msgid "question content must be > 10 characters"
+msgstr ""
+
+#: forum/forms.py:53 forum/skins/default/templates/header.html:31
+msgid "tags"
+msgstr ""
+
+#: forum/forms.py:55
+msgid ""
+"Tags are short keywords, with no spaces within. Up to five tags can be used."
+msgstr ""
+
+#: forum/forms.py:62 forum/skins/default/templates/question_retag.html:39
+msgid "tags are required"
+msgstr ""
+
+#: forum/forms.py:70
+#, python-format
+msgid "please use %(tag_count)d tag or less"
+msgid_plural "please use %(tag_count)d tags or less"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/forms.py:79
+#, python-format
+msgid "each tag must be shorter than %(max_chars)d character"
+msgid_plural "each tag must be shorter than %(max_shars)d characters"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/forms.py:87
+msgid "use-these-chars-in-tags"
+msgstr ""
+
+#: forum/forms.py:97
+#: forum/skins/default/templates/post_contributor_info.html:7
+#: forum/skins/default/templates/question_summary_list_roll.html:26
+#: forum/skins/default/templates/question_summary_list_roll.html:38
+msgid "community wiki"
+msgstr ""
+
+#: forum/forms.py:98
+msgid ""
+"if you choose community wiki option, the question and answer do not generate "
+"points and name of author will not be shown"
+msgstr ""
+
+#: forum/forms.py:114
+msgid "update summary:"
+msgstr ""
+
+#: forum/forms.py:115
+msgid ""
+"enter a brief summary of your revision (e.g. fixed spelling, grammar, "
+"improved style, this field is optional)"
+msgstr ""
+
+#: forum/forms.py:118
+msgid "Automatically accept user's contributions for the email updates"
+msgstr ""
+
+#: forum/forms.py:205
+msgid "Your name:"
+msgstr ""
+
+#: forum/forms.py:206
+msgid "Email (not shared with anyone):"
+msgstr ""
+
+#: forum/forms.py:207
+msgid "Your message:"
+msgstr ""
+
+#: forum/forms.py:290
+msgid "this email does not have to be linked to gravatar"
+msgstr ""
+
+#: forum/forms.py:292
+msgid "Screen name"
+msgstr ""
+
+#: forum/forms.py:293
+msgid "Real name"
+msgstr ""
+
+#: forum/forms.py:294
+msgid "Website"
+msgstr ""
+
+#: forum/forms.py:295
+msgid "Location"
+msgstr ""
+
+#: forum/forms.py:296
+msgid "Date of birth"
+msgstr ""
+
+#: forum/forms.py:296
+msgid "will not be shown, used to calculate age, format: YYYY-MM-DD"
+msgstr ""
+
+#: forum/forms.py:297 forum/skins/default/templates/account_settings.html:21
+#: forum/skins/default/templates/authopenid/settings.html:21
+msgid "Profile"
+msgstr ""
+
+#: forum/forms.py:328 forum/forms.py:329
+msgid "this email has already been registered, please use another one"
+msgstr ""
+
+#: forum/forms.py:335
+msgid "Choose email tag filter"
+msgstr ""
+
+#: forum/forms.py:351 forum/forms.py:352
+msgid "weekly"
+msgstr ""
+
+#: forum/forms.py:351 forum/forms.py:352
+msgid "no email"
+msgstr ""
+
+#: forum/forms.py:352
+msgid "daily"
+msgstr ""
+
+#: forum/forms.py:367
+msgid "Asked by me"
+msgstr ""
+
+#: forum/forms.py:370
+msgid "Answered by me"
+msgstr ""
+
+#: forum/forms.py:373
+msgid "Individually selected"
+msgstr ""
+
+#: forum/forms.py:376
+msgid "Entire forum (tag filtered)"
+msgstr ""
+
+#: forum/forms.py:430 forum/authentication/forms.py:41
+msgid "okay, let's try!"
+msgstr ""
+
+#: forum/forms.py:431
+msgid "no community email please, thanks"
+msgstr ""
+
+#: forum/forms.py:434 forum/authentication/forms.py:45
+msgid "please choose one of the options above"
+msgstr ""
+
+#: forum/urls.py:28
+msgid "upfiles/"
+msgstr ""
+
+#: forum/urls.py:33
+msgid "about/"
+msgstr ""
+
+#: forum/urls.py:34
+msgid "faq/"
+msgstr ""
+
+#: forum/urls.py:35
+msgid "privacy/"
+msgstr ""
+
+#: forum/urls.py:36
+msgid "logout/"
+msgstr ""
+
+#: forum/urls.py:37 forum/urls.py:38 forum/urls.py:39 forum/urls.py:56
+msgid "answers/"
+msgstr ""
+
+#: forum/urls.py:37 forum/urls.py:49 forum/urls.py:52 forum/urls.py:56
+msgid "comments/"
+msgstr ""
+
+#: forum/urls.py:38 forum/urls.py:43 forum/urls.py:78
+#: forum/skins/default/templates/user_info.html:47
+msgid "edit/"
+msgstr ""
+
+#: forum/urls.py:39 forum/urls.py:48
+msgid "revisions/"
+msgstr ""
+
+#: forum/urls.py:40 forum/urls.py:41 forum/urls.py:42 forum/urls.py:43
+#: forum/urls.py:44 forum/urls.py:45 forum/urls.py:46 forum/urls.py:47
+#: forum/urls.py:48 forum/urls.py:49 forum/urls.py:52
+msgid "questions/"
+msgstr ""
+
+#: forum/urls.py:41 forum_modules/books/urls.py:8
+msgid "ask/"
+msgstr ""
+
+#: forum/urls.py:42
+msgid "unanswered/"
+msgstr ""
+
+#: forum/urls.py:44
+msgid "close/"
+msgstr ""
+
+#: forum/urls.py:45
+msgid "reopen/"
+msgstr ""
+
+#: forum/urls.py:46
+msgid "answer/"
+msgstr ""
+
+#: forum/urls.py:47
+msgid "vote/"
+msgstr ""
+
+#: forum/urls.py:50
+msgid "command/"
+msgstr ""
+
+#: forum/urls.py:60 forum/views/readers.py:249
+msgid "question/"
+msgstr ""
+
+#: forum/urls.py:61 forum/urls.py:62
+msgid "tags/"
+msgstr ""
+
+#: forum/urls.py:64 forum/urls.py:68
+msgid "mark-tag/"
+msgstr ""
+
+#: forum/urls.py:64
+msgid "interesting/"
+msgstr ""
+
+#: forum/urls.py:68
+msgid "ignored/"
+msgstr ""
+
+#: forum/urls.py:72
+msgid "unmark-tag/"
+msgstr ""
+
+#: forum/urls.py:76 forum/urls.py:78 forum/urls.py:79
+msgid "users/"
+msgstr ""
+
+#: forum/urls.py:77
+msgid "moderate-user/"
+msgstr ""
+
+#: forum/urls.py:80 forum/urls.py:81
+msgid "badges/"
+msgstr ""
+
+#: forum/urls.py:82
+msgid "messages/"
+msgstr ""
+
+#: forum/urls.py:82
+msgid "markread/"
+msgstr ""
+
+#: forum/urls.py:84
+msgid "nimda/"
+msgstr ""
+
+#: forum/urls.py:86
+msgid "upload/"
+msgstr ""
+
+#: forum/urls.py:87
+msgid "search/"
+msgstr ""
+
+#: forum/urls.py:88
+msgid "feedback/"
+msgstr ""
+
+#: forum/urls.py:89 forum/urls.py:90
+msgid "account/"
+msgstr ""
+
+#: forum/authentication/forms.py:22
+msgid "Your account email"
+msgstr ""
+
+#: forum/authentication/forms.py:24
+msgid "You cannot leave this field blank"
+msgstr ""
+
+#: forum/authentication/forms.py:25 forum/utils/forms.py:111
+msgid "please enter a valid email address"
+msgstr ""
+
+#: forum/authentication/forms.py:33
+msgid "Sorry, but this email is not on our database."
+msgstr ""
+
+#: forum/authentication/forms.py:42
+msgid "no OSQA community email please, thanks"
+msgstr ""
+
+#: forum/management/commands/send_email_alerts.py:236
+msgid "email update message subject"
+msgstr ""
+
+#: forum/management/commands/send_email_alerts.py:238
+#, python-format
+msgid "%(name)s, this is an update message header for a question"
+msgid_plural "%(name)s, this is an update message header for %(num)d questions"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/management/commands/send_email_alerts.py:255
+msgid "new question"
+msgstr ""
+
+#: forum/management/commands/send_email_alerts.py:272
+msgid ""
+"Please visit the forum and see what's new! Could you spread the word about "
+"it - can somebody you know help answering those questions or benefit from "
+"posting one?"
+msgstr ""
+
+#: forum/management/commands/send_email_alerts.py:284
+msgid ""
+"Your most frequent subscription setting is 'daily' on selected questions. If "
+"you are receiving more than one email per dayplease tell about this issue to "
+"the forum administrator."
+msgstr ""
+
+#: forum/management/commands/send_email_alerts.py:290
+msgid ""
+"Your most frequent subscription setting is 'weekly' if you are receiving "
+"this email more than once a week please report this issue to the forum "
+"administrator."
+msgstr ""
+
+#: forum/management/commands/send_email_alerts.py:296
+msgid ""
+"There is a chance that you may be receiving links seen before - due to a "
+"technicality that will eventually go away. "
+msgstr ""
+
+#: forum/management/commands/send_email_alerts.py:311
+#, python-format
+msgid ""
+"go to %(link)s to change frequency of email updates or %(email)s "
+"administrator"
+msgstr ""
+
+#: forum/middleware/anon_user.py:34
+#, python-format
+msgid "First time here? Check out the <a href=\"%s\">FAQ</a>!"
+msgstr ""
+
+#: forum/models/question.py:481
+#, python-format
+msgid "%(author)s modified the question"
+msgstr ""
+
+#: forum/models/question.py:485
+#, python-format
+msgid "%(people)s posted %(new_answer_count)s new answers"
+msgstr ""
+
+#: forum/models/question.py:490
+#, python-format
+msgid "%(people)s commented the question"
+msgstr ""
+
+#: forum/models/question.py:495
+#, python-format
+msgid "%(people)s commented answers"
+msgstr ""
+
+#: forum/models/question.py:497
+#, python-format
+msgid "%(people)s commented an answer"
+msgstr ""
+
+#: forum/models/repute.py:13 forum/skins/default/templates/badges.html:53
+msgid "gold"
+msgstr ""
+
+#: forum/models/repute.py:14 forum/skins/default/templates/badges.html:61
+msgid "silver"
+msgstr ""
+
+#: forum/models/repute.py:15 forum/skins/default/templates/badges.html:68
+msgid "bronze"
+msgstr ""
+
+#: forum/models/tag.py:81
+msgid "interesting"
+msgstr ""
+
+#: forum/models/tag.py:81
+msgid "ignored"
+msgstr ""
+
+#: forum/models/user.py:36
+msgid "Entire forum"
+msgstr ""
+
+#: forum/models/user.py:37
+msgid "Questions that I asked"
+msgstr ""
+
+#: forum/models/user.py:38
+msgid "Questions that I answered"
+msgstr ""
+
+#: forum/models/user.py:39
+msgid "Individually selected questions"
+msgstr ""
+
+#: forum/models/user.py:42
+msgid "Weekly"
+msgstr ""
+
+#: forum/models/user.py:43
+msgid "Daily"
+msgstr ""
+
+#: forum/models/user.py:44
+msgid "No email"
+msgstr ""
+
+#: forum/skins/default/templates/404.html:24
+msgid "Sorry, could not find the page you requested."
+msgstr ""
+
+#: forum/skins/default/templates/404.html:26
+msgid "This might have happened for the following reasons:"
+msgstr ""
+
+#: forum/skins/default/templates/404.html:28
+msgid "this question or answer has been deleted;"
+msgstr ""
+
+#: forum/skins/default/templates/404.html:29
+msgid "url has error - please check it;"
+msgstr ""
+
+#: forum/skins/default/templates/404.html:30
+msgid ""
+"the page you tried to visit is protected or you don't have sufficient "
+"points, see"
+msgstr ""
+
+#: forum/skins/default/templates/404.html:31
+msgid "if you believe this error 404 should not have occured, please"
+msgstr ""
+
+#: forum/skins/default/templates/404.html:32
+msgid "report this problem"
+msgstr ""
+
+#: forum/skins/default/templates/404.html:41
+#: forum/skins/default/templates/500.html:27
+msgid "back to previous page"
+msgstr ""
+
+#: forum/skins/default/templates/404.html:42
+#: forum/skins/default/templates/questions.html:52
+msgid "see all questions"
+msgstr ""
+
+#: forum/skins/default/templates/404.html:43
+#: forum/skins/default/templates/index.html:65
+msgid "see all tags"
+msgstr ""
+
+#: forum/skins/default/templates/500.html:22
+msgid "sorry, system error"
+msgstr ""
+
+#: forum/skins/default/templates/500.html:24
+msgid "system error log is recorded, error will be fixed as soon as possible"
+msgstr ""
+
+#: forum/skins/default/templates/500.html:25
+msgid "please report the error to the site administrators if you wish"
+msgstr ""
+
+#: forum/skins/default/templates/500.html:28
+msgid "see latest questions"
+msgstr ""
+
+#: forum/skins/default/templates/500.html:29
+msgid "see tags"
+msgstr ""
+
+#: forum/skins/default/templates/about.html:6
+#: forum/skins/default/templates/about.html:11
+msgid "About"
+msgstr ""
+
+#: forum/skins/default/templates/account_settings.html:4
+#: forum/skins/default/templates/authopenid/settings.html:4
+msgid "Account functions"
+msgstr ""
+
+#: forum/skins/default/templates/account_settings.html:29
+#: forum/skins/default/templates/authopenid/changepw.html:5
+#: forum/skins/default/templates/authopenid/changepw.html:14
+#: forum/skins/default/templates/authopenid/settings.html:29
+msgid "Change password"
+msgstr ""
+
+#: forum/skins/default/templates/account_settings.html:30
+#: forum/skins/default/templates/authopenid/settings.html:30
+msgid "Give your account a new password."
+msgstr ""
+
+#: forum/skins/default/templates/account_settings.html:32
+#: forum/skins/default/templates/authopenid/settings.html:31
+msgid "Change email "
+msgstr ""
+
+#: forum/skins/default/templates/account_settings.html:33
+#: forum/skins/default/templates/authopenid/settings.html:32
+msgid "Add or update the email address associated with your account."
+msgstr ""
+
+#: forum/skins/default/templates/account_settings.html:35
+#: forum/skins/default/templates/authopenid/changeopenid.html:4
+#: forum/skins/default/templates/authopenid/changeopenid.html:30
+#: forum/skins/default/templates/authopenid/settings.html:34
+msgid "Change OpenID"
+msgstr ""
+
+#: forum/skins/default/templates/account_settings.html:36
+#: forum/skins/default/templates/authopenid/settings.html:35
+msgid "Change openid associated to your account"
+msgstr ""
+
+#: forum/skins/default/templates/account_settings.html:39
+#: forum/skins/default/templates/authopenid/delete.html:4
+#: forum/skins/default/templates/authopenid/settings.html:38
+msgid "Delete account"
+msgstr ""
+
+#: forum/skins/default/templates/account_settings.html:40
+#: forum/skins/default/templates/authopenid/settings.html:39
+msgid "Erase your username and all your data from website"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit.html:5
+#: forum/skins/default/templates/answer_edit.html:48
+msgid "Edit answer"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit.html:25
+#: forum/skins/default/templates/answer_edit.html:28
+#: forum/skins/default/templates/ask.html:26
+#: forum/skins/default/templates/ask.html:29
+#: forum/skins/default/templates/question.html:46
+#: forum/skins/default/templates/question.html:49
+#: forum/skins/default/templates/question_edit.html:25
+#: forum/skins/default/templates/question_edit.html:28
+msgid "hide preview"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit.html:28
+#: forum/skins/default/templates/ask.html:29
+#: forum/skins/default/templates/question.html:49
+#: forum/skins/default/templates/question_edit.html:28
+msgid "show preview"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit.html:48
+#: forum/skins/default/templates/question_edit.html:66
+#: forum/skins/default/templates/question_retag.html:53
+#: forum/skins/default/templates/revisions_answer.html:38
+#: forum/skins/default/templates/revisions_question.html:38
+msgid "back"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit.html:53
+#: forum/skins/default/templates/question_edit.html:71
+#: forum/skins/default/templates/revisions_answer.html:52
+#: forum/skins/default/templates/revisions_question.html:52
+msgid "revision"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit.html:56
+#: forum/skins/default/templates/question_edit.html:75
+msgid "select revision"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit.html:63
+#: forum/skins/default/templates/ask.html:98
+#: forum/skins/default/templates/ask_form.html:39
+#: forum/skins/default/templates/question.html:433
+#: forum/skins/default/templates/question_edit.html:92
+msgid "Toggle the real time Markdown editor preview"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit.html:63
+#: forum/skins/default/templates/ask.html:98
+#: forum/skins/default/templates/ask_form.html:39
+#: forum/skins/default/templates/question.html:434
+#: forum/skins/default/templates/question_edit.html:92
+msgid "toggle preview"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit.html:72
+#: forum/skins/default/templates/question_edit.html:118
+#: forum/skins/default/templates/question_retag.html:74
+msgid "Save edit"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit.html:73
+#: forum/skins/default/templates/close.html:29
+#: forum/skins/default/templates/feedback.html:50
+#: forum/skins/default/templates/question_edit.html:119
+#: forum/skins/default/templates/question_retag.html:75
+#: forum/skins/default/templates/reopen.html:30
+#: forum/skins/default/templates/user_edit.html:84
+#: forum/skins/default/templates/authopenid/changeemail.html:40
+msgid "Cancel"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:4
+msgid "answer tips"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:7
+msgid "please make your answer relevant to this community"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:10
+msgid "try to give an answer, rather than engage into a discussion"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:13
+msgid "please try to provide details"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:16
+#: forum/skins/default/templates/question_edit_tips.html:13
+msgid "be clear and concise"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:20
+#: forum/skins/default/templates/question_edit_tips.html:17
+msgid "see frequently asked questions"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:26
+#: forum/skins/default/templates/question_edit_tips.html:23
+msgid "Markdown tips"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:29
+#: forum/skins/default/templates/question_edit_tips.html:26
+msgid "*italic* or __italic__"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:32
+#: forum/skins/default/templates/question_edit_tips.html:29
+msgid "**bold** or __bold__"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:35
+#: forum/skins/default/templates/question_edit_tips.html:32
+msgid "link"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:35
+#: forum/skins/default/templates/answer_edit_tips.html:39
+#: forum/skins/default/templates/question_edit_tips.html:32
+#: forum/skins/default/templates/question_edit_tips.html:37
+msgid "text"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:39
+#: forum/skins/default/templates/question_edit_tips.html:37
+msgid "image"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:43
+#: forum/skins/default/templates/question_edit_tips.html:41
+msgid "numbered list:"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:48
+#: forum/skins/default/templates/question_edit_tips.html:46
+msgid "basic HTML tags are also supported"
+msgstr ""
+
+#: forum/skins/default/templates/answer_edit_tips.html:52
+#: forum/skins/default/templates/question_edit_tips.html:50
+msgid "learn more about Markdown"
+msgstr ""
+
+#: forum/skins/default/templates/ask.html:5
+#: forum/skins/default/templates/ask.html:62
+msgid "Ask a question"
+msgstr ""
+
+#: forum/skins/default/templates/ask.html:69
+#: forum/skins/default/templates/ask_form.html:11
+msgid "login to post question info"
+msgstr ""
+
+#: forum/skins/default/templates/ask.html:75
+#, python-format
+msgid ""
+"must have valid %(email)s to post, \n"
+" see %(email_validation_faq_url)s\n"
+" "
+msgstr ""
+
+#: forum/skins/default/templates/ask.html:113
+#: forum/skins/default/templates/ask_form.html:54
+msgid "(required)"
+msgstr ""
+
+#: forum/skins/default/templates/ask.html:120
+#: forum/skins/default/templates/ask_form.html:61
+msgid "Login/signup to post your question"
+msgstr ""
+
+#: forum/skins/default/templates/ask.html:122
+#: forum/skins/default/templates/ask_form.html:63
+msgid "Ask your question"
+msgstr ""
+
+#: forum/skins/default/templates/ask_form.html:15
+#, python-format
+msgid ""
+"must have valid %(email)s to post, \n"
+" see %(email_validation_faq_url)s\n"
+" "
+msgstr ""
+
+#: forum/skins/default/templates/badge.html:6
+#: forum/skins/default/templates/badge.html:17
+msgid "Badge"
+msgstr ""
+
+#: forum/skins/default/templates/badge.html:26
+msgid "The users have been awarded with badges:"
+msgstr ""
+
+#: forum/skins/default/templates/badges.html:6
+msgid "Badges summary"
+msgstr ""
+
+#: forum/skins/default/templates/badges.html:17
+msgid "Badges"
+msgstr ""
+
+#: forum/skins/default/templates/badges.html:21
+msgid "Community gives you awards for your questions, answers and votes."
+msgstr ""
+
+#: forum/skins/default/templates/badges.html:22
+#, python-format
+msgid ""
+"Below is the list of available badges and number \n"
+" of times each type of badge has been awarded. Give us feedback at %"
+"(feedback_faq_url)s.\n"
+" "
+msgstr ""
+
+#: forum/skins/default/templates/badges.html:50
+msgid "Community badges"
+msgstr ""
+
+#: forum/skins/default/templates/badges.html:56
+msgid "gold badge description"
+msgstr ""
+
+#: forum/skins/default/templates/badges.html:64
+msgid "silver badge description"
+msgstr ""
+
+#: forum/skins/default/templates/badges.html:67
+msgid "bronze badge: often given as a special honor"
+msgstr ""
+
+#: forum/skins/default/templates/badges.html:71
+msgid "bronze badge description"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:7
+msgid "reading channel"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:26
+msgid "[author]"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:30
+msgid "[publisher]"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:34
+msgid "[publication date]"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:38
+msgid "[price]"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:39
+msgid "currency unit"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:42
+msgid "[pages]"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:43
+msgid "pages abbreviation"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:46
+msgid "[tags]"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:56
+msgid "author blog"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:62
+msgid "book directory"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:66
+msgid "buy online"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:79
+msgid "reader questions"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:82
+msgid "ask the author"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:88
+#: forum/skins/default/templates/book.html:93
+#: forum/skins/default/templates/users_questions.html:18
+msgid "this question was selected as favorite"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:88
+#: forum/skins/default/templates/book.html:93
+#: forum/skins/default/templates/users_questions.html:11
+#: forum/skins/default/templates/users_questions.html:18
+msgid "number of times"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:105
+#: forum/skins/default/templates/index_.html:40
+#: forum/skins/default/templates/question_summary_list_roll.html:14
+msgid "votes"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:108
+msgid "the answer has been accepted to be correct"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:115
+#: forum/skins/default/templates/index_.html:48
+#: forum/skins/default/templates/question_summary_list_roll.html:15
+msgid "views"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:125
+#: forum/skins/default/templates/index_.html:63
+#: forum/skins/default/templates/question.html:136
+#: forum/skins/default/templates/question_list.html:19
+#: forum/skins/default/templates/question_summary_list_roll.html:52
+#: forum/skins/default/templates/tags.html:50
+#: forum/skins/default/templates/users_questions.html:34
+#, python-format
+msgid "see questions tagged '%(tag)s'"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:147
+msgid "subscribe to book RSS feed"
+msgstr ""
+
+#: forum/skins/default/templates/book.html:147
+#: forum/skins/default/templates/index.html:88
+#: forum/skins/default/templates/index_.html:115
+msgid "subscribe to the questions feed"
+msgstr ""
+
+#: forum/skins/default/templates/close.html:6
+#: forum/skins/default/templates/close.html:16
+msgid "Close question"
+msgstr ""
+
+#: forum/skins/default/templates/close.html:19
+msgid "Close the question"
+msgstr ""
+
+#: forum/skins/default/templates/close.html:25
+msgid "Reasons"
+msgstr ""
+
+#: forum/skins/default/templates/close.html:28
+msgid "OK to close"
+msgstr ""
+
+#: forum/skins/default/templates/email_base.html:11
+msgid "home"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:11
+msgid "Frequently Asked Questions "
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:16
+msgid "What kinds of questions can I ask here?"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:17
+msgid ""
+"Most importanly - questions should be <strong>relevant</strong> to this "
+"community."
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:18
+msgid ""
+"Before asking the question - please make sure to use search to see whether "
+"your question has alredy been answered."
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:21
+msgid "What questions should I avoid asking?"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:22
+msgid ""
+"Please avoid asking questions that are not relevant to this community, too "
+"subjective and argumentative."
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:27
+msgid "What should I avoid in my answers?"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:28
+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 ""
+
+#: forum/skins/default/templates/faq.html:32
+msgid "Who moderates this community?"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:33
+msgid "The short answer is: <strong>you</strong>."
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:34
+msgid "This website is moderated by the users."
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:35
+msgid ""
+"The reputation system allows users earn the authorization to perform a "
+"variety of moderation tasks."
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:40
+msgid "How does reputation system work?"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:41
+msgid "Rep system summary"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:42
+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>10</strong> "
+"points, each vote against will subtract <strong>2</strong> points. There is "
+"a limit of <strong>200</strong> points that can be accumulated per question "
+"or answer. The table below explains reputation point requirements for each "
+"type of moderation task."
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:53
+#: forum/skins/default/templates/user_votes.html:15
+msgid "upvote"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:57
+msgid "use tags"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:62
+msgid "add comments"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:66
+#: forum/skins/default/templates/user_votes.html:17
+msgid "downvote"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:69
+msgid "open and close own questions"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:73
+msgid "retag questions"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:78
+msgid "edit community wiki questions"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:83
+msgid "edit any answer"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:87
+msgid "open any closed question"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:91
+msgid "delete any comment"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:95
+msgid "delete any questions and answers and perform other moderation tasks"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:103
+msgid "how to validate email title"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:105
+#, python-format
+msgid ""
+"how to validate email info with %(send_email_key_url)s %(gravatar_faq_url)s"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:110
+msgid "what is gravatar"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:111
+msgid "gravatar faq info"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:114
+msgid "To register, do I need to create new password?"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:115
+msgid ""
+"No, you don't have to. You can login through any service that supports "
+"OpenID, e.g. Google, Yahoo, AOL, etc."
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:116
+msgid "Login now!"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:121
+msgid "Why other people can edit my questions/answers?"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:122
+msgid "Goal of this site is..."
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:122
+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 ""
+
+#: forum/skins/default/templates/faq.html:123
+msgid "If this approach is not for you, we respect your choice."
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:127
+msgid "Still have questions?"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:128
+#, python-format
+msgid ""
+"Please ask your question at %(ask_question_url)s, help make our community "
+"better!"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:130
+#: forum/skins/default/templates/header.html:30
+msgid "questions"
+msgstr ""
+
+#: forum/skins/default/templates/faq.html:130
+#: forum/skins/default/templates/index.html:95
+#: forum/skins/default/templates/index_.html:122
+msgid "."
+msgstr ""
+
+#: forum/skins/default/templates/feedback.html:6
+msgid "Feedback"
+msgstr ""
+
+#: forum/skins/default/templates/feedback.html:11
+msgid "Give us your feedback!"
+msgstr ""
+
+#: forum/skins/default/templates/feedback.html:17
+#, 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 ""
+
+#: forum/skins/default/templates/feedback.html:24
+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 ""
+
+#: forum/skins/default/templates/feedback.html:41
+msgid "(this field is required)"
+msgstr ""
+
+#: forum/skins/default/templates/feedback.html:49
+msgid "Send Feedback"
+msgstr ""
+
+#: forum/skins/default/templates/feedback_email.txt:3
+#, python-format
+msgid ""
+"\n"
+"Hello, this is a %(site_title)s forum feedback message\n"
+msgstr ""
+
+#: forum/skins/default/templates/feedback_email.txt:9
+msgid "Sender is"
+msgstr ""
+
+#: forum/skins/default/templates/feedback_email.txt:11
+#: forum/skins/default/templates/feedback_email.txt:14
+msgid "email"
+msgstr ""
+
+#: forum/skins/default/templates/feedback_email.txt:13
+msgid "anonymous"
+msgstr ""
+
+#: forum/skins/default/templates/feedback_email.txt:19
+msgid "Message body:"
+msgstr ""
+
+#: forum/skins/default/templates/footer.html:8
+#: forum/skins/default/templates/header.html:17
+#: forum/skins/default/templates/index.html:46
+#: forum/skins/default/templates/index_.html:77
+msgid "about"
+msgstr ""
+
+#: forum/skins/default/templates/footer.html:9
+#: forum/skins/default/templates/header.html:18
+#: forum/skins/default/templates/index.html:47
+#: forum/skins/default/templates/index_.html:78
+#: forum/skins/default/templates/question_edit_tips.html:17
+msgid "faq"
+msgstr ""
+
+#: forum/skins/default/templates/footer.html:10
+msgid "privacy policy"
+msgstr ""
+
+#: forum/skins/default/templates/footer.html:19
+msgid "give feedback"
+msgstr ""
+
+#: forum/skins/default/templates/header.html:13
+msgid "logout"
+msgstr ""
+
+#: forum/skins/default/templates/header.html:15
+msgid "login"
+msgstr ""
+
+#: forum/skins/default/templates/header.html:25
+msgid "back to home page"
+msgstr ""
+
+#: forum/skins/default/templates/header.html:32
+msgid "users"
+msgstr ""
+
+#: forum/skins/default/templates/header.html:34
+msgid "books"
+msgstr ""
+
+#: forum/skins/default/templates/header.html:36
+#: forum/templatetags/extra_tags.py:174 forum/templatetags/extra_tags.py:203
+msgid "badges"
+msgstr ""
+
+#: forum/skins/default/templates/header.html:37
+#: forum/skins/default/templates/header.html:41
+msgid "ask a question"
+msgstr ""
+
+#: forum/skins/default/templates/header.html:39
+msgid "unanswered questions"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:9
+#: forum/skins/default/templates/index_.html:8
+msgid "Home"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:26
+#: forum/skins/default/templates/index_.html:25
+#: forum/skins/default/templates/questions.html:8
+msgid "Questions"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:28
+#: forum/skins/default/templates/index_.html:27
+msgid "last updated questions"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:29
+#: forum/skins/default/templates/index_.html:28
+msgid "hottest questions"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:30
+#: forum/skins/default/templates/index_.html:29
+msgid "most voted questions"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:31
+#: forum/skins/default/templates/index_.html:30
+msgid "all questions"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:43
+#: forum/skins/default/templates/index_.html:74
+msgid "welcome to website"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:54
+#: forum/skins/default/templates/index_.html:85
+msgid "Recent tags"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:60
+#: forum/skins/default/templates/index_.html:90
+#, python-format
+msgid "see questions tagged '%(tagname)s'"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:70
+#: forum/skins/default/templates/index_.html:99
+msgid "Recent awards"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:83
+#: forum/skins/default/templates/index_.html:110
+msgid "all awards"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:88
+#: forum/skins/default/templates/index_.html:115
+msgid "subscribe to last 30 questions by RSS"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:95
+#: forum/skins/default/templates/index_.html:122
+msgid "Still looking for more? See"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:95
+#: forum/skins/default/templates/index_.html:122
+msgid "complete list of questions"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:95
+#: forum/skins/default/templates/index_.html:122
+#: forum/skins/default/templates/authopenid/signup.html:28
+msgid "or"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:95
+#: forum/skins/default/templates/index_.html:94
+#: forum/skins/default/templates/index_.html:122
+msgid "popular tags"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:95
+#: forum/skins/default/templates/index_.html:122
+msgid "Please help us answer"
+msgstr ""
+
+#: forum/skins/default/templates/index.html:95
+#: forum/skins/default/templates/index_.html:122
+msgid "list of unanswered questions"
+msgstr ""
+
+#: forum/skins/default/templates/index_.html:42
+#: forum/skins/default/templates/question_counter_widget.html:21
+msgid "this answer has been accepted to be correct"
+msgstr ""
+
+#: forum/skins/default/templates/index_.html:44
+#: forum/skins/default/templates/question_summary_list_roll.html:13
+msgid "answers"
+msgstr ""
+
+#: forum/skins/default/templates/input_bar.html:33
+msgid "search"
+msgstr ""
+
+#: forum/skins/default/templates/logout.html:6
+#: forum/skins/default/templates/logout.html:16
+msgid "Logout"
+msgstr ""
+
+#: forum/skins/default/templates/logout.html:19
+msgid ""
+"As a registered user you can login with your OpenID, log out of the site or "
+"permanently remove your account."
+msgstr ""
+
+#: forum/skins/default/templates/logout.html:20
+msgid "Logout now"
+msgstr ""
+
+#: forum/skins/default/templates/notarobot.html:3
+msgid "Please prove that you are a Human Being"
+msgstr ""
+
+#: forum/skins/default/templates/notarobot.html:10
+msgid "I am a Human Being"
+msgstr ""
+
+#: forum/skins/default/templates/pagesize.html:6
+msgid "posts per page"
+msgstr ""
+
+#: forum/skins/default/templates/paginator.html:6
+#: forum/skins/default/templates/paginator.html:7
+msgid "previous"
+msgstr ""
+
+#: forum/skins/default/templates/paginator.html:19
+msgid "current page"
+msgstr ""
+
+#: forum/skins/default/templates/paginator.html:22
+#: forum/skins/default/templates/paginator.html:29
+msgid "page number "
+msgstr ""
+
+#: forum/skins/default/templates/paginator.html:22
+#: forum/skins/default/templates/paginator.html:29
+msgid "number - make blank in english"
+msgstr ""
+
+#: forum/skins/default/templates/paginator.html:33
+msgid "next page"
+msgstr ""
+
+#: forum/skins/default/templates/post_contributor_info.html:9
+#, python-format
+msgid ""
+"\n"
+" one revision\n"
+" "
+msgid_plural ""
+"\n"
+" %(rev_count)s revisions\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/post_contributor_info.html:19
+msgid "asked"
+msgstr ""
+
+#: forum/skins/default/templates/post_contributor_info.html:22
+msgid "answered"
+msgstr ""
+
+#: forum/skins/default/templates/post_contributor_info.html:24
+msgid "posted"
+msgstr ""
+
+#: forum/skins/default/templates/post_contributor_info.html:45
+msgid "updated"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:6
+#: forum/skins/default/templates/privacy.html:11
+msgid "Privacy policy"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:15
+msgid "general message about privacy"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:18
+msgid "Site Visitors"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:20
+msgid "what technical information is collected about visitors"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:23
+msgid "Personal Information"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:25
+msgid "details on personal information policies"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:28
+msgid "Other Services"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:30
+msgid "details on sharing data with third parties"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:35
+msgid "cookie policy details"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:37
+msgid "Policy Changes"
+msgstr ""
+
+#: forum/skins/default/templates/privacy.html:38
+msgid "how privacy policies can be changed"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:78
+#: forum/skins/default/templates/question.html:79
+#: forum/skins/default/templates/question.html:95
+#: forum/skins/default/templates/question.html:97
+msgid "i like this post (click again to cancel)"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:81
+#: forum/skins/default/templates/question.html:99
+#: forum/skins/default/templates/question.html:258
+msgid "current number of votes"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:90
+#: forum/skins/default/templates/question.html:91
+#: forum/skins/default/templates/question.html:104
+#: forum/skins/default/templates/question.html:105
+msgid "i dont like this post (click again to cancel)"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:109
+#: forum/skins/default/templates/question.html:110
+msgid "mark this question as favorite (click again to cancel)"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:116
+#: forum/skins/default/templates/question.html:117
+msgid "remove favorite mark from this question (click again to restore mark)"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:141
+#: forum/skins/default/templates/question.html:295
+#: forum/skins/default/templates/revisions_answer.html:58
+#: forum/skins/default/templates/revisions_question.html:58
+msgid "edit"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:146
+msgid "reopen"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:150
+msgid "close"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:156
+#: forum/skins/default/templates/question.html:300
+msgid ""
+"report as offensive (i.e containing spam, advertising, malicious text, etc.)"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:157
+#: forum/skins/default/templates/question.html:301
+msgid "flag offensive"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:165
+#: forum/skins/default/templates/question.html:312
+msgid "delete"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:183
+#: forum/skins/default/templates/question.html:332
+msgid "delete this comment"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:194
+#: forum/skins/default/templates/question.html:343
+msgid "add comment"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:198
+#, python-format
+msgid ""
+"\n"
+" see <strong>one</strong> more \n"
+" "
+msgid_plural ""
+"\n"
+" see <strong>%(counter)s</strong> "
+"more\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/question.html:204
+#, python-format
+msgid ""
+"\n"
+" see <strong>one</strong> more "
+"comment\n"
+" "
+msgid_plural ""
+"\n"
+" see <strong>%(counter)s</strong> "
+"more comments\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/question.html:220
+#, python-format
+msgid ""
+"The question has been closed for the following reason \"%(close_reason)s\" by"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:222
+#, python-format
+msgid "close date %(closed_at)s"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:230
+#, python-format
+msgid ""
+"\n"
+" One Answer:\n"
+" "
+msgid_plural ""
+"\n"
+" %(counter)s Answers:\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/question.html:238
+msgid "oldest answers will be shown first"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:238
+msgid "oldest answers"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:240
+msgid "newest answers will be shown first"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:240
+msgid "newest answers"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:242
+msgid "most voted answers will be shown first"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:242
+msgid "popular answers"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:256
+#: forum/skins/default/templates/question.html:257
+msgid "i like this answer (click again to cancel)"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:263
+#: forum/skins/default/templates/question.html:264
+msgid "i dont like this answer (click again to cancel)"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:269
+#: forum/skins/default/templates/question.html:270
+msgid "mark this answer as favorite (click again to undo)"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:275
+#: forum/skins/default/templates/question.html:276
+msgid "the author of the question has selected this answer as correct"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:289
+msgid "answer permanent link"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:290
+msgid "permanent link"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:312
+msgid "undelete"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:347
+#, python-format
+msgid ""
+"\n"
+" see <strong>one</"
+"strong> more \n"
+" "
+msgid_plural ""
+"\n"
+" see <strong>%"
+"(counter)s</strong> more\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/question.html:353
+#, python-format
+msgid ""
+"\n"
+" see <strong>one</"
+"strong> more comment\n"
+" "
+msgid_plural ""
+"\n"
+" see <strong>%"
+"(counter)s</strong> more comments\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/question.html:379
+#: forum/skins/default/templates/question.html:382
+msgid "Notify me once a day when there are any new answers"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:385
+msgid "Notify me weekly when there are any new answers"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:390
+#, python-format
+msgid ""
+"You can always adjust frequency of email updates from your %(profile_url)s"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:395
+msgid "once you sign in you will be able to subscribe for any updates here"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:406
+msgid "Your answer"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:408
+msgid "Be the first one to answer this question!"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:414
+msgid "you can answer anonymously and then login"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:418
+msgid "answer your own question only to give an answer"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:420
+msgid "please only give an answer, no discussions"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:456
+msgid "Login/Signup to Post Your Answer"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:459
+msgid "Answer Your Own Question"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:461
+msgid "Answer the question"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:475
+msgid "Question tags"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:480
+#: forum/skins/default/templates/questions.html:246
+#: forum/skins/default/templates/tag_selector.html:11
+#: forum/skins/default/templates/tag_selector.html:28
+#, python-format
+msgid "see questions tagged '%(tag_name)s'"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:486
+msgid "question asked"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:489
+msgid "question was seen"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:489
+msgid "times"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:492
+msgid "last updated"
+msgstr ""
+
+#: forum/skins/default/templates/question.html:498
+msgid "Related questions"
+msgstr ""
+
+#: forum/skins/default/templates/question_counter_widget.html:6
+msgid "Please decide if you like this question or not by voting"
+msgstr ""
+
+#: forum/skins/default/templates/question_counter_widget.html:12
+msgid ""
+"\n"
+" vote\n"
+" "
+msgid_plural ""
+"\n"
+" votes\n"
+" "
+msgstr[0] ""
+"\n"
+"golos"
+msgstr[1] ""
+"\n"
+"golosa"
+msgstr[2] ""
+"\n"
+"golosov"
+
+#: forum/skins/default/templates/question_counter_widget.html:27
+msgid ""
+"\n"
+" answer \n"
+" "
+msgid_plural ""
+"\n"
+" answers \n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/question_counter_widget.html:39
+msgid ""
+"\n"
+" view\n"
+" "
+msgid_plural ""
+"\n"
+" views\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/question_edit.html:5
+#: forum/skins/default/templates/question_edit.html:66
+msgid "Edit question"
+msgstr ""
+
+#: forum/skins/default/templates/question_edit_tips.html:4
+msgid "question tips"
+msgstr ""
+
+#: forum/skins/default/templates/question_edit_tips.html:7
+msgid "please ask a relevant question"
+msgstr ""
+
+#: forum/skins/default/templates/question_edit_tips.html:10
+msgid "please try provide enough details"
+msgstr ""
+
+#: forum/skins/default/templates/question_retag.html:4
+#: forum/skins/default/templates/question_retag.html:53
+msgid "Change tags"
+msgstr ""
+
+#: forum/skins/default/templates/question_retag.html:40
+msgid "up to 5 tags, less than 20 characters each"
+msgstr ""
+
+#: forum/skins/default/templates/question_retag.html:83
+msgid "Why use and modify tags?"
+msgstr ""
+
+#: forum/skins/default/templates/question_retag.html:86
+msgid "tags help us keep Questions organized"
+msgstr ""
+
+#: forum/skins/default/templates/question_retag.html:94
+msgid "tag editors receive special awards from the community"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:32
+msgid "Found by tags"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:36
+msgid "Search results"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:38
+msgid "Found by title"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:42
+msgid "Unanswered questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:44
+msgid "All questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:51
+msgid "In:"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:53
+msgid "see unanswered questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:55
+msgid "see your favorite questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:59
+msgid "Sort by:"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:64
+#: forum/skins/default/templates/questions.html:75
+msgid "click to see the newest questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:70
+msgid "click to see the oldest questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:83
+#: forum/skins/default/templates/questions.html:94
+msgid "click to see the most recently updated questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:89
+msgid "click to see the least recently updated questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:102
+#: forum/skins/default/templates/questions.html:113
+msgid "click to see hottest questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:102
+msgid "less answers"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:108
+msgid "click to see coldest questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:108
+#: forum/skins/default/templates/questions.html:113
+msgid "more answers"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:121
+#: forum/skins/default/templates/questions.html:132
+msgid "click to see most voted questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:121
+msgid "unpopular"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:127
+msgid "click to see least voted questions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:127
+#: forum/skins/default/templates/questions.html:132
+msgid "popular"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:141
+#, python-format
+msgid " One question found"
+msgid_plural "%(q_num)s questions found"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#: forum/skins/default/templates/questions.html:143
+#, python-format
+msgid " %(q_num)s question"
+msgid_plural "%(q_num)s questions"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+#: forum/skins/default/templates/questions.html:147
+#, python-format
+msgid "with %(author_name)s's contributions"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:151
+msgid "tagged"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:157
+msgid "Search tips:"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:161
+msgid "reset author"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:165
+msgid "reset tags"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:169
+#: forum/skins/default/templates/questions.html:173
+msgid "start over"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:175
+msgid " - to expand, or dig in by adding more tags and revising the query."
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:178
+msgid "Search tip:"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:178
+msgid "add tags and a query to focus your search"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:190
+msgid "There are no unanswered questions here"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:193
+msgid "No favorite questions here. "
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:194
+msgid "Please start (bookmark) some questions when you visit them"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:199
+msgid "You can expand your search by "
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:203
+msgid "resetting author"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:207
+msgid "resetting tags"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:211
+#: forum/skins/default/templates/questions.html:215
+msgid "starting over"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:220
+msgid "Please always feel free to ask your question!"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:224
+msgid "Did not find what you were looking for?"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:225
+msgid "Please, post your question!"
+msgstr ""
+
+#: forum/skins/default/templates/questions.html:243
+msgid "Related tags"
+msgstr ""
+
+#: forum/skins/default/templates/reopen.html:6
+#: forum/skins/default/templates/reopen.html:16
+msgid "Reopen question"
+msgstr ""
+
+#: forum/skins/default/templates/reopen.html:19
+msgid "Open the previously closed question"
+msgstr ""
+
+#: forum/skins/default/templates/reopen.html:22
+msgid "The question was closed for the following reason "
+msgstr ""
+
+#: forum/skins/default/templates/reopen.html:22
+msgid "reason - leave blank in english"
+msgstr ""
+
+#: forum/skins/default/templates/reopen.html:22
+msgid "on "
+msgstr ""
+
+#: forum/skins/default/templates/reopen.html:22
+msgid "date closed"
+msgstr ""
+
+#: forum/skins/default/templates/reopen.html:29
+msgid "Reopen this question"
+msgstr ""
+
+#: forum/skins/default/templates/revisions_answer.html:7
+#: forum/skins/default/templates/revisions_answer.html:38
+#: forum/skins/default/templates/revisions_question.html:8
+#: forum/skins/default/templates/revisions_question.html:38
+msgid "Revision history"
+msgstr ""
+
+#: forum/skins/default/templates/revisions_answer.html:50
+#: forum/skins/default/templates/revisions_question.html:50
+msgid "click to hide/show revision"
+msgstr ""
+
+#: forum/skins/default/templates/tag_selector.html:5
+msgid "Interesting tags"
+msgstr ""
+
+#: forum/skins/default/templates/tag_selector.html:15
+#, python-format
+msgid "remove '%(tag_name)s' from the list of interesting tags"
+msgstr ""
+
+#: forum/skins/default/templates/tag_selector.html:21
+#: forum/skins/default/templates/tag_selector.html:38
+msgid "Add"
+msgstr ""
+
+#: forum/skins/default/templates/tag_selector.html:22
+msgid "Ignored tags"
+msgstr ""
+
+#: forum/skins/default/templates/tag_selector.html:32
+#, python-format
+msgid "remove '%(tag_name)s' from the list of ignored tags"
+msgstr ""
+
+#: forum/skins/default/templates/tag_selector.html:41
+msgid "keep ignored questions hidden"
+msgstr ""
+
+#: forum/skins/default/templates/tags.html:6
+#: forum/skins/default/templates/tags.html:30
+msgid "Tag list"
+msgstr ""
+
+#: forum/skins/default/templates/tags.html:32
+msgid "sorted alphabetically"
+msgstr ""
+
+#: forum/skins/default/templates/tags.html:32
+msgid "by name"
+msgstr ""
+
+#: forum/skins/default/templates/tags.html:33
+msgid "sorted by frequency of tag use"
+msgstr ""
+
+#: forum/skins/default/templates/tags.html:33
+msgid "by popularity"
+msgstr ""
+
+#: forum/skins/default/templates/tags.html:39
+#, python-format
+msgid ""
+"All tags matching '<span class=\"darkred\"><strong>%(stag)s</strong></span>'"
+msgstr ""
+
+#: forum/skins/default/templates/tags.html:42
+msgid "Nothing found"
+msgstr ""
+
+#: forum/skins/default/templates/user_edit.html:6
+msgid "Edit user profile"
+msgstr ""
+
+#: forum/skins/default/templates/user_edit.html:19
+msgid "edit profile"
+msgstr ""
+
+#: forum/skins/default/templates/user_edit.html:33
+#: forum/skins/default/templates/user_info.html:53
+msgid "Registered user"
+msgstr ""
+
+#: forum/skins/default/templates/user_edit.html:40
+msgid "Screen Name"
+msgstr ""
+
+#: forum/skins/default/templates/user_edit.html:83
+#: forum/skins/default/templates/user_email_subscriptions.html:20
+msgid "Update"
+msgstr ""
+
+#: forum/skins/default/templates/user_email_subscriptions.html:8
+msgid "Email subscription settings"
+msgstr ""
+
+#: forum/skins/default/templates/user_email_subscriptions.html:9
+msgid "email subscription settings info"
+msgstr ""
+
+#: forum/skins/default/templates/user_email_subscriptions.html:21
+msgid "Stop sending email"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:18
+msgid "change picture"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:25
+#: forum/skins/default/templates/users.html:26 forum/views/users.py:921
+msgid "reputation"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:35
+msgid "Moderate this user"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:47
+msgid "update profile"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:57
+msgid "real name"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:62
+msgid "member for"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:67
+msgid "last seen"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:73
+msgid "user website"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:79
+msgid "location"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:86
+msgid "age"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:87
+msgid "age unit"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:93
+msgid "todays unused votes"
+msgstr ""
+
+#: forum/skins/default/templates/user_info.html:94
+msgid "votes left"
+msgstr ""
+
+#: forum/skins/default/templates/user_reputation.html:29
+msgid "Your karma change log."
+msgstr ""
+
+#: forum/skins/default/templates/user_reputation.html:31
+#, python-format
+msgid "%(user_name)s's karma change log"
+msgstr ""
+
+#: forum/skins/default/templates/user_stats.html:12
+#, python-format
+msgid ""
+"\n"
+" <span class=\"count\">1</span> Question\n"
+" "
+msgid_plural ""
+"\n"
+" <span class=\"count\">%(counter)s</span> Questions\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/user_stats.html:23
+#, python-format
+msgid ""
+"\n"
+" <span class=\"count\">1</span> Answer\n"
+" "
+msgid_plural ""
+"\n"
+" <span class=\"count\">%(counter)s</span> Answers\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/user_stats.html:36
+#, python-format
+msgid "the answer has been voted for %(answer_score)s times"
+msgstr ""
+
+#: forum/skins/default/templates/user_stats.html:36
+msgid "this answer has been selected as correct"
+msgstr ""
+
+#: forum/skins/default/templates/user_stats.html:46
+#, python-format
+msgid ""
+"\n"
+" (one comment)\n"
+" "
+msgid_plural ""
+"\n"
+" the answer has been commented %(comment_count)s times\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/user_stats.html:61
+#, python-format
+msgid ""
+"\n"
+" <span class=\"count\">1</span> Vote\n"
+" "
+msgid_plural ""
+"\n"
+" <span class=\"count\">%(cnt)s</span> Votes\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/user_stats.html:72
+msgid "thumb up"
+msgstr ""
+
+#: forum/skins/default/templates/user_stats.html:73
+msgid "user has voted up this many times"
+msgstr ""
+
+#: forum/skins/default/templates/user_stats.html:77
+msgid "thumb down"
+msgstr ""
+
+#: forum/skins/default/templates/user_stats.html:78
+msgid "user voted down this many times"
+msgstr ""
+
+#: forum/skins/default/templates/user_stats.html:87
+#, python-format
+msgid ""
+"\n"
+" <span class=\"count\">1</span> Tag\n"
+" "
+msgid_plural ""
+"\n"
+" <span class=\"count\">%(counter)s</span> Tags\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/user_stats.html:100
+#, python-format
+msgid ""
+"see other questions with %(view_user)s's contributions tagged '%(tag_name)s' "
+msgstr ""
+
+#: forum/skins/default/templates/user_stats.html:115
+#, python-format
+msgid ""
+"\n"
+" <span class=\"count\">1</span> Badge\n"
+" "
+msgid_plural ""
+"\n"
+" <span class=\"count\">%(counter)s</span> Badges\n"
+" "
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/skins/default/templates/user_tabs.html:7
+msgid "User profile"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:7 forum/views/users.py:895
+msgid "overview"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:9 forum/views/users.py:903
+msgid "recent activity"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:12 forum/views/users.py:913
+msgid "comments and answers to others questions"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:13 forum/views/users.py:912
+msgid "responses"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:16
+msgid "graph of user reputation"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:17
+msgid "reputation history"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:20 forum/views/users.py:939
+msgid "user vote record"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:20 forum/views/users.py:938
+msgid "casted votes"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:23
+msgid "questions that user selected as his/her favorite"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:24
+msgid "favorites"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:27 forum/views/users.py:948
+msgid "email subscription settings"
+msgstr ""
+
+#: forum/skins/default/templates/user_tabs.html:28 forum/views/users.py:947
+msgid "email subscriptions"
+msgstr ""
+
+#: forum/skins/default/templates/users.html:6
+#: forum/skins/default/templates/users.html:24
+msgid "Users"
+msgstr ""
+
+#: forum/skins/default/templates/users.html:27
+msgid "recent"
+msgstr ""
+
+#: forum/skins/default/templates/users.html:29
+msgid "by username"
+msgstr ""
+
+#: forum/skins/default/templates/users.html:35
+#, python-format
+msgid "users matching query %(suser)s:"
+msgstr ""
+
+#: forum/skins/default/templates/users.html:39
+msgid "Nothing found."
+msgstr ""
+
+#: forum/skins/default/templates/users_questions.html:11
+msgid "this questions was selected as favorite"
+msgstr ""
+
+#: forum/skins/default/templates/users_questions.html:12
+msgid "thumb-up on"
+msgstr ""
+
+#: forum/skins/default/templates/users_questions.html:19
+msgid "thumb-up off"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:3
+#: forum/skins/default/templates/authopenid/changeemail.html:9
+#: forum/skins/default/templates/authopenid/changeemail.html:38
+msgid "Change email"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:11
+msgid "Save your email address"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:16
+#, python-format
+msgid "change %(email)s info"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:18
+#, python-format
+msgid "here is why email is required, see %(gravatar_faq_url)s"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:31
+msgid "Your new Email"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:31
+msgid "Your Email"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:38
+msgid "Save Email"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:49
+msgid "Validate email"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:52
+#, python-format
+msgid "validate %(email)s info or go to %(change_email_url)s"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:57
+msgid "Email not changed"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:60
+#, python-format
+msgid "old %(email)s kept, if you like go to %(change_email_url)s"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:65
+msgid "Email changed"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:68
+#, python-format
+msgid "your current %(email)s can be used for this"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:73
+msgid "Email verified"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:76
+msgid "thanks for verifying email"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:81
+msgid "email key not sent"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeemail.html:84
+#, python-format
+msgid "email key not sent %(email)s change email here %(change_link)s"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeopenid.html:8
+msgid "Account: change OpenID URL"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeopenid.html:12
+msgid ""
+"This is where you can change your OpenID URL. Make sure you remember it!"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeopenid.html:14
+#: forum/skins/default/templates/authopenid/delete.html:14
+#: forum/skins/default/templates/authopenid/delete.html:24
+msgid "Please correct errors below:"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changeopenid.html:29
+msgid "OpenID URL:"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changepw.html:7
+msgid "Account: change password"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/changepw.html:8
+msgid "This is where you can change your password. Make sure you remember it!"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:19
+msgid "Connect your OpenID with this site"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:22
+msgid "Connect your OpenID with your account on this site"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:27
+#, python-format
+msgid "register new %(provider)s account info, see %(gravatar_faq_url)s"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:31
+#, python-format
+msgid ""
+"%(username)s already exists, choose another name for \n"
+" %(provider)s. Email is required too, see %"
+"(gravatar_faq_url)s\n"
+" "
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:35
+#, python-format
+msgid ""
+"register new external %(provider)s account info, see %(gravatar_faq_url)s"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:38
+#, python-format
+msgid "register new Facebook connect account info, see %(gravatar_faq_url)s"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:42
+msgid "This account already exists, please use another."
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:57
+msgid "Sorry, looks like we have some errors:"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:82
+msgid "Screen name label"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:89
+msgid "Email address label"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:95
+#: forum/skins/default/templates/authopenid/signup.html:18
+msgid "receive updates motivational blurb"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:99
+#: forum/skins/default/templates/authopenid/signup.html:22
+msgid "please select one of the options above"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:102
+msgid "Tag filter tool will be your right panel, once you log in."
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:103
+msgid "create account"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:112
+msgid "Existing account"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:113
+msgid "user name"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:114
+msgid "password"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:121
+msgid "Register"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/complete.html:122
+#: forum/skins/default/templates/authopenid/signin.html:168
+msgid "Forgot your password?"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/confirm_email.txt:2
+msgid "Thank you for registering at our Q&A forum!"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/confirm_email.txt:4
+msgid "Your account details are:"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/confirm_email.txt:6
+msgid "Username:"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/confirm_email.txt:7
+#: forum/skins/default/templates/authopenid/delete.html:19
+msgid "Password:"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/confirm_email.txt:9
+msgid "Please sign in here:"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/confirm_email.txt:12
+#: forum/skins/default/templates/authopenid/email_validation.txt:14
+#: forum/skins/default/templates/authopenid/sendpw_email.txt:8
+msgid ""
+"Sincerely,\n"
+"Forum Administrator"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/delete.html:8
+msgid "Account: delete account"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/delete.html:12
+msgid ""
+"Note: After deleting your account, anyone will be able to register this "
+"username."
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/delete.html:16
+msgid "Check confirm box, if you want delete your account."
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/delete.html:31
+msgid "I am sure I want to delete my account."
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/delete.html:32
+msgid "Password/OpenID URL"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/delete.html:32
+msgid "(required for your security)"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/delete.html:34
+msgid "Delete account permanently"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/email_validation.txt:2
+msgid "Greetings from the Q&A forum"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/email_validation.txt:4
+msgid "To make use of the Forum, please follow the link below:"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/email_validation.txt:8
+msgid "Following the link above will help us verify your email address."
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/email_validation.txt:10
+msgid ""
+"If you beleive that this message was sent in mistake - \n"
+"no further action is needed. Just ingore this email, we apologize\n"
+"for any inconvenience"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/external_legacy_login_info.html:4
+#: forum/skins/default/templates/authopenid/external_legacy_login_info.html:7
+msgid "Traditional login information"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/external_legacy_login_info.html:12
+#, python-format
+msgid ""
+"how to login with password through external login website or use %"
+"(feedback_url)s"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/sendpw.html:4
+#: forum/skins/default/templates/authopenid/sendpw.html:7
+msgid "Send new password"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/sendpw.html:10
+msgid "password recovery information"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/sendpw.html:21
+msgid "Reset password"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/sendpw.html:22
+msgid "return to login"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/sendpw_email.txt:2
+#, python-format
+msgid ""
+"Someone has requested to reset your password on %(site_url)s.\n"
+"If it were not you, it is safe to ignore this email."
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/sendpw_email.txt:5
+#, python-format
+msgid ""
+"email explanation how to use new %(password)s for %(username)s\n"
+"with the %(key_link)s"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:5
+#: forum/skins/default/templates/authopenid/signin.html:21
+msgid "User login"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:28
+#, python-format
+msgid ""
+"\n"
+" Your answer to %(title)s %(summary)s will be posted once you "
+"log in\n"
+" "
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:35
+#, python-format
+msgid ""
+"Your question \n"
+" %(title)s %(summary)s will be posted once you log in\n"
+" "
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:42
+msgid "Click to sign in through any of these services."
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:144
+msgid "Enter your <span id=\"enter_your_what\">Provider user name</span>"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:151
+msgid ""
+"Enter your <a class=\"openid_logo\" href=\"http://openid.net\">OpenID</a> "
+"web address"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:153
+#: forum/skins/default/templates/authopenid/signin.html:166
+msgid "Login"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:157
+msgid "Enter your login name and password"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:161
+msgid "Login name"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:163
+msgid "Password"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:167
+msgid "Create account"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:178
+msgid "Why use OpenID?"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:181
+msgid "with openid it is easier"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:184
+msgid "reuse openid"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:187
+msgid "openid is widely adopted"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:190
+msgid "openid is supported open standard"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:195
+msgid "Find out more"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signin.html:196
+msgid "Get OpenID"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signup.html:4
+msgid "Signup"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signup.html:8
+msgid "Create login name and password"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signup.html:10
+msgid "Traditional signup info"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signup.html:25
+msgid ""
+"Please read and type in the two words below to help us prevent automated "
+"account creation."
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signup.html:27
+msgid "Create Account"
+msgstr ""
+
+#: forum/skins/default/templates/authopenid/signup.html:29
+msgid "return to OpenID login"
+msgstr ""
+
+#: forum/skins/default/templates/fbconnect/xd_receiver.html:5
+#, python-format
+msgid "Connect to %(APP_SHORT_NAME)s with Facebook!"
+msgstr ""
+
+#: forum/templatetags/extra_tags.py:175 forum/templatetags/extra_tags.py:202
+msgid "reputation points"
+msgstr ""
+
+#: forum/templatetags/extra_tags.py:262
+msgid "2 days ago"
+msgstr ""
+
+#: forum/templatetags/extra_tags.py:264
+msgid "yesterday"
+msgstr ""
+
+#: forum/templatetags/extra_tags.py:266
+#, python-format
+msgid "%(hr)d hour ago"
+msgid_plural "%(hr)d hours ago"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/templatetags/extra_tags.py:268
+#, python-format
+msgid "%(min)d min ago"
+msgid_plural "%(min)d mins ago"
+msgstr[0] ""
+msgstr[1] ""
+
+#: forum/utils/forms.py:30
+msgid "this field is required"
+msgstr ""
+
+#: forum/utils/forms.py:45
+msgid "choose a username"
+msgstr ""
+
+#: forum/utils/forms.py:50
+msgid "user name is required"
+msgstr ""
+
+#: forum/utils/forms.py:51
+msgid "sorry, this name is taken, please choose another"
+msgstr ""
+
+#: forum/utils/forms.py:52
+msgid "sorry, this name is not allowed, please choose another"
+msgstr ""
+
+#: forum/utils/forms.py:53
+msgid "sorry, there is no user with this name"
+msgstr ""
+
+#: forum/utils/forms.py:54
+msgid "sorry, we have a serious error - user name is taken by several users"
+msgstr ""
+
+#: forum/utils/forms.py:55
+msgid "user name can only consist of letters, empty space and underscore"
+msgstr ""
+
+#: forum/utils/forms.py:109
+msgid "your email address"
+msgstr ""
+
+#: forum/utils/forms.py:110
+msgid "email address is required"
+msgstr ""
+
+#: forum/utils/forms.py:112
+msgid "this email is already used by someone else, please choose another"
+msgstr ""
+
+#: forum/utils/forms.py:140
+msgid "choose password"
+msgstr ""
+
+#: forum/utils/forms.py:141
+msgid "password is required"
+msgstr ""
+
+#: forum/utils/forms.py:144
+msgid "retype password"
+msgstr ""
+
+#: forum/utils/forms.py:145
+msgid "please, retype your password"
+msgstr ""
+
+#: forum/utils/forms.py:146
+msgid "sorry, entered passwords did not match, please try again"
+msgstr ""
+
+#: forum/views/auth.py:104 forum/views/auth.py:113
+msgid ""
+"Sorry, these login credentials belong to anoother user. Plese terminate your "
+"current session and try again."
+msgstr ""
+
+#: forum/views/auth.py:106
+msgid "You are already logged in with that user."
+msgstr ""
+
+#: forum/views/auth.py:111
+msgid "These login credentials are already associated with your account."
+msgstr ""
+
+#: forum/views/auth.py:117
+msgid "The new credentials are now associated with your account"
+msgstr ""
+
+#: forum/views/auth.py:155
+msgid ""
+"Oops, something went wrong in the middle of this process. Please try again."
+msgstr ""
+
+#: forum/views/auth.py:215
+msgid "Temporary login link"
+msgstr ""
+
+#: forum/views/auth.py:220
+msgid "An email has been sent with your temporary login key"
+msgstr ""
+
+#: forum/views/auth.py:235
+msgid ""
+"You are logged in with a temporary access key, please take the time to fix "
+"your issue with authentication."
+msgstr ""
+
+#: forum/views/auth.py:241
+msgid "Email Validation"
+msgstr ""
+
+#: forum/views/auth.py:252
+msgid "Thank you, your email is now validated."
+msgstr ""
+
+#: forum/views/auth.py:276
+msgid "Your password was changed"
+msgstr ""
+
+#: forum/views/auth.py:278
+msgid "New password set"
+msgstr ""
+
+#: forum/views/auth.py:311
+#, python-format
+msgid "You removed the association with %s"
+msgstr ""
+
+#: forum/views/auth.py:350
+#, python-format
+msgid "Welcome back %s, you are now logged in"
+msgstr ""
+
+#: forum/views/commands.py:209
+#, python-format
+msgid "subscription saved, %(email)s needs validation, see %(details_url)s"
+msgstr ""
+
+#: forum/views/commands.py:217
+msgid "email update frequency has been set to daily"
+msgstr ""
+
+#: forum/views/meta.py:34
+msgid "Q&A forum feedback"
+msgstr ""
+
+#: forum/views/meta.py:35
+msgid "Thanks for the feedback!"
+msgstr ""
+
+#: forum/views/meta.py:43
+msgid "We look forward to hearing your feedback! Please, give it next time :)"
+msgstr ""
+
+#: forum/views/users.py:856 forum/views/users.py:860
+msgid "changes saved"
+msgstr ""
+
+#: forum/views/users.py:866
+msgid "email updates canceled"
+msgstr ""
+
+#: forum/views/users.py:896
+msgid "user profile"
+msgstr ""
+
+#: forum/views/users.py:897
+msgid "user profile overview"
+msgstr ""
+
+#: forum/views/users.py:904
+msgid "recent user activity"
+msgstr ""
+
+#: forum/views/users.py:905
+msgid "profile - recent activity"
+msgstr ""
+
+#: forum/views/users.py:914
+msgid "profile - responses"
+msgstr ""
+
+#: forum/views/users.py:922
+msgid "user reputation in the community"
+msgstr ""
+
+#: forum/views/users.py:923
+msgid "profile - user reputation"
+msgstr ""
+
+#: forum/views/users.py:929
+msgid "favorite questions"
+msgstr ""
+
+#: forum/views/users.py:930
+msgid "users favorite questions"
+msgstr ""
+
+#: forum/views/users.py:931
+msgid "profile - favorite questions"
+msgstr ""
+
+#: forum/views/users.py:940
+msgid "profile - votes"
+msgstr ""
+
+#: forum/views/users.py:949
+msgid "profile - email subscriptions"
+msgstr ""
+
+#: forum/views/writers.py:70
+msgid "uploading images is limited to users with >60 reputation points"
+msgstr ""
+
+#: forum/views/writers.py:72
+msgid "allowed file types are 'jpg', 'jpeg', 'gif', 'bmp', 'png', 'tiff'"
+msgstr ""
+
+#: forum/views/writers.py:74
+#, python-format
+msgid "maximum upload file size is %sK"
+msgstr ""
+
+#: forum/views/writers.py:76
+#, python-format
+msgid ""
+"Error uploading file. Please contact the site administrator. Thank you. %s"
+msgstr ""
+
+#: forum_modules/books/urls.py:7 forum_modules/books/urls.py:8
+#: forum_modules/books/urls.py:9
+msgid "books/"
+msgstr ""
+
+#: stackexchange/management/commands/load_stackexchange.py:124
+msgid "Congratulations, you are now an Administrator"
+msgstr ""
diff --git a/settings.py b/settings.py
index 65aa0d41..f9b776cd 100644
--- a/settings.py
+++ b/settings.py
@@ -31,6 +31,7 @@ MIDDLEWARE_CLASSES = (
#'recaptcha_django.middleware.ReCaptchaMiddleware',
'django.middleware.transaction.TransactionMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware',
+ 'forum.middleware.view_log.ViewLogMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = (
@@ -73,7 +74,8 @@ INSTALLED_APPS = (
'forum',
'django_authopenid',
'debug_toolbar' ,
- #'stackexchange', #se loader
+ #'forum.importers.stackexchange', #se loader
+ 'south',
)
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)