summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--askbot/doc/source/compile-time-configuration.rst38
-rw-r--r--askbot/doc/source/cron-jobs.rst16
-rw-r--r--askbot/doc/source/debugging.rst32
-rw-r--r--askbot/doc/source/dependencies.rst38
-rw-r--r--askbot/doc/source/deployment.rst118
-rw-r--r--askbot/doc/source/git.rst13
-rw-r--r--askbot/doc/source/index.rst282
-rw-r--r--askbot/doc/source/initialize-database-tables.rst47
-rw-r--r--askbot/doc/source/install-easy-install.rst45
-rw-r--r--askbot/doc/source/pre-requisites.rst42
-rw-r--r--askbot/doc/source/run-time-configuration.rst21
-rw-r--r--askbot/migrations/0017_add_group__moderators.py302
12 files changed, 714 insertions, 280 deletions
diff --git a/askbot/doc/source/compile-time-configuration.rst b/askbot/doc/source/compile-time-configuration.rst
new file mode 100644
index 00000000..3e15dde4
--- /dev/null
+++ b/askbot/doc/source/compile-time-configuration.rst
@@ -0,0 +1,38 @@
+.. _compile-time-configuration:
+
+===============================
+Initial Configuration of Askbot
+===============================
+
+While most configuration settings for askbot can be done at any time :ref:`through the web-interface <run-time-configuration>`, some manipulations on the server are still necessary.
+
+When you are installing askbot the first time you will need to initialize the site setup files by typing::
+
+ startforum
+
+and answering the questions.
+
+The startforum script will attempt to create necessary directories and copy files.
+
+If you are creating a brand new Django project, then you will need to edit file `settings.py`_
+
+In the case you are adding askbot to an existing Django project, you will need to
+merge askbot files settings.py_ and urls.py_ into your project files manually.
+
+.. note::
+
+ Files settings.py_ and urls.py_ may also need to be touched up
+ when you upgrate the software, because new versions may bring
+ new dependencies and add new site urls.
+
+
+Within settings.py, at the very minimum you will need to provide correct values to::
+
+ DATABASE_NAME = ''
+ DATABASE_USER = ''
+ DATABASE_PASSWORD = ''
+
+within single quotes - login credentials to your mysql database.
+
+.. _urls.py: http://github.com/ASKBOT/askbot-devel/blob/master/askbot/setup_templates/urls.py
+.. _settings.py: http://github.com/ASKBOT/askbot-devel/blob/master/askbot/setup_templates/settings.py
diff --git a/askbot/doc/source/cron-jobs.rst b/askbot/doc/source/cron-jobs.rst
new file mode 100644
index 00000000..db96a532
--- /dev/null
+++ b/askbot/doc/source/cron-jobs.rst
@@ -0,0 +1,16 @@
+==========================================
+Automation of maintenance jobs with cron
+==========================================
+
+There are routine tasks that should be performed periodically
+from the command line. They can be automated via cron_ jobs
+
+File askbot_cron_job_ has a sample script that can be run say hourly
+
+The script currently does two things: (1) sends delayed email alerts and
+(2) awards badges. These two actions can be separated into two separate jobs,
+if necessary
+
+.. _cron: http://www.unixgeeks.org/security/newbie/unix/cron-1.html
+.. _askbot_cron_job: http://github.com/ASKBOT/askbot-devel/blob/master/askbot/cron/askbot_cron_job
+
diff --git a/askbot/doc/source/debugging.rst b/askbot/doc/source/debugging.rst
index 017d41d9..4b46ee58 100644
--- a/askbot/doc/source/debugging.rst
+++ b/askbot/doc/source/debugging.rst
@@ -1,9 +1,14 @@
+.. _debugging:
+
+================================================
+Debugging Askbot (and other Django applications)
+================================================
+
This document describes techniques that can be used to debug Askbot and other Django projects
If you discover new debugging techniques, please add here.
-===================
-USE LOGGING IN CODE
-===================
+Use logging in code
+---------------------
Please remember that log files may contain plaintext passwords, etc.
@@ -11,6 +16,7 @@ Please do not add print statements - at least do not commit them to git
because in some environments printing to stdout causes errors
Instead use python logging this way::
+
#somewere on top of file
import logging
@@ -27,17 +33,21 @@ please update it if you need - in older revs logging strings have less info
messages of interest can be grepped out of the log file by module/file/function name
e.g. to take out all django_authopenid logs run::
+
>grep 'askbot\/django_authopenid' log/django.askbot.log | sed 's/^.*MSG: //'
in the example above `sed` call truncates out a long prefix
and makes output look more meaningful
-=====================
-DJANGO DEBUG TOOLBAR
-=====================
+Using django debug toolbar
+---------------------------
+
+Askbot works with django debug toolbar that displays a lot of useful diagnostics about
+your site.
+
+To enable the toolbar set parameter `DEBUG = True` in the `settings.py` file. Also you will
+need to add your IP address to the tuple `INTERNAL_IPS` in the same `settings.py` file.
-askbot works with django debug toolbar
-if debugging under apache server, check
-that debug toolbar media is loaded correctly
-if toolbar is enabled but you do not see it, possibly some Alias statement
-in apache config is wrong in your VirtualHost or elsewhere
+If your debugging site runs under apache server, check
+that debug toolbar media is loaded correctly through an `alias` configuration directive in
+the appropriate place of your apache configuration file.
diff --git a/askbot/doc/source/dependencies.rst b/askbot/doc/source/dependencies.rst
new file mode 100644
index 00000000..3cd992ce
--- /dev/null
+++ b/askbot/doc/source/dependencies.rst
@@ -0,0 +1,38 @@
+.. _dependencies:
+
+===================
+Askbot Dependencies
+===================
+
+Askbot depends on quite a few other packages. Normally those dependencies will be
+automatically resolved with setuptools (i.e. when you run `easy_install` or `python setup.py install`).
+
+However, if something does not go well - e.g.
+some dependency package site is not accessible, please
+download and install them manually:
+
+* django-1.1.2_
+* django-debug-toolbar_
+* South_
+* recaptcha-client_
+* markdown2_
+* html5lib_
+* python-openid_
+* django-keyedcache_
+* django-threaded-multihost_
+* mysql-python_
+
+If any of the provided links
+do not work please try to look up those packages or notify askbot maintainers at admin@askbot.org.
+
+.. _django-1.1.2: http://www.djangoproject.com/download/1.1.2/tarball/
+.. _django-debug-toolbar: http://github.com/robhudson/django-debug-toolbar
+.. _South: http://www.aeracode.org/releases/south/
+.. _recaptcha-client: http://code.google.com/p/django-recaptcha/
+.. _markdown2: http://code.google.com/p/python-markdown2/
+.. _html5lib: http://code.google.com/p/html5lib/
+.. _python-openid: http://github.com/openid/python-openid
+.. _django-keyedcache: http://bitbucket.org/bkroeze/django-keyedcache/src
+.. _django-threaded-multihost: http://bitbucket.org/bkroeze/django-threaded-multihost/src
+.. _mysql-python: http://sourceforge.net/projects/mysql-python/
+.. _mod_wsgi: http://code.google.com/p/modwsgi/
diff --git a/askbot/doc/source/deployment.rst b/askbot/doc/source/deployment.rst
new file mode 100644
index 00000000..12eb00fe
--- /dev/null
+++ b/askbot/doc/source/deployment.rst
@@ -0,0 +1,118 @@
+.. _deployment:
+
+================
+Deploying Askbot
+================
+
+Deploying askbot (assuming that it is already installed) entails:
+
+* setting correct file access permissions
+* configuring the webserver to work with your application
+
+This document currently explains the configuration under Apache and mod_wsgi_.
+
+Setting up file access permissions
+----------------------------------
+
+Webserver process must be able to write to the following locations within your project::
+
+ log/
+ askbot/upfiles
+
+If you know user name or the group name under which the webserver runs,
+you can make those directories writable by setting the permissons
+accordingly:
+
+For example, if you are using Linux installation of apache webserver running under
+group name 'apache' you could do the following::
+
+ cd /path/to/django-project
+ cd .. #go one level up
+ chown -R yourlogin:apache django-project
+ chmod -R g+w django-project/askbot/upfiles
+ chmod -R g+w django-project/log
+
+If your account somehow limits you from running such commands - please consult your
+system administrator.
+
+Installation under Apache/mod\_wsgi
+------------------------------------
+
+Apache/mod\_wsgi combination is the only type of deployment described in this
+document at the moment. mod_wsgi_ is currently the most resource efficient
+apache handler for the Python web applications.
+
+The main wsgi script is in the file django.wsgi_
+it does not need to be modified
+
+Configure webserver
+~~~~~~~~~~~~~~~~~~~~
+
+Settings below are not perfect but may be a good starting point::
+
+ #NOTE: the directory paths used here may be adjusted
+
+ #the following two directories must be both readable and writable by apache
+ WSGISocketPrefix /path/to/socket/sock
+ WSGIPythonEggs /var/python/eggs
+
+ #the following directory must be readable by apache
+ WSGIPythonHome /usr/local
+
+ #NOTE: all urs below will need to be adjusted if
+ #settings.FORUM_SCRIPT_ALIAS is anything other than empty string (e.g. = 'forum/')
+ #this allows "rooting" forum at http://example.com/forum, if you like
+
+ #replace with 127.0.0.1 with real IP address
+ <VirtualHost 127.0.0.1:80>
+ ServerAdmin you@example.com
+ DocumentRoot /path/to/django-project
+ ServerName example.come
+
+ #aliases to serve static media directly
+ #will probably need adjustment
+ Alias /m/ /usr/local/lib/python2.6/site-packages/askbot/skins/default/media/
+ Alias /upfiles/ /path/to/django-project/askbot/upfiles/
+ Alias /admin/media/ /usr/local/lib/python2.6/site-packages/django/contrib/admin/media/
+ <DirectoryMatch "/path/to/django-project/askbot/skins/([^/]+)/media">
+ Order deny,allow
+ Allow from all
+ </DirectoryMatch>
+ <Directory "/path/to/django-project/askbot/upfiles">
+ Order deny,allow
+ Allow from all
+ </Directory>
+ #must be a distinct name within your apache configuration
+ WSGIDaemonProcess askbot2
+ WSGIProcessGroup askbot2
+ WSGIScriptAlias / /path/to/django-project/django.wsgi
+ #make all admin stuff except media go through secure connection
+ <LocationMatch "/admin(?!/media)">
+ RewriteEngine on
+ RewriteRule /admin(.*)$ https://example.com/admin$1 [L,R=301]
+ </LocationMatch>
+ CustomLog /var/log/httpd/askbot/access_log common
+ ErrorLog /var/log/httpd/askbot/error_log
+ LogLevel debug
+ </VirtualHost>
+ #again, replace the IP address
+ <VirtualHost 127.0.0.1:443>
+ ServerAdmin you@example.com
+ DocumentRoot /path/to/django-project
+ ServerName example.com
+ <LocationMatch "^(?!/admin)">
+ RewriteEngine on
+ RewriteRule django.wsgi(.*)$ http://example.com$1 [L,R=301]
+ </LocationMatch>
+ SSLEngine on
+ #your SSL keys
+ SSLCertificateFile /etc/httpd/ssl.crt/server.crt
+ SSLCertificateKeyFile /etc/httpd/ssl.key/server.key
+ Alias /admin/media/ /usr/local/lib/python2.6/site-packages/django/contrib/admin/media/
+ WSGIScriptAlias / /path/to/django-project/django.wsgi
+ CustomLog /var/log/httpd/askbot/access_log common
+ ErrorLog /var/log/httpd/askbot/error_log
+ </VirtualHost>
+
+.. _mod_wsgi: http://code.google.com/p/modwsgi/
+.. _django.wsgi: http://github.com/ASKBOT/askbot-devel/blob/master/askbot/setup_templates/django.wsgi
diff --git a/askbot/doc/source/git.rst b/askbot/doc/source/git.rst
index 1ef52ed2..9719f4bf 100644
--- a/askbot/doc/source/git.rst
+++ b/askbot/doc/source/git.rst
@@ -1,15 +1,14 @@
-==================
-Upgrading with git
-==================
+.. _upgrading-with-git:
-Git makes it easy to upgrade software, especially if your version is customized.
+===============================================
+Upgrading Askbot (and other software) with git
+===============================================
-Below is a description of a typical upgrade git session. The document assumes
-that your code is already managed with git.
+Git makes it easy to upgrade software, especially if your version is customized.
Upgrading with git consists of three steps:
-#. preparing your local repository for merge
+#. preparing your local repository for the merge
#. bringing the latest version of the code onto your system
#. merging the latest code with your work
diff --git a/askbot/doc/source/index.rst b/askbot/doc/source/index.rst
index 78ae333c..a222e314 100644
--- a/askbot/doc/source/index.rst
+++ b/askbot/doc/source/index.rst
@@ -1,279 +1,37 @@
-Askbot is a Question and Answer (Q&A) forum whose design is inspired by StackOverflow_
-and YahooAnswers_ and other similar projects (to lesser extent).
+.. _index:
-Askbot is written in Python_ on top of Django_ platform.
+=============================
+Askbot Project Documentation
+=============================
+
+Askbot is an open source Question and Answer (Q&A) forum project inspired by StackOverflow_
+and YahooAnswers_. Askbot is written in Python_ on top of the Django_ platform.
Code of Askbot grew out of CNPROG_ project originally written by
`Mike Chen <http://cn.linkedin.com/in/mikegangchen>`_ and Sailing Cai.
-If you have any questions installing or tweaking askbot - please do not hesitate to ask
-at the forum_ or by email at admin@askbot.org.
-
-Prerequisites
-======================
-To install and run Askbot the following are required:
-
-* Python_ version 2.4 - 2.6 (Version 3 is not supported)
-* MySQL_ version 5
-
-For the production deployment you will also need a webserver capable to run
-python web applications (see section Deployment_).
-
-Installation Instructions
-===========================
-
-To simplify future deployment, please make sure to use the same python
-interpreter for the installation and testing as the one assigned
-(or will be assigned) to the webserver.
-
-If you already have `easy_install`_ on your system, then type::
-
- easy_install askbot
-
-If you are using the easy\_install tool, make sure that it was also
-originally installed with the python interpreter mentioned above,
-otherwise use the second method:
-
-Download the latest version of askbot_, unzip and untar the archive and run::
-
- python setup.py install
-
-If you are planning to use askbot on Windows, please install
-`mysql-python windows binary package <http://www.codegood.com/archives/4>`_ manually.
-
-Chances are that steps above will complete your installation. If so, then
-proceed to the Configuration_ section. Below are extra installation notes
-that cover some special cases.
-
-To install in non-standard locations add parameter --prefix=/path/to/some/dir to both commands.
-
-Askbot depends on about a dozen other packages. Normally those dependencies will be
-automatically resolved. However, if something does not go well - e.g.
-some dependency package site is not accessible, please
-download and install some of those things
-(
-django-1.1.2_,
-django-debug-toolbar_,
-South_,
-recaptcha-client_,
-markdown2_,
-html5lib_,
-python-openid_,
-django-keyedcache_,
-django-threaded-multihost_,
-mysql-python_
-) manually.
-
-If any of the provided links
-do not work please try to look up those packages or notify askbot maintainers at admin@askbot.org.
-
-.. _Configuration:
-
-Configuration
-====================
-
-type::
-
- startforum
-
-and answer questions.
-
-The startforum script will attempt to create necessary directories
-and copy files.
-
-If you are creating a new Django project, you will need to edit file
-
-In the case you are adding askbot to an existing Django project, you will need to
-merge askbot files settings.py_ and urls.py_ into your project files manually.
-
-Within settings.py, at the very minimum you will need to provide correct values to::
-
- DATABASE_NAME = ''
- DATABASE_USER = ''
- DATABASE_PASSWORD = ''
-
-within single quotes - login credential to your mysql database. Assuming that
-the database exists, you can now install the tables by running::
-
- python manage.py syncdb
- python manage.py migrate forum
-
-now run the development sever::
+.. note::
- python manage.py runserver `hostname -i`:8000 #or use some other port number > 1024
+ If you have any questions installing or tweaking askbot - please do not hesitate to ask
+ at the forum_ or by email at admin@askbot.org. This documentation is in the active development
+ - if you notice any omissions - please don't hesitate to contact us.
-`hostname -i` is a Unix command returning the IP address of your system, you can also type
-the IP manually or replace it with localhost if you are installing askbot
-on a local machine.
+:ref:`Pre-requisites <pre-requisites>`
-Your basic installation is now complete. Many settings can be
-changed at runtime by following url /settings.
+Install - :ref:`latest stable version <install-easy-install>` or `development version`_.
-If you choose to host a real website, please read
-section Deployment_.
+Configure - (1) :ref:`edit settings files <compile-time-configuration>`
+(2) :ref:`initialize the application database <initialize-database-tables>` (3) :ref:`configure the running site <run-time-configuration>`
-.. _Deployment:
+Upgrade: :ref:`to next stable version <upgrade-with-easy-install>` or to the :ref:`current development version <upgrading-with-git>`
-Deployment
-==============
-Webserver process must be able to write to the following locations::
+:ref:`Maintain <maintenance>`
- /path/to/django-project/log/
- /path/to/django-project/askbot/upfiles
+:ref:`Debugging techniques <debugging>`
-If you know user name or the group name under which the webserver runs,
-you can make those directories writable by setting the permissons
-accordingly:
-
-For example, if you are using Linux installation of apache webserver running under
-group name 'apache' you could do the following::
-
- chown -R yourlogin:apache /path/to/askbot-site
- chmod -R g+w /path/to/askbot-site/forum/upfiles
- chmod -R g+w /path/to/askbot-site/log
-
-If your account somehow limits you from running such commands - please consult your
-system administrator.
-
-Installation under Apache/mod\_wsgi
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Apache/mod\_wsgi combination is the only type of deployment described in this
-document at the moment. mod_wsgi_ is currently the most resource efficient
-apache handler for the Python web applications.
-
-The main wsgi script is in the file django.wsgi_
-it does not need to be modified
-
-Configure webserver
-^^^^^^^^^^^^^^^^^^^^^^
-
-Settings below are not perfect but may be a good starting point::
-
- #NOTE: the directory paths used here may be adjusted
-
- #the following two directories must be both readable and writable by apache
- WSGISocketPrefix /path/to/socket/sock
- WSGIPythonEggs /var/python/eggs
-
- #the following directory must be readable by apache
- WSGIPythonHome /usr/local
-
- #NOTE: all urs below will need to be adjusted if
- #settings.FORUM_SCRIPT_ALIAS is anything other than empty string (e.g. = 'forum/')
- #this allows "rooting" forum at http://example.com/forum, if you like
-
- #replace with 127.0.0.1 with real IP address
- <VirtualHost 127.0.0.1:80>
- ServerAdmin you@example.com
- DocumentRoot /path/to/django-project
- ServerName example.come
-
- #aliases to serve static media directly
- #will probably need adjustment
- Alias /m/ /usr/local/lib/python2.6/site-packages/askbot/skins/default/media/
- Alias /upfiles/ /path/to/django-project/askbot/upfiles/
- Alias /admin/media/ /usr/local/lib/python2.6/site-packages/django/contrib/admin/media/
- <DirectoryMatch "/path/to/django-project/askbot/skins/([^/]+)/media">
- Order deny,allow
- Allow from all
- </DirectoryMatch>
- <Directory "/path/to/django-project/askbot/upfiles">
- Order deny,allow
- Allow from all
- </Directory>
- #must be a distinct name within your apache configuration
- WSGIDaemonProcess askbot2
- WSGIProcessGroup askbot2
- WSGIScriptAlias / /path/to/django-project/django.wsgi
- #make all admin stuff except media go through secure connection
- <LocationMatch "/admin(?!/media)">
- RewriteEngine on
- RewriteRule /admin(.*)$ https://example.com/admin$1 [L,R=301]
- </LocationMatch>
- CustomLog /var/log/httpd/askbot/access_log common
- ErrorLog /var/log/httpd/askbot/error_log
- LogLevel debug
- </VirtualHost>
- #again, replace the IP address
- <VirtualHost 127.0.0.1:443>
- ServerAdmin you@example.com
- DocumentRoot /path/to/django-project
- ServerName example.com
- <LocationMatch "^(?!/admin)">
- RewriteEngine on
- RewriteRule django.wsgi(.*)$ http://example.com$1 [L,R=301]
- </LocationMatch>
- SSLEngine on
- #your SSL keys
- SSLCertificateFile /etc/httpd/ssl.crt/server.crt
- SSLCertificateKeyFile /etc/httpd/ssl.key/server.key
- Alias /admin/media/ /usr/local/lib/python2.6/site-packages/django/contrib/admin/media/
- WSGIScriptAlias / /path/to/django-project/django.wsgi
- CustomLog /var/log/httpd/askbot/access_log common
- ErrorLog /var/log/httpd/askbot/error_log
- </VirtualHost>
-
-Database configuration
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Database can be prepared via your hosting control panel, if available or
-can be created manually (provided that you have a mysql account with
-a sufficient privilege)
-
-The relevant MySQL the commands are::
-
- create database askbot DEFAULT CHARACTER SET UTF8 COLLATE utf8_general_ci;
- grant all privileges on dbname.* to dbuser@localhost identified by 'dbpassword';
-
-where dbname, dbuser and dbpassword should be replaced with the real values.
-MySQL will create a user with those credentials if it does not yet exist.
-
-Automation of maintenance jobs
-===============================
-
-There are routine tasks that should be performed periodically
-from the command line. They can be automated via cron_ jobs
-
-File askbot_cron_job_ has a sample script that can be run say hourly
-
-The script currently does two things: (1) sends delayed email alerts and
-(2) awards badges. These two actions can be separated into two separate jobs,
-if necessary
-
-Sitemap registration
-=======================
-Sitemap to your forum will be available at url /<settings.FORUM\_SCRIPT\_ALIAS>sitemap.xml
-e.g yoursite.com/forum/sitemap.xml or yoursite.com/sitemap.xml
-
-Google will be pinged each time question, answer or
-comment is saved or a question deleted.
-
-If you register you sitemap through `Google Webmasters Tools`_ Google
-will have be indexing your site more efficiently.
-
-.. _`Google Webmasters Tools`: https://www.google.com/webmasters/tools/
.. _Python: http://www.python.org/download/
-.. _MySQL: http://www.mysql.com/downloads/mysql/#downloads
.. _YahooAnswers: http://answers.yahoo.com/
.. _StackOverflow: http://stackoverflow.com/
+.. _Django: http://djangoproject.com
.. _CNPROG: http://cnprog.com
-.. _askbot: http://pypi.python.org/pypi/askbot
-.. _django-1.1.2: http://www.djangoproject.com/download/1.1.2/tarball/
-.. _django-debug-toolbar: http://github.com/robhudson/django-debug-toolbar
-.. _South: http://www.aeracode.org/releases/south/
-.. _recaptcha-client: http://code.google.com/p/django-recaptcha/
-.. _markdown2: http://code.google.com/p/python-markdown2/
-.. _html5lib: http://code.google.com/p/html5lib/
-.. _python-openid: http://github.com/openid/python-openid
-.. _django-keyedcache: http://bitbucket.org/bkroeze/django-keyedcache/src
-.. _django-threaded-multihost: http://bitbucket.org/bkroeze/django-threaded-multihost/src
-.. _mysql-python-win:
-.. _mysql-python: http://sourceforge.net/projects/mysql-python/
-.. _settings.py: http://github.com/ASKBOT/askbot-devel/blob/master/askbot/setup_templates/settings.py
-.. _urls.py: http://github.com/ASKBOT/askbot-devel/blob/master/askbot/setup_templates/urls.py
-.. _cron: http://www.unixgeeks.org/security/newbie/unix/cron-1.html
-.. _mod_wsgi: http://code.google.com/p/modwsgi/
-.. _django.wsgi: http://github.com/ASKBOT/askbot-devel/blob/master/askbot/setup_templates/django.wsgi
.. _forum: http://askbot.org
-.. _askbot_cron_job: http://github.com/ASKBOT/askbot-devel/blob/master/askbot/cron/askbot_cron_job
-.. _Django: http://djangoproject.com
-.. _`easy_install`: http://pypi.python.org/pypi/setuptools
+.. _`development version`: http://github.com/ASKBOT/askbot-devel
diff --git a/askbot/doc/source/initialize-database-tables.rst b/askbot/doc/source/initialize-database-tables.rst
new file mode 100644
index 00000000..83e70c14
--- /dev/null
+++ b/askbot/doc/source/initialize-database-tables.rst
@@ -0,0 +1,47 @@
+.. _initialize-database-tables:
+
+=======================================================
+Initialization and upgrade of the database for Askbot
+=======================================================
+
+When you install Askbot the first time and any time you upgrade the software, run these two commands::
+
+ python manage.py syncdb
+
+When you will be suggested to create a superuser, answer **no**.
+
+Then run::
+
+ python manage.py migrate askbot
+
+.. note::
+
+ When upgrading - do not skip to back up the database before proceeding!!!
+ Things can break and it is better to be safe than sorry. Even better -
+ do run two installations of your project - one for production deployment
+ and the second one - for testing the upgrade. When you are sure that
+ your upgrade works, just switch the testing installation for the former production one.
+
+Now run the Django development server and check that everything works::
+
+ python manage.py runserver `hostname -i`:8000 #or use some other port number > 1024
+
+.. note::
+
+ `hostname -i` is a Unix command returning the IP address of your system, you can also type
+ the IP manually or replace it with word `localhost` if you are installing askbot
+ on a local machine.
+
+Finally, register at the site and turn yourself into a superuser by running::
+
+ python manage.py add_admin 1
+
+Here number 1 is the numeric id of the first user, enter a different number, if it is indeed different.
+
+Your basic installation is now complete. Many settings can be
+:ref:`changed at runtime <run-time-configuration>` by following url `/settings`.
+
+If you choose to host a real website, please read
+section :ref:`deployment`.
+
+
diff --git a/askbot/doc/source/install-easy-install.rst b/askbot/doc/source/install-easy-install.rst
new file mode 100644
index 00000000..80513d0a
--- /dev/null
+++ b/askbot/doc/source/install-easy-install.rst
@@ -0,0 +1,45 @@
+.. _install-easy-install:
+
+===========================================================
+Installing Askbot with easy_install (python package index).
+===========================================================
+
+The latest stable version of askbot can be installed from the official `Python Package Index (PyPI) <http://pypi.python.org/pypi/askbot/>`_
+
+.. note::
+
+ To simplify future deployment, please make sure to use the same python
+ interpreter for the installation and testing as the one assigned
+ (or will be assigned) to the webserver.
+ The same applies to easy_install tool, and the `PYTHONPATH`
+ environment variable.
+
+If you already have `easy_install`_ (python setuptools) on your system, then type::
+
+ easy_install askbot
+
+If you do not yet have it, download the `askbot archive from PyPI <http://pypi.python.org/pypi/askbot/>`_, unzip and untar it, then run::
+
+ python setup.py install
+
+Both command achieve the same effect, except the second one will also install the setuptools.
+
+.. note::
+
+ To install in non-standard locations add parameter ``--prefix=/path/to/some/dir`` to both commands.
+
+Under windows, please install
+`mysql-python windows binary package <http://www.codegood.com/archives/4>`_ manually.
+
+Most likely, by this time you will have askbot software installed. However, in some cases
+one of the dependency packages might fail to install. :ref:`This document <dependencies>` will help you find those components.
+
+When you have all packages installed,
+please proceed to the :ref:`initial configuration <compile-time-configuration>` section.
+
+.. _Python: http://www.python.org/download/
+.. _askbot: http://pypi.python.org/pypi/askbot
+.. _`easy_install`: http://pypi.python.org/pypi/setuptools
+.. _pypi: http://pypi.python.org/
+
+.. _django.wsgi: http://github.com/ASKBOT/askbot-devel/blob/master/askbot/setup_templates/django.wsgi
diff --git a/askbot/doc/source/pre-requisites.rst b/askbot/doc/source/pre-requisites.rst
new file mode 100644
index 00000000..83591b19
--- /dev/null
+++ b/askbot/doc/source/pre-requisites.rst
@@ -0,0 +1,42 @@
+.. _pre-requisites:
+
+=========================
+Prerequisites for Askbot
+=========================
+Askbot installation currently requires:
+
+* Python_ version 2.4 - 2.6 (Version 3 is not yet supported)
+* MySQL_ version 5
+* access to an instance of MySQL database with full privileges
+
+For the production :ref:`deployment` you will also need a webserver capable to run
+python web applications.
+
+Creating a database instance
+-----------------------------
+This section assumes that MySQL is installed and is up and running.
+
+Database can be prepared via your hosting control panel, if available, or
+can be created manually as shown below (using a high privilege MySQL account):
+
+Log in to mysql::
+
+ mysql -u username -p
+
+Then type these two commands (note that fake `dbname`, `dbuser`, and `dbpassword` are used in this example)::
+
+ create database askbot DEFAULT CHARACTER SET UTF8 COLLATE utf8_general_ci;
+ grant all privileges on dbname.* to dbuser@localhost identified by 'dbpassword';
+
+Again, please remember to create real usernname, database name and password and write them down. These
+credentials will go into the file `settings.py`_ - the main configuration file of the Django application.
+
+.. note::
+
+ Notation `dbuser@hostname` is important for security - normally you want to restrict access to
+ the database to certain hosts only. `localhost` entry ensures that database cannot be accessed
+ from remote hosts at all.
+
+.. _Python: http://www.python.org/download/
+.. _MySQL: http://www.mysql.com/downloads/mysql/#downloads
+.. _settings.py: http://github.com/ASKBOT/askbot-devel/blob/master/askbot/setup_templates/settings.py
diff --git a/askbot/doc/source/run-time-configuration.rst b/askbot/doc/source/run-time-configuration.rst
new file mode 100644
index 00000000..46ec025a
--- /dev/null
+++ b/askbot/doc/source/run-time-configuration.rst
@@ -0,0 +1,21 @@
+.. _run-time-configuration:
+
+==================================
+Run-time configuration of Askbot
+==================================
+
+Any of this can be done later via url `/settings` at your site - log in as a superuser and explore what is available.
+
+.. note::
+ Probably the first two settings you should update are the Google Site verification Key for the sitemap
+ and (if you want Google search engine crawl your site timely) the Google Analytics Key (if you wish to monitor
+ the site traffic)
+
+Google will be pinged each time question, answer or comment is saved or a question deleted and the
+site verification key is required for this to work. Please obtain the Site Verification Key at the
+`Google Webmasters Tools`_ site.
+
+There are many more settings that can be changed at any time without restarting the site. More
+documentaition on this topic will be added in the near future.
+
+.. _`Google Webmasters Tools`: https://www.google.com/webmasters/tools/
diff --git a/askbot/migrations/0017_add_group__moderators.py b/askbot/migrations/0017_add_group__moderators.py
new file mode 100644
index 00000000..910fb279
--- /dev/null
+++ b/askbot/migrations/0017_add_group__moderators.py
@@ -0,0 +1,302 @@
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from django.contrib.auth.models import Group
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+ moderators = Group(name = 'askbot_moderators')
+ moderators.save()
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+ try:
+ moderators = Group.objects.get(name = 'askbot_moderators')
+ moderators.delete()
+ except Group.DoesNotExist:
+ pass
+
+ models = {
+ 'askbot.activity': {
+ 'Meta': {'object_name': 'Activity', 'db_table': "u'activity'"},
+ 'active_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'activity_type': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_auditted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'receiving_users': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'received_activity'", 'to': "orm['auth.User']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'askbot.anonymousanswer': {
+ 'Meta': {'object_name': 'AnonymousAnswer'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ip_addr': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'anonymous_answers'", 'to': "orm['askbot.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'})
+ },
+ 'askbot.anonymousquestion': {
+ 'Meta': {'object_name': 'AnonymousQuestion'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ip_addr': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}),
+ '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'})
+ },
+ 'askbot.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['askbot.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'})
+ },
+ 'askbot.answerrevision': {
+ 'Meta': {'object_name': 'AnswerRevision', 'db_table': "u'answer_revision'"},
+ 'answer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['askbot.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', [], {})
+ },
+ 'askbot.award': {
+ 'Meta': {'object_name': 'Award', 'db_table': "u'award'"},
+ 'awarded_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'badge': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_badge'", 'to': "orm['askbot.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']"})
+ },
+ 'askbot.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', [], {})
+ },
+ 'askbot.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': '2048'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'html': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '2048'}),
+ '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']"})
+ },
+ 'askbot.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', [], {'related_name': "'notification_subscriptions'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.favoritequestion': {
+ 'Meta': {'object_name': 'FavoriteQuestion', 'db_table': "u'favorite_question'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Question']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.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']"})
+ },
+ 'askbot.markedtag': {
+ 'Meta': {'object_name': 'MarkedTag'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'reason': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
+ 'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_selections'", 'to': "orm['askbot.Tag']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.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['askbot.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'})
+ },
+ 'askbot.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['askbot.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'})
+ },
+ 'askbot.questionview': {
+ 'Meta': {'object_name': 'QuestionView'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'viewed'", 'to': "orm['askbot.Question']"}),
+ 'when': ('django.db.models.fields.DateTimeField', [], {}),
+ 'who': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'question_views'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.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['askbot.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']"})
+ },
+ 'askbot.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'})
+ },
+ 'askbot.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'})
+ },
+ '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'}),
+ 'response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ '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'})
+ }
+ }
+
+ complete_apps = ['askbot']