def fill_dirs(self): """Fill data_dir and config_dir. Do this even if they already exist, because we might have added new files since the last version. """ exists = os.path.exists join = os.path.join # Create paths. if not exists(self.data_dir): os.makedirs(self.data_dir) if not exists(self.config_dir): os.makedirs(self.config_dir) for directory in ["history", "plugins", "backups"]: if not exists(join(self.data_dir, directory)): os.mkdir(join(self.data_dir, directory)) # Create default config.py. config_file = join(self.config_dir, "config.py") if not exists(config_file): f = file(config_file, "w") print >> f, config_py f.close() # Create machine_id. Do this in a separate file, as extra warning # signal that people should not copy this file to a different machine. machine_id_file = join(self.config_dir, "machine.id") if not exists(machine_id_file): f = file(machine_id_file, "w") print >> f, rand_uuid() f.close()
def __init__(self, name, id=None): if id is None: id = rand_uuid() self.id = id self._id = None self.name = name self.extra_data = {}
def fill_dirs(self): """Fill data_dir and config_dir. Do this even if they already exist, because we might have added new files since the last version. """ exists = os.path.exists join = os.path.join # Create paths. if not exists(self.data_dir): os.makedirs(self.data_dir) if not exists(self.config_dir): os.makedirs(self.config_dir) for directory in ["history", "plugins", "backups"]: if not exists(join(self.data_dir, directory)): os.mkdir(join(self.data_dir, directory)) # Create default config.py. config_file = join(self.config_dir, "config.py") if not exists(config_file): f = open(config_file, "w") print(config_py(), file=f) f.close() # Create machine_id. Do this in a separate file, as extra warning # signal that people should not copy this file to a different machine. machine_id_file = join(self.config_dir, "machine.id") if not exists(machine_id_file): f = open(machine_id_file, "w") print(rand_uuid(), file=f) f.close()
def __init__(self, component_manager, id=None): Component.__init__(self, component_manager) self.name = "" if id is None: id = rand_uuid() self.id = id self._id = None
def unanonymise_id(self, item_id): if "." in item_id: old_id, suffix = item_id.split(".", 1) suffix = "." + suffix else: old_id, suffix = item_id, "" if old_id in self.anon_to_id: item_id = self.anon_to_id[old_id] else: item_id = rand_uuid() self.anon_to_id[old_id] = item_id return item_id + suffix
def __init__(self, card_type, fact, fact_view, creation_time=None): self.card_type = card_type self.fact = fact self.fact_view = fact_view self.id = rand_uuid() self._id = None if creation_time is None: creation_time = int(time.time()) self.creation_time = creation_time self.modification_time = self.creation_time self.tags = set() self.extra_data = {} self.scheduler_data = 0 self.active = True self.reset_learning_data()
def set_defaults(self): """Fill the config with default values. Is called after every load, since a new version of Mnemosyne might have introduced new keys. """ for key, value in \ {"last_database": \ self.database().default_name + self.database().suffix, "first_run": True, "import_img_dir": self.data_dir, "import_sound_dir": self.data_dir, "import_video_dir": self.data_dir, "import_flash_dir": self.data_dir, "import_plugin_dir": os.path.expanduser("~"), "user_id": None, "upload_science_logs": True, "science_server": "mnemosyne-proj.dyndns.org:80", "max_log_size_before_upload": 64000, # For testability. "show_daily_tips": True, "current_tip": 0, "font": {}, # [card_type.id][fact_key] "font_colour": {}, # [card_type.id][fact_key] "background_colour": {}, # [card_type.id] "alignment": {}, # [card_type.id] "hide_pronunciation_field": {}, # [card_type.id] "non_latin_font_size_increase": 0, "non_memorised_cards_in_hand": 10, "randomise_new_cards": False, "randomise_scheduled_cards": False, "cramming_store_state": True, "cramming_order": RANDOM, "show_intervals": "never", "only_editable_when_answer_shown": False, "show_tags_during_review": True, "ui_language": "en", "backups_to_keep": 10, "backup_before_sync": True, "check_for_edited_local_media_files": False, "interested_in_old_reps": True, "single_database_help_shown": False, "save_database_help_shown": False, "find_duplicates_help_shown": False, "star_help_shown": False, "start_card_browser_sorted": False, "day_starts_at": 3, "save_after_n_reps": 10, "latex_preamble": "\\documentclass[12pt]{article}\n"+ "\\pagestyle{empty}\n\\begin{document}", "latex_postamble": "\\end{document}", "latex": "latex -interaction=nonstopmode", "dvipng": "dvipng -D 200 -T tight tmp.dvi", "active_plugins": set(), # Plugin classes, not instances. "media_autoplay": True, "media_controls": False, "run_sync_server": False, "run_web_server": False, "sync_server_port": 8512, "web_server_port": 8513, "remote_access_username": "", "remote_access_password": "", "warned_about_learning_ahead": False, "shown_backlog_help": False, "shown_learn_new_cards_help": False, "shown_schedule_help": False, "asynchronous_database": False, "author_name": "", "author_email": "", "import_dir": os.path.expanduser("~"), "import_format": None, "import_extra_tag_names": "", "export_dir": os.path.expanduser("~"), "export_format": None, "last_db_maintenance": time.time() }.items(): self.setdefault(key, value) # These keys will be shared in the sync protocol. Front-ends can # modify this list, e.g. if they don't want to override the fonts. self.keys_to_sync = ["font", "font_colour", "background_colour", "alignment", "non_latin_font_size_increase", "hide_pronunciation_field", "non_memorised_cards_in_hand", "randomise_new_cards", "randomise_scheduled_cards", "ui_language", "day_starts_at", "latex_preamble", "latex_postamble", "latex", "dvipng"] # If the user id is not set, it's either because this is the first run # of the program, or because the user deleted the config file. In the # latter case, we try to recuperate the id from the history files. if self["user_id"] is None: _dir = os.listdir(unicode(os.path.join(self.data_dir, "history"))) history_files = [x for x in _dir if x[-4:] == ".bz2"] if not history_files: self["user_id"] = rand_uuid() else: self["user_id"] = history_files[0].split("_", 1)[0] # Allow other plugins or frontend to set their configuration data. for f in self.component_manager.all("hook", "configuration_defaults"): f.run() self.save()
self.starttime = int(tree.getroot().get("time_of_start")) category_with_name = {} self.categories = [] for element in tree.findall("category"): category = Mnemosyne1.MnemosyneCore.Category() category.name = element.find("name").text category.active = bool(element.get("active")) self.categories.append(category) category_with_name[category.name] = category self.items = [] warned_about_import = False for element in tree.findall("item"): item = Mnemosyne1.MnemosyneCore.Item() item.id = element.get("id") if not item.id: item.id = rand_uuid() if item.id.startswith('_'): item.id = self.unanonymise_id(item.id) item.q = element.find("Q").text item.a = element.find("A").text if item.a is None: item.a = "" item.cat = category_with_name[element.find("cat").text] if element.get("gr"): if not warned_about_import: result = w.show_question(_("This XML file contains learning data. It's best to import this from a mem file, in order to preserve historical statistics. Continue?"), _("Yes"), _("No"), "") warned_about_import = True if result == 1: # No return item.grade = int(element.get("gr")) else:
def __init__(self, data, id=None): self.data = data if id is None: id = rand_uuid() self.id = id self._id = None
def set_defaults(self): """Fill the config with default values. Is called after every load, since a new version of Mnemosyne might have introduced new keys. """ for key, value in \ list({"last_database": \ self.database().default_name + self.database().suffix, "first_run": True, "import_img_dir": self.data_dir, "import_sound_dir": self.data_dir, "import_video_dir": self.data_dir, "import_flash_dir": self.data_dir, "import_plugin_dir": os.path.expanduser("~"), "user_id": None, "upload_science_logs": True, "science_server": "mnemosyne-proj.dyndns.org:80", "max_log_size_before_upload": 64000, # For testability. "show_daily_tips": True, "current_tip": 0, "font": {}, # [card_type.id][fact_key] "font_colour": {}, # [card_type.id][fact_key] "background_colour": {}, # [card_type.id] "alignment": {}, # [card_type.id] "hide_pronunciation_field": {}, # [card_type.id] "language_id": {}, # [card_type.id], ISO code "sublanguage_id": {}, # [card_type.id], ISO code "foreign_fact_key": {}, # [card_type.id] "translation_language_id": {}, # [card_type.id], ISO code "non_latin_font_size_increase": 0, "non_memorised_cards_in_hand": 10, "randomise_new_cards": False, "randomise_scheduled_cards": False, "cramming_store_state": True, "max_ret_reps_for_recent_cards": 1, "cramming_order": RANDOM, "show_intervals": "never", "only_editable_when_answer_shown": False, "show_tags_during_review": True, "ui_language": self.default_language(), "max_backups": 10, "backup_before_sync": True, "check_for_edited_local_media_files": False, "interested_in_old_reps": True, "single_database_help_shown": False, "save_database_help_shown": False, "find_duplicates_help_shown": False, "star_help_shown": False, "start_card_browser_sorted": False, "day_starts_at": 3, "save_after_n_reps": 10, "latex_preamble": "\\documentclass[12pt]{article}\n"+ "\\pagestyle{empty}\n\\begin{document}", "latex_postamble": "\\end{document}", "latex": "latex -interaction=nonstopmode", "dvipng": "dvipng -D 200 -T tight tmp.dvi", "active_plugins": set(), # Plugin class name, not instance. "media_autoplay": True, "media_controls": False, "run_sync_server": False, "run_web_server": False, "sync_server_port": 8512, "web_server_port": 8513, "remote_access_username": "", "remote_access_password": "", "warned_about_learning_ahead": False, "shown_backlog_help": False, "shown_learn_new_cards_help": False, "shown_schedule_help": False, "asynchronous_database": False, "author_name": "", "author_email": "", "import_dir": os.path.expanduser("~"), "import_format": None, "import_extra_tag_names": "", "export_dir": os.path.expanduser("~"), "export_format": None, "last_db_maintenance": time.time() - 1 * DAY, "QA_split": "fixed", # "fixed", "adaptive", "single_window", "study_mode": "ScheduledForgottenNew", "tts_dir_for_card_type_id": {} # card_type_id, dir }.items()): self.setdefault(key, value) # These keys will be shared in the sync protocol. Front-ends can # modify this list, e.g. if they don't want to override the fonts. self.keys_to_sync = [ "font", "font_colour", "background_colour", "alignment", "non_latin_font_size_increase", "hide_pronunciation_field", "non_memorised_cards_in_hand", "randomise_new_cards", "randomise_scheduled_cards", "ui_language", "day_starts_at", "latex_preamble", "latex_postamble", "latex", "dvipng", "max_backups", "language_id", "sublanguage_id", "foreign_fact_key" ] # If the user id is not set, it's either because this is the first run # of the program, or because the user deleted the config file. In the # latter case, we try to recuperate the id from the history files. if self["user_id"] is None: _dir = os.listdir(os.path.join(self.data_dir, "history")) history_files = [x for x in _dir if x[-4:] == ".bz2"] if not history_files: self["user_id"] = rand_uuid() else: self["user_id"] = history_files[0].split("_", 1)[0] self["latex"] = self["latex"].strip().split() self["dvipng"] = self["dvipng"].strip().split() # Allow other plugins or frontend to set their configuration data. for f in self.component_manager.all("hook", "configuration_defaults"): f.run() self.save()
def read_items_from_mnemosyne1_xml(self, filename): # Reset anonymiser when importing a new file, otherwise information # from the previous file still lingers and we get erroneously think # we've imported this before. self.anon_to_id = {} w = self.main_widget() try: tree = cElementTree.parse(filename) except cElementTree.ParseError as e: w.show_error(_("Unable to parse file:") + str(e)) raise MnemosyneError except: w.show_error(_("Unable to open file.")) raise MnemosyneError if tree.getroot().tag != "mnemosyne" or \ tree.getroot().get("core_version") != "1": w.show_error( _("XML file does not seem to be a Mnemosyne 1.x XML file.")) raise MnemosyneError self.starttime = 0 if tree.getroot().get("time_of_start"): self.starttime = int(tree.getroot().get("time_of_start")) category_with_name = {} self.categories = [] for element in tree.findall("category"): category = Mnemosyne1.MnemosyneCore.Category() category.name = element.find("name").text category.active = bool(element.get("active")) self.categories.append(category) category_with_name[category.name] = category self.items = [] warned_about_import = False for element in tree.findall("item"): item = Mnemosyne1.MnemosyneCore.Item() item.id = element.get("id") if not item.id: item.id = rand_uuid() if item.id.startswith('_'): item.id = self.unanonymise_id(item.id) item.q = element.find("Q").text item.a = element.find("A").text if item.a is None: item.a = "" item.cat = category_with_name[element.find("cat").text] if element.get("gr"): if not warned_about_import: result = w.show_question( _("This XML file contains learning data. It's best to import this from a mem file, in order to preserve historical statistics. Continue?" ), _("Yes"), _("No"), "") warned_about_import = True if result == 1: # No return item.grade = int(element.get("gr")) else: item.grade = 0 if element.get("e"): item.easiness = float(element.get("e")) else: item.easiness = 2.5 if element.get("ac_rp"): item.acq_reps = int(element.get("ac_rp")) else: item.acq_reps = 0 if element.get("rt_rp"): item.ret_reps = int(element.get("rt_rp")) else: item.ret_reps = 0 if element.get("lps"): item.lapses = int(element.get("lps")) else: item.lapses = 0 if element.get("ac_rp_l"): item.acq_reps_since_lapse = int(element.get("ac_rp_l")) else: item.acq_reps_since_lapse = 0 if element.get("rt_rp_l"): item.ret_reps_since_lapse = int(element.get("rt_rp_l")) else: item.ret_reps_since_lapse = 0 if element.get("l_rp"): item.last_rep = int(float(element.get("l_rp"))) else: item.last_rep = 0 if element.get("n_rp"): item.next_rep = int(float(element.get("n_rp"))) else: item.next_rep = 0 if element.get("u"): item.unseen = bool(element.get("u")) else: if item.acq_reps <= 1 and item.ret_reps == 0 \ and item.grade == 0: item.unseen = True else: item.unseen = False self.items.append(item)
self.starttime = int(tree.getroot().get("time_of_start")) category_with_name = {} self.categories = [] for element in tree.findall("category"): category = Mnemosyne1.MnemosyneCore.Category() category.name = element.find("name").text category.active = bool(element.get("active")) self.categories.append(category) category_with_name[category.name] = category self.items = [] warned_about_import = False for element in tree.findall("item"): item = Mnemosyne1.MnemosyneCore.Item() item.id = element.get("id") if not item.id: item.id = rand_uuid() if item.id.startswith('_'): item.id = self.unanonymise_id(item.id) item.q = element.find("Q").text item.a = element.find("A").text if item.a is None: item.a = "" item.cat = category_with_name[element.find("cat").text] if element.get("gr"): if not warned_about_import: result = w.show_question( _("This XML file contains learning data. It's best to import this from a mem file, in order to preserve historical statistics. Continue?" ), _("Yes"), _("No"), "") warned_about_import = True if result == 1: # No return