From 757f37a52d7854ed752d56c66498383125a05a9f Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Sun, 22 May 2011 10:52:53 -0500 Subject: [PATCH] User migration works (but the rest of the system isn't updated for new user setup yet) --- mediagoblin/db/migrations.py | 39 ++++++++++++++++++++++++ mediagoblin/db/models.py | 6 +++- mediagoblin/gmg_commands/__init__.py | 4 +++ mediagoblin/gmg_commands/migrate.py | 45 ++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 mediagoblin/db/migrations.py create mode 100644 mediagoblin/gmg_commands/migrate.py diff --git a/mediagoblin/db/migrations.py b/mediagoblin/db/migrations.py new file mode 100644 index 00000000..d035b15b --- /dev/null +++ b/mediagoblin/db/migrations.py @@ -0,0 +1,39 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from mongokit import DocumentMigration + +from mediagoblin import globals as mediagoblin_globals + + +class MediaEntryMigration(DocumentMigration): + def allmigration01_uploader_to_reference(self): + """ + Old MediaEntry['uploader'] accidentally embedded the User instead + of referencing it. Fix that! + """ + # uploader is an associative array + self.target = {'uploader': {'$type': 3}} + if not self.status: + for doc in self.collection.find(self.target): + self.update = { + '$set': { + 'uploader': doc['uploader']['_id']}} + self.collection.update( + self.target, self.update, multi=True, safe=True) + + +MIGRATE_CLASSES = ['MediaEntry'] diff --git a/mediagoblin/db/models.py b/mediagoblin/db/models.py index 8e7889eb..3fc8d9e8 100644 --- a/mediagoblin/db/models.py +++ b/mediagoblin/db/models.py @@ -21,6 +21,8 @@ from mongokit import Document, Set from mediagoblin import util from mediagoblin.auth import lib as auth_lib from mediagoblin import globals as mediagoblin_globals +from mediagoblin.db import migrations +from mediagoblin.db.util import ObjectId ################### # Custom validators @@ -67,7 +69,7 @@ class MediaEntry(Document): __collection__ = 'media_entries' structure = { - 'uploader': User, + 'uploader': ObjectId, 'title': unicode, 'slug': unicode, 'created': datetime.datetime, @@ -99,6 +101,8 @@ class MediaEntry(Document): 'created': datetime.datetime.utcnow, 'state': u'unprocessed'} + migration_handler = migrations.MediaEntryMigration + # Actually we should referene uniqueness by uploader, but we # should fix http://bugs.foocorp.net/issues/340 first. # indexes = [ diff --git a/mediagoblin/gmg_commands/__init__.py b/mediagoblin/gmg_commands/__init__.py index 9ece2ec5..d1f7bfc1 100644 --- a/mediagoblin/gmg_commands/__init__.py +++ b/mediagoblin/gmg_commands/__init__.py @@ -24,6 +24,10 @@ SUBCOMMAND_MAP = { 'setup': 'mediagoblin.gmg_commands.shell:shell_parser_setup', 'func': 'mediagoblin.gmg_commands.shell:shell', 'help': 'Run a shell with some tools pre-setup'}, + 'migrate': { + 'setup': 'mediagoblin.gmg_commands.migrate:migrate_parser_setup', + 'func': 'mediagoblin.gmg_commands.migrate:migrate', + 'help': 'Apply all unapplied bulk migrations to the database'}, } diff --git a/mediagoblin/gmg_commands/migrate.py b/mediagoblin/gmg_commands/migrate.py new file mode 100644 index 00000000..e04fb343 --- /dev/null +++ b/mediagoblin/gmg_commands/migrate.py @@ -0,0 +1,45 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + + +from mediagoblin.db import migrations +from mediagoblin.gmg_commands import util as commands_util +from mediagoblin import globals as mgoblin_globals + + +def migrate_parser_setup(subparser): + subparser.add_argument( + '-cf', '--conf_file', default='mediagoblin.ini', + help="Config file used to set up environment") + subparser.add_argument( + '-cs', '--app_section', default='app:mediagoblin', + help="Section of the config file where the app config is stored.") + + +def migrate(args): + mgoblin_app = commands_util.setup_app(args) + print "Applying migrations..." + + for model_name in migrations.MIGRATE_CLASSES: + model = getattr(mgoblin_app.db, model_name) + + if not hasattr(model, 'migration_handler') or not model.collection: + continue + + migration = model.migration_handler(model) + migration.migrate_all(collection=model.collection) + + print "... done." -- 2.25.1