summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAurélien Bompard <aurelien@bompard.org>2013-11-14 18:27:47 +0100
committerAurélien Bompard <aurelien@bompard.org>2013-11-20 19:15:40 +0100
commit54e10ee28d7c72f5614219e92adcc460a3b72a48 (patch)
tree07cb7af58e716231d538f749af9f396302c0ffca
parent89406e71d9541396a48370d48e40f5e6c1e4a357 (diff)
downloadhyperkitty-54e10ee28d7c72f5614219e92adcc460a3b72a48.tar.gz
hyperkitty-54e10ee28d7c72f5614219e92adcc460a3b72a48.tar.xz
hyperkitty-54e10ee28d7c72f5614219e92adcc460a3b72a48.zip
KittyStore does not auto-upgrade its schema anymore
-rw-r--r--doc/database.rst19
-rw-r--r--doc/install.rst2
-rw-r--r--hyperkitty/lib/store.py88
-rw-r--r--hyperkitty/middleware.py50
-rw-r--r--hyperkitty/templates/errors/schemaupgrade.html28
-rw-r--r--hyperkitty/tests/test_views.py6
-rw-r--r--hyperkitty/urls.py8
7 files changed, 93 insertions, 108 deletions
diff --git a/doc/database.rst b/doc/database.rst
index ade71f9..e022536 100644
--- a/doc/database.rst
+++ b/doc/database.rst
@@ -13,8 +13,7 @@ created using the following command::
python hyperkitty_standalone/manage.py syncdb
python hyperkitty_standalone/manage.py migrate hyperkitty
-KittyStore's database will be created automatically on first access, but you
-still need to configure its URI. The syntax is as follows::
+KittyStore's database is configured using an URI. The syntax is as follows::
KITTYSTORE_URL = "scheme://username:password@hostname:port/database_name"
@@ -26,18 +25,14 @@ The scheme may be "sqlite", "postgres", or "mysql". For example, with sqlite::
If you're using SQLite and you're getting "Database is locked" errors, stop
your webserver during the import.
-If you want to force the creation of the KittyStore database, you can run::
-
- kittystore-updatedb -p hyperkitty_standalone -s settings
-
-and it will be created.
-
KittyStore also uses a fulltext search engine which resides in a directory on
the filesystem. The path to this directory must be configured in the
``KITTYSTORE_SEARCH_INDEX`` variable. This directory should be writable by the
-user running Mailman and readable by the user running HyperKitty. It will be
-automatically created, but the creation can be forced using the
-``kittystore-updatedb`` command described above.
+user running Mailman and readable by the user running HyperKitty (usually your
+webserver). It will be automatically created when the regular KittyStore
+database is created. The command to create the KittyStore database is::
+
+ kittystore-updatedb -p hyperkitty_standalone -s settings
Importing the current archives
@@ -62,7 +57,7 @@ where:
* ``NAME`` is the fully-qualified list name (including the ``@`` sign and the
domain name)
* The ``mbox_file`` arguments are the existing archives to import. Make sure you point
-at the *.txt version of the files and not the *.gz.
+at the ``*.txt`` version of the files and not the ``*.gz``.
If the previous archives aren't available locally, you need to download them
from your current Mailman 2.1 installation. The ``kittystore-download21``
diff --git a/doc/install.rst b/doc/install.rst
index 1f2b17e..7c21856 100644
--- a/doc/install.rst
+++ b/doc/install.rst
@@ -128,7 +128,7 @@ from HyperKitty itself. To update the KittyStore database, just run::
kittystore-updatedb -p hyperkitty_standalone -s settings
-This command may take a long time to complete, donc interrupt it.
+This command may take a long time to complete, don't interrupt it.
Then, to update the HyperKitty database, run::
diff --git a/hyperkitty/lib/store.py b/hyperkitty/lib/store.py
deleted file mode 100644
index 400fb9a..0000000
--- a/hyperkitty/lib/store.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (C) 1998-2012 by the Free Software Foundation, Inc.
-#
-# This file is part of HyperKitty.
-#
-# HyperKitty is free software: you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free
-# Software Foundation, either version 3 of the License, or (at your option)
-# any later version.
-#
-# HyperKitty is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# HyperKitty. If not, see <http://www.gnu.org/licenses/>.
-#
-# Author: Aurelien Bompard <abompard@fedoraproject.org>
-#
-
-"""
-WSGI and Django middlewares for KittyStore
-
-Inspired by http://pypi.python.org/pypi/middlestorm
-"""
-
-from threading import local
-
-from django.conf import settings
-import kittystore
-
-
-class KittyStoreWSGIMiddleware(object):
- """WSGI middleware.
- Add KittyStore object in environ['kittystore.store']. Each thread contains
- own store.
- """
-
- def __init__(self, app):
- """Create WSGI middleware.
- :param app: top level application or middleware.
- :param database: instance of Database returned create_database.
- """
- self._app = app
- self._local = local()
-
- def __call__(self, environ, start_response):
- try:
- environ['kittystore.store'] = self._local.store
- except AttributeError:
- environ['kittystore.store'] = \
- self._local.__dict__.setdefault('store',
- kittystore.get_store(settings))
- try:
- return self._app(environ, start_response)
- finally:
- environ['kittystore.store'].rollback()
- #environ['kittystore.store'].close()
-
-
-class KittyStoreDjangoMiddleware(object):
- """Django middleware.
- Add KittyStore object in environ['kittystore.store']. Each thread contains
- own store.
- """
-
- def __init__(self):
- """Create Django middleware."""
- self._local = local()
-
- def process_request(self, request):
- try:
- request.environ['kittystore.store'] = self._local.store
- except AttributeError:
- request.environ['kittystore.store'] = \
- self._local.__dict__.setdefault('store',
- kittystore.get_store(settings))
-
- def process_response(self, request, response):
- if "kittystore.store" in request.environ:
- # kittystore.store could be absent on automatic redirects for ex.
- request.environ['kittystore.store'].commit()
- #request.environ['kittystore.store'].close()
- return response
-
- def process_exception(self, request, exception):
- request.environ['kittystore.store'].rollback()
diff --git a/hyperkitty/middleware.py b/hyperkitty/middleware.py
index 823dd88..4f48e37 100644
--- a/hyperkitty/middleware.py
+++ b/hyperkitty/middleware.py
@@ -20,6 +20,10 @@
# Author: Aurelien Bompard <abompard@fedoraproject.org>
#
+
+from django.conf import settings
+
+
class PaginationMiddleware(object):
"""
Inserts a variable representing the current page onto the request object if
@@ -33,9 +37,52 @@ class PaginationMiddleware(object):
+# KittyStore
+
+from threading import local
+from django.shortcuts import redirect
+from django.core.urlresolvers import reverse
+import kittystore
+
+class KittyStoreDjangoMiddleware(object):
+ """Django middleware.
+ Add KittyStore object in environ['kittystore.store']. Each thread contains
+ own store.
+ Inspired by http://pypi.python.org/pypi/middlestorm
+ """
+
+ def __init__(self):
+ """Create Django middleware."""
+ self._local = local()
+
+ def process_request(self, request):
+ if request.path == reverse("error_schemaupgrade"):
+ return # Display the error page
+ try:
+ request.environ['kittystore.store'] = self._local.store
+ except AttributeError:
+ try:
+ store = kittystore.get_store(settings)
+ except kittystore.SchemaUpgradeNeeded:
+ return redirect("error_schemaupgrade")
+ else:
+ request.environ['kittystore.store'] = \
+ self._local.__dict__.setdefault('store', store)
+
+ def process_response(self, request, response):
+ if "kittystore.store" in request.environ:
+ # kittystore.store could be absent on automatic redirects for ex.
+ request.environ['kittystore.store'].commit()
+ #request.environ['kittystore.store'].close()
+ return response
+
+ def process_exception(self, request, exception):
+ request.environ['kittystore.store'].rollback()
+
+
+
# http://stackoverflow.com/questions/2799450/django-https-for-just-login-page
-from django.conf import settings
from django.http import HttpResponsePermanentRedirect
SSL = 'SSL'
@@ -97,7 +144,6 @@ class TimezoneMiddleware(object):
from mailmanclient import Client as MailmanClient
from mailmanclient import MailmanConnectionError
-from django.conf import settings
class MailmanUserMetadata(object):
diff --git a/hyperkitty/templates/errors/schemaupgrade.html b/hyperkitty/templates/errors/schemaupgrade.html
new file mode 100644
index 0000000..f23281b
--- /dev/null
+++ b/hyperkitty/templates/errors/schemaupgrade.html
@@ -0,0 +1,28 @@
+{% extends "base.html" %}
+{% load url from future %}
+
+
+{% block title %}
+Error: the database schema needs an upgrade
+ - {{ app_name|title }}
+{% endblock %}
+
+{% block content %}
+
+<div class="row-fluid">
+
+ <div class="span2">
+ </div>
+
+ <div class="span7">
+ <p class="text-error">
+ The database schema needs to be upgraded. Please refer to
+ <a href="http://hyperkitty.readthedocs.org/en/latest/install.html#upgrading">the documentation</a>
+ to perform this task.
+ </p>
+ <p>When you're done, <a href="{% url 'root' %}">go back</a> to the front page.</p>
+ </div>
+
+</div>
+
+{% endblock %}
diff --git a/hyperkitty/tests/test_views.py b/hyperkitty/tests/test_views.py
index af829c2..e522f07 100644
--- a/hyperkitty/tests/test_views.py
+++ b/hyperkitty/tests/test_views.py
@@ -91,7 +91,7 @@ class LastViewsTestCase(TestCase):
def setUp(self):
self.user = User.objects.create_user('testuser', 'test@example.com', 'testPass')
self.client.login(username='testuser', password='testPass')
- store = kittystore.get_store(SettingsModule(), debug=False)
+ store = kittystore.get_store(SettingsModule(), debug=False, auto_create=True)
ml = FakeList("list@example.com")
ml.subject_prefix = u"[example] "
# Create 3 threads
@@ -267,7 +267,7 @@ class ReattachTestCase(TestCase):
self.user = User.objects.create_user('testuser', 'test@example.com', 'testPass')
self.user.is_staff = True
self.client.login(username='testuser', password='testPass')
- self.store = kittystore.get_store(SettingsModule(), debug=False)
+ self.store = kittystore.get_store(SettingsModule(), debug=False, auto_create=True)
ml = FakeList("list@example.com")
ml.subject_prefix = u"[example] "
# Create 2 threads
@@ -424,7 +424,7 @@ class PrivateArchivesTestCase(TestCase):
#self.client.login(username='testuser', password='testPass')
settings = SettingsModule()
settings.KITTYSTORE_SEARCH_INDEX = self.tmpdir
- self.store = kittystore.get_store(settings, debug=False)
+ self.store = kittystore.get_store(settings, debug=False, auto_create=True)
ml = FakeList("list@example.com")
ml.subject_prefix = u"[example] "
ml.archive_policy = ArchivePolicy.private
diff --git a/hyperkitty/urls.py b/hyperkitty/urls.py
index b1eda96..efee204 100644
--- a/hyperkitty/urls.py
+++ b/hyperkitty/urls.py
@@ -111,11 +111,15 @@ urlpatterns = patterns('hyperkitty.views',
SearchResource.as_view(), name="api_search"),
url(r'^api/tag\/', TagResource.as_view(), name="api_tag"),
- # Uncomment the admin/doc line below to enable admin documentation:
- # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
+ # Errors
+ url(r'^error/schemaupgrade$',
+ TemplateView.as_view(template_name="errors/schemaupgrade.html"),
+ name="error_schemaupgrade"),
# Admin
url(r'^admin/', include(admin.site.urls), {"SSL": True}),
+ # Uncomment the admin/doc line below to enable admin documentation:
+ # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Robots.txt
url(r'^robots\.txt$', TextTemplateView.as_view(template_name="robots.txt")),