1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
#
# upgrade1.py <Peter.Bienstman@UGent.be>
#
import os
import sys
import shutil
import cPickle
from mnemosyne.libmnemosyne.translator import _
from mnemosyne.libmnemosyne.utils import expand_path
from mnemosyne.libmnemosyne.component import Component
class Upgrade1(Component):
"""Upgrade from 1.x to 2.x."""
def run(self): # pragma: no cover
join = os.path.join
# Only do this upgrade once.
if not self.database().is_empty():
return
# Determine old data_dir.
home = os.path.expanduser("~")
if sys.platform == "darwin":
# This is where backup_old_dir put the old data dir.
old_data_dir = join(unicode(home), "Library", "Mnemosyne_1")
else:
try:
home = home.decode(locale.getdefaultlocale()[1])
except:
pass
old_data_dir = join(home, ".mnemosyne")
# We split off the rest to a separate function for testability.
if os.path.exists(old_data_dir):
self.upgrade_from_old_data_dir(old_data_dir)
def backup_old_dir(self): # pragma: no cover
join = os.path.join
# We only do this on OSX, since on the other platforms, we use a
# different directory anyway.
if sys.platform == "darwin":
home = os.path.expanduser("~")
old_data_dir = join(unicode(home), "Library", "Mnemosyne")
backup_dir = join(unicode(home), "Library", "Mnemosyne_1")
# Work around os.path.exists seeming to give wrong results on
# OSX 10.6 (but not 10.7).
if os.path.exists(join(old_data_dir, "default.db")):
# Data was already backed up.
return
if os.path.exists(old_data_dir):
if not os.path.exists(backup_dir):
old_files = sorted(os.listdir(old_data_dir))
shutil.move(old_data_dir, backup_dir)
new_files = sorted(os.listdir(backup_dir))
assert old_files == new_files
self.main_widget().show_information(\
_("Your old 1.x files are now stored here:\n\n" + backup_dir))
else:
self.main_widget().show_error(\
_("Tried to backup your old 1.x files to %s, but that directory already exists.") \
% (backup_dir,))
sys.exit()
def upgrade_from_old_data_dir(self, old_data_dir):
join = os.path.join
try:
old_data_dir = unicode(old_data_dir)
except:
old_data_dir = unicode(old_data_dir, "mbcs")
# Warn people that this directory is no longer used.
file(join(old_data_dir,
"DIRECTORY_NO_LONGER_USED_BY_MNEMOSYNE2"), "w").close()
# Read old configuration.
old_config = {}
config_file = file(join(old_data_dir, "config"), "rb")
for key, value in cPickle.load(config_file).iteritems():
old_config[key] = value
# Migrate configuration settings.
if "user_id" in old_config:
self.config()["user_id"] = old_config["user_id"]
if "upload_logs" in old_config:
self.config()["upload_science_logs"] = old_config["upload_logs"]
if "non_latin_font_size_increase" in old_config:
self.config()["non_latin_font_size_increase"] \
= old_config["non_latin_font_size_increase"]
for card_type in self.card_types():
if "QA_font" in old_config:
self.config().set_card_type_property("font",
old_config["QA_font"], card_type)
if "left_align" in old_config and old_config["left_align"]:
for card_type in self.card_types():
self.config().set_card_type_property("alignment",
"left", card_type)
# Migrate latex settings.
setting_for_file = {"dvipng": "dvipng",
"preamble": "latex_preamble",
"postamble": "latex_postamble"}
for filename, setting in setting_for_file.iteritems():
full_filename = join(old_data_dir, "latex", filename)
self.config()[setting] = ""
if os.path.exists(full_filename):
for line in file(full_filename):
self.config()[setting] += line
# Copy over everything that does not interfere with Mnemosyne 2.
new_data_dir = self.config().data_dir
new_media_dir = self.database().media_dir()
shutil.rmtree(join(new_data_dir, "history"))
names = [name for name in os.listdir(old_data_dir) if name not in
["backups", "config", "config.py", "config.pyc",
"DIRECTORY_NO_LONGER_USED_BY_MNEMOSYNE2", "error_log.txt",
"latex", "plugins", "log.txt", "history"] \
and not name.endswith(".mem") and not name is None]
self.main_widget().set_progress_text(_("Copying files from 1.x..."))
# By copying over the history folder and log.txt, we also completely
# preserve the state of all the files that need to uploaded to the
# science server.
self.main_widget().set_progress_range(len(names) + 2)
if os.path.exists(join(old_data_dir, "history")):
shutil.copytree(join(old_data_dir, "history"),
join(new_data_dir, "history"))
self.main_widget().increase_progress(1)
shutil.copyfile(join(old_data_dir, "log.txt"),
join(new_data_dir, "log.txt"))
self.main_widget().increase_progress(1)
# We copy all the other files to the media directory. In this way,
# if there are media files that are not explicitly referenced in the
# cards, it will be easier for the user to fix his path errors after
# the upgrade.
for name in names:
if os.path.isdir(join(old_data_dir, name)):
try:
shutil.copytree(join(old_data_dir, name),
join(new_media_dir, name))
except OSError, e:
# https://bugs.launchpad.net/mnemosyne-proj/+bug/1210435
import errno
if e.errno != errno.EEXIST:
raise e
self.main_widget().show_information(\
"Skipping copying of %s because it already exists.") \
% (name, )
else:
shutil.copyfile(join(old_data_dir, name),
join(new_media_dir, name))
self.main_widget().increase_progress(1)
# Upgrade database.
old_database = expand_path("default.mem", old_data_dir)
for format in self.component_manager.all("file_format"):
if format.__class__.__name__ == "Mnemosyne1Mem":
format.do_import(old_database)
self.review_controller().reset()
# Give info to the user.
info = _("Upgrade from Mnemosyne 1.x complete!") + "\n\n"
info += _("Mnemosyne 2.x now stores its data here:") + "\n\n"
info += self.config().data_dir + "\n"
if self.config().config_dir != \
self.config().data_dir: # pragma: no cover
# Only happens on Linux, outside of the test suite.
info += self.config().config_dir
self.main_widget().show_information(info)
|