Просмотр исходного кода

#600: move forum settings from old forum

Rafał Pitoń 8 лет назад
Родитель
Сommit
199f575872

+ 1 - 0
docs/index.rst

@@ -19,6 +19,7 @@ Table of Contents
    :maxdepth: 1
 
    setup_maintenance
+   upgrading_from_05
    developers/index
    developers/acls
    developers/admin_actions

+ 51 - 0
docs/upgrading_from_05.rst

@@ -0,0 +1,51 @@
+=========================
+Upgrading from Misago 0.5
+=========================
+
+Misago 0.6 comes with special utility that allows those upgrading from Misago 0.5 to move their data to new site. This utility, named ``datamover``, provides set of management commands allowing you to move data over.
+
+
+Preparing for move
+==================
+
+To move your data to new site, you'll need to first install Misago 0.6, and then tell mover how to access your old data.
+
+
+Database
+--------
+
+In your site's ``settings.py`` find ``DATABASES`` setting, and add connection named ``misago05``::
+
+    DATABASES = {
+        'default': {
+            # new database used by Misago
+        },
+        'misago05': {
+            'ENGINE': 'django.db.backends.mysql',
+            'NAME': 'your_misago_05_database_name',
+            'USER': 'your_misago_05_database_user',
+            'PASSWORD': 'your_misago_05_database_password',
+            'HOST': 'localhost',
+            'PORT': '3306',
+        }
+    }
+
+
+User uploads
+------------
+
+You'll actually won't need all of your old forum's files for move, only attachments and media directories. To tell data mover where it can find those directories, add ``MISAGO_OLD_FORUM`` setting somewhere in your ``settings.py``, just like in example below::
+
+    MISAGO_OLD_FORUM = {
+        'ATTACHMENTS': '/home/somewhere/myoldmisago/attachments/',
+        'MEDIA': '/home/somewhere/myoldmisago/media/',
+    }
+
+
+Moving forum configuration
+--------------------------
+
+To move configuration over to new forum, run ``python manage.py movesettings`` command.
+
+.. note::
+   Some settings have been moved from admin to configuration file, or removed. Those will not be migrated. Please consult :doc:`configuration reference </developers/settings>`.

+ 3 - 0
misago/conf/defaults.py

