From e4dc9a9229205b9bbdc58a62b0411685fecf0f82 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Thu, 24 Jun 2010 21:30:14 -0400 Subject: some progress on documentation --- askbot/doc/source/compile-time-configuration.rst | 38 +++ askbot/doc/source/cron-jobs.rst | 16 ++ askbot/doc/source/debugging.rst | 32 ++- askbot/doc/source/dependencies.rst | 38 +++ askbot/doc/source/deployment.rst | 118 +++++++++ askbot/doc/source/git.rst | 13 +- askbot/doc/source/index.rst | 282 ++------------------- askbot/doc/source/initialize-database-tables.rst | 47 ++++ askbot/doc/source/install-easy-install.rst | 45 ++++ askbot/doc/source/pre-requisites.rst | 42 ++++ askbot/doc/source/run-time-configuration.rst | 21 ++ askbot/migrations/0017_add_group__moderators.py | 302 +++++++++++++++++++++++ 12 files changed, 714 insertions(+), 280 deletions(-) create mode 100644 askbot/doc/source/compile-time-configuration.rst create mode 100644 askbot/doc/source/cron-jobs.rst create mode 100644 askbot/doc/source/dependencies.rst create mode 100644 askbot/doc/source/deployment.rst create mode 100644 askbot/doc/source/initialize-database-tables.rst create mode 100644 askbot/doc/source/install-easy-install.rst create mode 100644 askbot/doc/source/pre-requisites.rst create mode 100644 askbot/doc/source/run-time-configuration.rst create mode 100644 askbot/migrations/0017_add_group__moderators.py 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 `, 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 + + 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/ + + Order deny,allow + Allow from all + + + Order deny,allow + Allow from all + + #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 + + RewriteEngine on + RewriteRule /admin(.*)$ https://example.com/admin$1 [L,R=301] + + CustomLog /var/log/httpd/askbot/access_log common + ErrorLog /var/log/httpd/askbot/error_log + LogLevel debug + + #again, replace the IP address + + ServerAdmin you@example.com + DocumentRoot /path/to/django-project + ServerName example.com + + RewriteEngine on + RewriteRule django.wsgi(.*)$ http://example.com$1 [L,R=301] + + 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 + + +.. _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 `_ 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 `_ 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 ` -Your basic installation is now complete. Many settings can be -changed at runtime by following url /settings. +Install - :ref:`latest stable version ` or `development version`_. -If you choose to host a real website, please read -section Deployment_. +Configure - (1) :ref:`edit settings files ` +(2) :ref:`initialize the application database ` (3) :ref:`configure the running site ` -.. _Deployment: +Upgrade: :ref:`to next stable version ` or to the :ref:`current development version ` -Deployment -============== -Webserver process must be able to write to the following locations:: +:ref:`Maintain ` - /path/to/django-project/log/ - /path/to/django-project/askbot/upfiles +:ref:`Debugging techniques ` -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 - - 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/ - - Order deny,allow - Allow from all - - - Order deny,allow - Allow from all - - #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 - - RewriteEngine on - RewriteRule /admin(.*)$ https://example.com/admin$1 [L,R=301] - - CustomLog /var/log/httpd/askbot/access_log common - ErrorLog /var/log/httpd/askbot/error_log - LogLevel debug - - #again, replace the IP address - - ServerAdmin you@example.com - DocumentRoot /path/to/django-project - ServerName example.com - - RewriteEngine on - RewriteRule django.wsgi(.*)$ http://example.com$1 [L,R=301] - - 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 - - -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 /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 ` 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) `_ + +.. 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 `_, 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 `_ 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 ` will help you find those components. + +When you have all packages installed, +please proceed to the :ref:`initial 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'] -- cgit v1.2.3-1-g7c22