Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/datastore/src/carquinyol/migration.py
diff options
context:
space:
mode:
Diffstat (limited to 'datastore/src/carquinyol/migration.py')
-rw-r--r--datastore/src/carquinyol/migration.py103
1 files changed, 103 insertions, 0 deletions
diff --git a/datastore/src/carquinyol/migration.py b/datastore/src/carquinyol/migration.py
new file mode 100644
index 0000000..95ee391
--- /dev/null
+++ b/datastore/src/carquinyol/migration.py
@@ -0,0 +1,103 @@
+# Copyright (C) 2008, One Laptop Per Child
+#
+# This program 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 2 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Transform one DataStore directory in a newer format.
+"""
+
+import os
+import logging
+import shutil
+import time
+import traceback
+
+import cjson
+
+from carquinyol import layoutmanager
+
+DATE_FORMAT = '%Y-%m-%dT%H:%M:%S'
+
+
+def migrate_from_0():
+ logging.info('Migrating datastore from version 0 to version 1')
+
+ root_path = layoutmanager.get_instance().get_root_path()
+ old_root_path = os.path.join(root_path, 'store')
+ if not os.path.exists(old_root_path):
+ return
+
+ for f in os.listdir(old_root_path):
+ uid, ext = os.path.splitext(f)
+ if ext != '.metadata':
+ continue
+
+ logging.debug('Migrating entry %r', uid)
+ try:
+ _migrate_metadata(root_path, old_root_path, uid)
+ _migrate_file(root_path, old_root_path, uid)
+ _migrate_preview(root_path, old_root_path, uid)
+ except Exception:
+ logging.exception('Error while migrating entry %r', uid)
+
+ # Just be paranoid, it's cheap.
+ if old_root_path.endswith('datastore/store'):
+ shutil.rmtree(old_root_path)
+
+ logging.info('Migration finished')
+
+
+def _migrate_metadata(root_path, old_root_path, uid):
+ dir_path = layoutmanager.get_instance().get_entry_path(uid)
+ metadata_path = layoutmanager.get_instance().get_metadata_path(uid)
+ os.makedirs(metadata_path)
+
+ old_metadata_path = os.path.join(old_root_path, uid + '.metadata')
+ metadata = cjson.decode(open(old_metadata_path, 'r').read())
+
+ if 'uid' not in metadata:
+ metadata['uid'] = uid
+
+ if 'timestamp' not in metadata and 'mtime' in metadata:
+ metadata['timestamp'] = \
+ time.mktime(time.strptime(metadata['mtime'], DATE_FORMAT))
+
+ for key, value in metadata.items():
+ try:
+ f = open(os.path.join(metadata_path, key), 'w')
+ try:
+ if isinstance(value, unicode):
+ value = value.encode('utf-8')
+ if not isinstance(value, basestring):
+ value = str(value)
+ f.write(value)
+ finally:
+ f.close()
+ except Exception:
+ logging.exception(
+ 'Error while migrating property %s of entry %s', key, uid)
+
+
+def _migrate_file(root_path, old_root_path, uid):
+ if os.path.exists(os.path.join(old_root_path, uid)):
+ new_data_path = layoutmanager.get_instance().get_data_path(uid)
+ os.rename(os.path.join(old_root_path, uid),
+ new_data_path)
+
+
+def _migrate_preview(root_path, old_root_path, uid):
+ dir_path = layoutmanager.get_instance().get_entry_path(uid)
+ metadata_path = layoutmanager.get_instance().get_metadata_path(uid)
+ os.rename(os.path.join(old_root_path, 'preview', uid),
+ os.path.join(metadata_path, 'preview'))