@@ -66,6 +66,9 @@ INSTALLED_APPS = (
     'misago.readtracker',
     'misago.search',
     'misago.faker',
+
+    # Utility for moving data from Misago 0.5
+    'misago.datamover',
 )
 
 MIDDLEWARE_CLASSES = (

+ 8 - 0
misago/datamover/__init__.py

@@ -0,0 +1,8 @@
+from .conf import OLD_FORUM
+from .db import fetch_assoc
+
+
+class DevNull(object):
+    def write(self, *args, **kwargs):
+        pass
+defstdout = DevNull()

+ 4 - 0
misago/datamover/conf.py

@@ -0,0 +1,4 @@
+from django.conf import settings
+
+
+OLD_FORUM = getattr(settings, 'MISAGO_OLD_FORUM', None)

+ 15 - 0
misago/datamover/db.py

@@ -0,0 +1,15 @@
+from django.db import connections
+
+
+def fetch_assoc(query, *args):
+    """
+    Return all rows from a cursor as a dict
+    """
+    cursor = connections['misago05'].cursor()
+    cursor.execute(query, *args)
+
+    columns = [col[0] for col in cursor.description]
+    row = cursor.fetchone()
+    while row:
+        yield dict(zip(columns, row))
+        row = cursor.fetchone()

+ 0 - 0
misago/datamover/management/__init__.py


+ 36 - 0
misago/datamover/management/base.py

@@ -0,0 +1,36 @@
+import time
+
+from django.conf import settings
+from django.core.management import base
+
+from .. import OLD_FORUM
+
+
+CommandError = base.CommandError
+
+
+class BaseCommand(base.BaseCommand):
+    def execute(self, *args, **options):
+        self.check_move_setup()
+
+        return super(BaseCommand, self).execute(*args, **options)
+
+    def check_move_setup(self):
+        if not 'misago05' in settings.DATABASES:
+            raise CommandError(
+                "You need to configure connection for your old database by "
+                "adding \"misago05\" connection to your DATABASES"
+            )
+
+        if not OLD_FORUM:
+            raise CommandError(
+                "You need to configure migration from old forum by defining "
+                "MISAGO_OLD_FORUM setting in your settings.py"
+            )
+
+    def start_timer(self):
+        self._timer = time.time()
+
+    def stop_timer(self):
+        total_time = time.time() - self._timer
+        return time.strftime('%H:%M:%S', time.gmtime(total_time))

+ 0 - 0
misago/datamover/management/commands/__init__.py


+ 15 - 0
misago/datamover/management/commands/movesettings.py

@@ -0,0 +1,15 @@
+from ...settings import move_settings
+from ..base import BaseCommand, CommandError
+
+
+class Command(BaseCommand):
+    help = "Moves settings from Misago 0.5 installation"
+
+    def handle(self, *args, **options):
+        self.stdout.write("Moving settings from Misago 0.5:")
+
+        self.start_timer()
+        move_settings(self.stdout)
+
+        self.stdout.write(
+            self.style.SUCCESS("Moved settings in %s" % self.stop_timer()))

+ 82 - 0
misago/datamover/settings.py

@@ -0,0 +1,82 @@
+from misago.conf import db_settings
+from misago.conf.models import Setting
+
+from . import defstdout, fetch_assoc
+import pprint
+
+
+def copy_value(setting):
+    def closure(old_value):
+        setting_obj = Setting.objects.get(setting=setting)
+        setting_obj.value = old_value
+        setting_obj.save()
+        return setting_obj
+    return closure
+
+
+def map_value(setting, translation):
+    def closure(old_value):
+        setting_obj = Setting.objects.get(setting=setting)
+        setting_obj.value = translation[old_value]
+        setting_obj.save()
+        return setting_obj
+    return closure
+
+
+def convert_allow_custom_avatars(old_value):
+    setting_obj = Setting.objects.get(setting='allow_custom_avatars')
+    setting_obj.value = 'upload' in old_value.split(',')
+    setting_obj.save()
+    return setting_obj
+
+
+SETTING_CONVERTER = {
+    'board_name': copy_value('forum_name'),
+    'board_index_title': copy_value('forum_index_title'),
+    'board_index_meta': copy_value('forum_index_meta_description'),
+    'board_header': copy_value('forum_branding_text'),
+    'email_footnote_plain': copy_value('email_footer'),
+    'tos_title': copy_value('terms_of_service_title'),
+    'tos_url': copy_value('terms_of_service_link'),
+    'tos_content': copy_value('terms_of_service'),
+    'board_credits': copy_value('forum_footnote'),
+    'thread_name_min': copy_value('thread_title_length_min'),
+    'thread_name_max': copy_value('thread_title_length_max'),
+    'post_length_min': copy_value('post_length_min'),
+    'account_activation': map_value('account_activation', {
+        'none': 'none',
+        'user': 'user',
+        'admin': 'admin',
+        'block': 'closed',
+    }),
+    'username_length_min': copy_value('username_length_min'),
+    'username_length_max': copy_value('username_length_max'),
+    'password_length': copy_value('password_length_min'),
+    'avatars_types': convert_allow_custom_avatars,
+    'default_avatar': copy_value('default_avatar'),
+    'upload_limit': copy_value('avatar_upload_limit'),
+    'subscribe_start': copy_value('subscribe_start'),
+    'subscribe_reply': copy_value('subscribe_reply'),
+    'bots_registration': map_value('captcha_type', {
+        'no': 'no',
+        'recaptcha': 're',
+        'qa': 'qa',
+    }),
+    'recaptcha_public': copy_value('recaptcha_site_key'),
+    'recaptcha_private': copy_value('recaptcha_secret_key'),
+    'qa_test': copy_value('qa_question'),
+    'qa_test_help': copy_value('qa_help_text'),
+    'qa_test_answers': copy_value('qa_answers'),
+}
+
+
+def move_settings(stdout):
+    stdout = stdout or defstdout
+
+    for row in fetch_assoc('SELECT * FROM misago_setting'):
+        setting_key = row['setting']
+        if setting_key in SETTING_CONVERTER:
+            convert_setting = SETTING_CONVERTER[setting_key]
+            setting_obj = convert_setting(row['value'])
+            stdout.write(setting_obj.name)
+    db_settings.flush_cache()

+ 7 - 5
misago/templates/misago/navbar.html

@@ -100,11 +100,13 @@
         <i class="material-icon">group</i>
       </a>
     </li>
-    <li>
-      <a href="#">
-        <i class="material-icon">search</i>
-      </a>
-    </li>
+    {% if user.acl.can_search %}
+      <li>
+        <a href="{% url 'misago:search' %}">
+          <i class="material-icon">search</i>
+        </a>
+      </li>
+    {% endif %}
     <li id="user-menu-compact-mount"></li>
   </ul>
   <!-- /compact navbar -->

+ 4 - 1
misago/threads/migrations/0002_threads_settings.py

@@ -56,7 +56,10 @@ def create_threads_settings_group(apps, schema_editor):
             {
                 'setting': 'post_length_max',
                 'name': _("Maximum length"),
-                'description': _("Maximum allowed user post length. Enter zero to disable"),
+                'description': _(
+                    "Maximum allowed user post length. Enter zero to disable. "
+                    "Longer posts are more costful to parse and index."
+                ),
                 'python_type': 'int',
                 'value': 60000,
                 'field_extra': {

+ 2 - 2
misago/users/migrations/0002_users_settings.py

@@ -25,8 +25,8 @@ def create_users_settings_group(apps, schema_editor):
                 'field_extra': {
                     'choices': (
                         ('none', _("No activation required")),
-                        ('user', _("Activation Token sent to User")),
-                        ('admin', _("Activation by Administrator")),
+                        ('user', _("Activation token sent to User")),
+                        ('admin', _("Activation by administrator")),
                         ('closed', _("Don't allow new registrations"))
                     )
                 },