Esempio n. 1
0
def startup():

    global mnemosyne

    # Note that this also includes building the queue and getting the first card.

    mnemosyne = Mnemosyne(upload_science_logs=False,
                          interested_in_old_reps=True)
    mnemosyne.components.insert(
        0,
        ("mnemosyne.libmnemosyne.translators.no_translator", "NoTranslator"))
    mnemosyne.components.append(
        ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget"))
    mnemosyne.components.append(("mnemosyne_test", "TestReviewWidget"))

    mnemosyne.initialise(data_dir=os.path.abspath("dot_benchmark"),
                         automatic_upgrades=False)
    #mnemosyne.initialise(data_dir="\SDMMC\.mnemosyne",
    #automatic_upgrades=False)

    mnemosyne.start_review()
Esempio n. 2
0
def startup():

    global mnemosyne

    # Note that this also includes building the queue and getting the first card.

    mnemosyne = Mnemosyne(upload_science_logs=False,
        interested_in_old_reps=True)
    mnemosyne.components.insert(0,
        ("mnemosyne.libmnemosyne.translators.no_translator",
         "NoTranslator"))
    mnemosyne.components.append(
        ("mnemosyne.libmnemosyne.ui_components.main_widget",
         "MainWidget"))
    mnemosyne.components.append(
        ("mnemosyne_test",
         "TestReviewWidget"))

    mnemosyne.initialise(data_dir=os.path.abspath("dot_benchmark"),
        automatic_upgrades=False)
    #mnemosyne.initialise(data_dir="\SDMMC\.mnemosyne",
    #automatic_upgrades=False)

    mnemosyne.start_review()
Esempio n. 3
0
class TestLogging(MnemosyneTest):
    def restart(self):
        self.mnemosyne = Mnemosyne(upload_science_logs=False,
                                   interested_in_old_reps=True,
                                   asynchronous_database=True)
        self.mnemosyne.components.insert(
            0, ("mnemosyne.libmnemosyne.translators.gettext_translator",
                "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)

    def test_logging(self):
        card_type = self.card_type_with_id("1")
        fact_data = {"f": "1", "b": "b"}
        card = self.controller().create_new_cards(fact_data,
                                                  card_type,
                                                  grade=-1,
                                                  tag_names=["default"])[0]
        card_id_1 = card.id
        self.review_controller().show_new_question()
        self.review_controller().grade_answer(0)
        self.review_controller().show_new_question()
        self.review_controller().grade_answer(1)
        self.review_controller().grade_answer(4)

        self.mnemosyne.finalise()
        self.restart()
        card_type = self.card_type_with_id("1")
        fact_data = {"f": "2", "b": "b"}
        card = self.controller().create_new_cards(fact_data,
                                                  card_type,
                                                  grade=-1,
                                                  tag_names=["default"])[0]
        self.review_controller().show_new_question()
        self.controller().delete_current_card()

        self.log().dump_to_science_log()

        sql_res = self.database().con.execute(\
            "select * from log where _id=1").fetchone()
        assert sql_res[1] == EventTypes.STARTED_PROGRAM

        sql_res = self.database().con.execute(\
            "select * from log where _id=2").fetchone()
        assert sql_res[1] == EventTypes.STARTED_SCHEDULER

        sql_res = self.database().con.execute(\
            "select * from log where _id=3").fetchone()
        assert sql_res[1] == EventTypes.LOADED_DATABASE
        assert sql_res[6] == 0
        assert sql_res[7] == 0
        assert sql_res[8] == 0

        sql_res = self.database().con.execute(\
            "select * from log where _id=11").fetchone()
        assert sql_res[1] == EventTypes.ADDED_TAG
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=12").fetchone()
        assert sql_res[1] == EventTypes.EDITED_CRITERION
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=13").fetchone()
        assert sql_res[1] == EventTypes.ADDED_FACT
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=14").fetchone()
        assert sql_res[1] == EventTypes.ADDED_CARD
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=15").fetchone()
        assert sql_res[1] == EventTypes.REPETITION
        assert sql_res[6] == 1
        assert sql_res[7] == 0
        assert sql_res[11] == 0
        assert sql_res[12] == 0
        assert sql_res[14] - sql_res[2] == 0
        assert sql_res[13] == 0
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=16").fetchone()
        assert sql_res[1] == EventTypes.REPETITION
        assert sql_res[6] == 2
        assert sql_res[7] == 0
        assert sql_res[11] == 0
        assert sql_res[12] <= 10  # Depends on CPU load.
        assert sql_res[14] - sql_res[2] == 0
        assert sql_res[13] == 0

        sql_res = self.database().con.execute(\
            "select * from log where _id=17").fetchone()
        assert sql_res[1] == EventTypes.REPETITION
        assert sql_res[6] == 3
        assert sql_res[7] == 0
        assert sql_res[11] == 0
        assert sql_res[12] <= 10  # Depends on CPU load.
        new_interval = sql_res[14] - sql_res[2]
        assert new_interval > 0
        assert sql_res[13] == 0

        sql_res = self.database().con.execute(\
            "select * from log where _id=18").fetchone()
        assert sql_res[1] == EventTypes.SAVED_DATABASE
        assert sql_res[6] == 0
        assert sql_res[7] == 0
        assert sql_res[8] == 1

        sql_res = self.database().con.execute(\
            "select * from log where _id=19").fetchone()
        assert sql_res[1] == EventTypes.STOPPED_PROGRAM

        sql_res = self.database().con.execute(\
            "select * from log where _id=20").fetchone()
        assert sql_res[1] == EventTypes.STARTED_PROGRAM

        sql_res = self.database().con.execute(\
            "select * from log where _id=21").fetchone()
        assert sql_res[1] == EventTypes.STARTED_SCHEDULER

        sql_res = self.database().con.execute(\
            "select * from log where _id=22").fetchone()
        assert sql_res[1] == EventTypes.LOADED_DATABASE
        assert sql_res[6] == 0
        assert sql_res[7] == 0
        assert sql_res[8] == 1

        sql_res = self.database().con.execute(\
            "select * from log where _id=30").fetchone()
        assert sql_res[1] == EventTypes.ADDED_FACT
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=31").fetchone()
        assert sql_res[1] == EventTypes.ADDED_CARD

        sql_res = self.database().con.execute(\
            "select * from log where _id=32").fetchone()
        assert sql_res[1] == EventTypes.DELETED_CARD
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=33").fetchone()
        assert sql_res[1] == EventTypes.DELETED_FACT
        assert sql_res[3] is not None

        self.config()["upload_science_logs"] = True
        self.database().dump_to_science_log()

        logfile = os.path.join(os.path.abspath("dot_test"), "log.txt")
        found = False
        for line in open(logfile):
            if "R " + card_id_1 + " 4" in line:
                found = True
                assert str(new_interval) + " 0 | 0.0" in line
        assert found == True

    def test_unique_index(self):
        fact_data = {"f": "question", "b": "answer"}
        card_type_2 = self.card_type_with_id("2")
        card_1, card_2 = self.controller().create_new_cards(
            fact_data, card_type_2, grade=-1, tag_names=["default"])
        log_index = self.database().con.execute(\
            """select _id from log order by _id desc limit 1""").fetchone()[0]
        # Note: we need to keep the last log entry intact, otherwise indexes
        # start again at 1 and mess up the sync.
        self.database().con.execute("""delete from log where _id <?""",
                                    (log_index, ))
        self.database().save()
        self.database().con.execute("""vacuum""")
        fact_data = {"f": "question2", "b": "answer2"}
        card_type_2 = self.card_type_with_id("1")
        card_1 = self.controller().create_new_cards(fact_data,
                                                    card_type_2,
                                                    grade=-1,
                                                    tag_names=["default"])
        assert self.database().con.execute(\
            """select _id from log order by _id limit 1""").fetchone()[0] \
            == log_index

    def test_recover_user_id(self):
        assert self.config()["user_id"] is not None
        MnemosyneTest.teardown(self)

        open(
            os.path.join(os.getcwd(), "dot_test", "history", "userid_001.bz2"),
            "w")
        os.remove(os.path.join(os.getcwd(), "dot_test", "config.db"))

        self.mnemosyne = Mnemosyne(upload_science_logs=False,
                                   interested_in_old_reps=True,
                                   asynchronous_database=True)
        self.mnemosyne.components.insert(
            0, ("mnemosyne.libmnemosyne.translators.gettext_translator",
                "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.mnemosyne.start_review()

        assert self.config()["user_id"] == "userid"

    def test_recover_user_id_2(self):
        assert self.config()["user_id"] is not None
        MnemosyneTest.teardown(self)

        open(
            os.path.join(os.getcwd(), "dot_test", "history",
                         "userid_machine_001.bz2"), "w")
        os.remove(os.path.join(os.getcwd(), "dot_test", "config.db"))

        self.mnemosyne = Mnemosyne(upload_science_logs=False,
                                   interested_in_old_reps=True,
                                   asynchronous_database=True)
        self.mnemosyne.components.insert(
            0, ("mnemosyne.libmnemosyne.translators.gettext_translator",
                "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.mnemosyne.start_review()

        assert self.config()["user_id"] == "userid"

    def test_log_index_of_last_upload_1(self):
        assert self.log().log_index_of_last_upload() == 0

    def test_log_index_of_last_upload_2(self):
        machine_id = self.config().machine_id()
        for filename in ["user_001.bz2", "user_%s_2.bz2" % machine_id]:
            open(os.path.join(os.getcwd(), "dot_test", "history", filename),
                 "w")
        assert self.log().log_index_of_last_upload() == 2

    def test_log_index_of_last_upload_3(self):
        machine_id = self.config().machine_id()
        for filename in ["user_001.bz2"]:
            open(os.path.join(os.getcwd(), "dot_test", "history", filename),
                 "w")
        assert self.log().log_index_of_last_upload() == 1

    def test_log_index_of_last_upload_4(self):
        machine_id = self.config().machine_id()
        for filename in ["user_005.bz2"]:
            open(os.path.join(os.getcwd(), "dot_test", "history", filename),
                 "w")
        assert self.log().log_index_of_last_upload() == 5

    def test_log_index_of_last_upload_5(self):
        machine_id = self.config().machine_id()
        for filename in ["user_othermachine_005.bz2"]:
            open(os.path.join(os.getcwd(), "dot_test", "history", filename),
                 "w")
        assert self.log().log_index_of_last_upload() == 0

    def test_log_index_of_last_upload_6(self):
        machine_id = self.config().machine_id()
        for filename in [
                "user_othermachine_005.bz2",
                "user_%s_2.bz2" % machine_id
        ]:
            open(os.path.join(os.getcwd(), "dot_test", "history", filename),
                 "w")
        assert self.log().log_index_of_last_upload() == 2

    def test_log_index_of_last_upload_7(self):
        machine_id = self.config().machine_id()
        for filename in [
                "user_001.bz2", "user_othermachine_005.bz2",
                "user_%s_2.bz2" % machine_id
        ]:
            open(os.path.join(os.getcwd(), "dot_test", "history", filename),
                 "w")
        assert self.log().log_index_of_last_upload() == 2

    def test_log_upload(self):
        machine_id_file = os.path.join(self.mnemosyne.config().config_dir,
                                       "machine.id")
        f = open(machine_id_file, "w")
        print("TESTMACHINE", file=f)
        f.close()
        self.config().change_user_id("UPLOADTEST")
        self.config()["max_log_size_before_upload"] = 1
        MnemosyneTest.teardown(self)

        self.mnemosyne = Mnemosyne(upload_science_logs=True,
                                   interested_in_old_reps=True,
                                   asynchronous_database=True)
        self.mnemosyne.components.insert(
            0, ("mnemosyne.libmnemosyne.translators.gettext_translator",
                "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.mnemosyne.start_review()
        MnemosyneTest.teardown(self)

        self.mnemosyne = Mnemosyne(upload_science_logs=True,
                                   interested_in_old_reps=True,
                                   asynchronous_database=True)
        self.mnemosyne.components.insert(
            0, ("mnemosyne.libmnemosyne.translators.gettext_translator",
                "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.mnemosyne.start_review()
        MnemosyneTest.teardown(self)

        self.mnemosyne = Mnemosyne(upload_science_logs=True,
                                   interested_in_old_reps=True,
                                   asynchronous_database=True)
        self.mnemosyne.components.insert(
            0, ("mnemosyne.libmnemosyne.translators.gettext_translator",
                "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.mnemosyne.start_review()

    def test_log_upload_bad_server(self):
        # Most reliable way of setting this variable is throug config.py, otherwise
        # it will stay alive in a dangling imported userconfig.
        config_py_file = os.path.join(self.mnemosyne.config().config_dir,
                                      "config.py")
        f = open(config_py_file, "w")
        print("science_server = \"noserver:80\"", file=f)
        f.close()

        machine_id_file = os.path.join(self.mnemosyne.config().config_dir,
                                       "machine.id")
        f = open(machine_id_file, "w")
        print("TESTMACHINE", file=f)
        f.close()
        self.config().change_user_id("UPLOADTEST")
        self.config()["max_log_size_before_upload"] = 1
        MnemosyneTest.teardown(self)

        self.mnemosyne = Mnemosyne(upload_science_logs=True,
                                   interested_in_old_reps=True,
                                   asynchronous_database=True)
        self.mnemosyne.components.insert(
            0, ("mnemosyne.libmnemosyne.translators.gettext_translator",
                "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.mnemosyne.start_review()
        MnemosyneTest.teardown(self)

        self.mnemosyne = Mnemosyne(upload_science_logs=True,
                                   interested_in_old_reps=True,
                                   asynchronous_database=True)
        self.mnemosyne.components.insert(
            0, ("mnemosyne.libmnemosyne.translators.gettext_translator",
                "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.mnemosyne.start_review()

    def mem_importer(self):
        for format in self.mnemosyne.component_manager.all("file_format"):
            if format.__class__.__name__ == "Mnemosyne1Mem":
                return format

    def test_archive_old_logs(self):
        # Import old history.
        filename = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2",
                                "default.mem")
        self.mem_importer().do_import(filename)
        assert self.database().con.execute(
            "select count() from log").fetchone()[0] == 23
        assert not os.path.exists(os.path.join("dot_test", "archive"))
        # Archive.
        self.database().archive_old_logs()
        assert self.database().con.execute(
            "select count() from log").fetchone()[0] == 12
        archive_name = os.listdir(
            os.path.join(os.getcwd(), "dot_test", "archive"))[0]
        archive_path = os.path.join(os.getcwd(), "dot_test", "archive",
                                    archive_name)
        import sqlite3
        arch_con = sqlite3.connect(archive_path)
        assert arch_con.execute("select count() from log").fetchone()[0] == 11
Esempio n. 4
0
class MnemosyneTest():

    def initialise_data_dir(self, data_dir="dot_test"):
        # Creating a new database seems a very time-consuming operation,
        # so we don't delete the test directory everytime, but take a short
        # cut.

        # Note: disabled this, as it does not seem to be very reliable.
        if os.path.exists(data_dir):
            shutil.rmtree(data_dir)
        assert not os.path.exists(data_dir)
        return

        if os.path.exists(data_dir):
            shutil.copy(os.path.join("mnemosyne", "tests", "files", "empty.db"),
                        os.path.join(data_dir, "default.db"))
            for directory in ["default.db_media", "plugins", "backups",
                              "history"]:
                full_path = str(os.path.join(data_dir, directory))
                if os.path.exists(full_path):
                    shutil.rmtree(full_path)
            for file in ["default.db-journal", "config",
                         "config.py", "machine.id", "log.txt"]:
                full_path = str(os.path.join(data_dir, file))
                if os.path.exists(full_path):
                    os.remove(full_path)

    def setup(self):
        self.initialise_data_dir()
        self.restart()

    def restart(self):
        # If there is another Mnemosyne still running, finalise it so as to
        # avoid having multiple component_managers active.
        if hasattr(self, "mnemosyne"):
            try:
                self.mnemosyne.finalise()
            except:
                pass
        path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne",
                            "renderers")
        if path not in sys.path:
            sys.path.append(path)
        self.mnemosyne = Mnemosyne(upload_science_logs=False,
            interested_in_old_reps=True, asynchronous_database=True)
        self.mnemosyne.components.insert(0,
            ("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator",
             "GetTextGuiTranslator"))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.gui_for_component["CramAll"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.mnemosyne.start_review()

    def teardown(self):
        try:
            self.mnemosyne.finalise()
            # Avoid having multiple component_managers active.
            from mnemosyne.libmnemosyne.component_manager import clear_component_managers
            clear_component_managers()
        except: # Can throw some errors when we artificially mutilate plugins.
            self.mnemosyne.database().abandon()

    def config(self):
        return self.mnemosyne.component_manager.current("config")

    def log(self):
        return self.mnemosyne.component_manager.current("log")

    def database(self):
        return self.mnemosyne.component_manager.current("database")

    def scheduler(self):
        return self.mnemosyne.component_manager.current("scheduler")

    def main_widget(self):
        return self.mnemosyne.component_manager.current("main_widget")

    def review_widget(self):
        return self.mnemosyne.component_manager.current("review_widget")

    def controller(self):
        return self.mnemosyne.component_manager.current("controller")

    def review_controller(self):
        return self.mnemosyne.component_manager.current("review_controller")

    def card_types(self):
        return self.mnemosyne.component_manager.all("card_type")

    def filters(self):
        return self.mnemosyne.component_manager.all("filter")

    def plugins(self):
        return self.mnemosyne.component_manager.all("plugin")

    def render_chain(self, id="default"):
        return self.mnemosyne.component_manager.render_chain_with_id[id]

    def card_type_with_id(self, id):
        return self.mnemosyne.component_manager.card_type_with_id[id]
Esempio n. 5
0
class TestCrammingScheduler(MnemosyneTest):

    def setup(self):
        self.initialise_data_dir()

        self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True,
            asynchronous_database=True)
        self.mnemosyne.components.insert(0,
           ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_cramming", "Widget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)


        from mnemosyne.libmnemosyne.plugins.cramming_plugin import CrammingPlugin
        for plugin in self.plugins():
            if isinstance(plugin, CrammingPlugin):
                plugin.activate()
                break
        self.mnemosyne.start_review()

    def test_1(self):
        from mnemosyne.libmnemosyne.schedulers.cramming import Cramming

        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]
        fact_data = {"f": "2", "b": "b"}
        card_2 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]
        fact_data = {"f": "3", "b": "b"}
        card_3 = self.controller().create_new_cards(fact_data, card_type,
                     grade=2, tag_names=["default"])[0]
        fact_data = {"f": "4", "b": "b"}
        card_4 = self.controller().create_new_cards(fact_data, card_type,
                     grade=2, tag_names=["default"])[0]
        card_4.next_rep -= 1000
        self.database().update_card(card_4)
        self.review_controller().start_review()

        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4
        assert self.database().scheduler_data_count(Cramming.WRONG) == 0
        self.review_controller().grade_answer(0)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        self.review_controller().grade_answer(5)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 2
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        # Fail the cards a couple of times.
        for i in range(8):
            self.review_controller().grade_answer(0)
        # Pass the cards a couple of times.
        for i in range(8):
            self.review_controller().grade_answer(5)

    def test_reset(self):
        from mnemosyne.libmnemosyne.schedulers.cramming import Cramming

        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]
        fact_data = {"f": "2", "b": "b"}
        card_2 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]
        fact_data = {"f": "3", "b": "b"}
        card_3 = self.controller().create_new_cards(fact_data, card_type,
                     grade=2, tag_names=["default"])[0]
        fact_data = {"f": "4", "b": "b"}
        card_4 = self.controller().create_new_cards(fact_data, card_type,
                     grade=2, tag_names=["default"])[0]
        card_4.next_rep -= 1000
        self.database().update_card(card_4)
        self.review_controller().start_review()

        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4
        assert self.database().scheduler_data_count(Cramming.WRONG) == 0
        assert self.review_controller().counters() == (0, 4, 4)
        self.review_controller().grade_answer(0)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        assert self.review_controller().counters() == (1, 3, 4)
        self.review_controller().reset_but_try_to_keep_current_card()
        self.review_controller().update_dialog(redraw_all=True)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        assert self.review_controller().counters() == (1, 3, 4)

    def test_2(self):
        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]

        self.review_controller().show_new_question()
        self.controller().delete_current_card()
        assert self.review_controller().card == None

    def test_3(self):
        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]

        self.review_controller().show_new_question()
        self.review_controller().show_answer()
        self.review_controller().grade_answer(0)
        self.review_controller().counters()

        self.mnemosyne.finalise()
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)

        assert self.scheduler().name == "cramming"

    def test_4(self):
        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]

        self.review_controller().show_new_question()
        self.database().unload()
        self.review_controller().reset()
        self.restart()
Esempio n. 6
0
class WebServer(Component):
    def __init__(self, port, data_dir, config_dir, filename, **kwds):
        if "client_on_same_machine_as_server" in kwds:
            self.client_on_same_machine_as_server = \
                kwds["client_on_same_machine_as_server"]
            del kwds["client_on_same_machine_as_server"]
        else:
            self.client_on_same_machine_as_server = False
        super().__init__(**kwds)
        self.wsgi_server = None
        self.port = port
        self.data_dir = data_dir
        self.config_dir = config_dir
        self.filename = filename
        # When restarting the server, make sure we discard info from the
        # browser resending the form from the previous session.
        self.is_just_started = True
        self.is_mnemosyne_loaded = False
        self.is_shutting_down = False

    def activate(self):
        Component.activate(self)
        # Late import to speed up application startup.
        from cheroot import wsgi
        self.wsgi_server = wsgi.Server(\
            ("0.0.0.0", self.port), self.wsgi_app, server_name="localhost",
            numthreads=1, timeout=5)
        # We need to set the timeout relatively low, otherwise it will take
        # too long for the server to process a 'stop' request.

    def serve_until_stopped(self):
        try:
            self.wsgi_server.start()  # Sets self.wsgi_server.ready
        except KeyboardInterrupt:
            self.wsgi_server.stop()
            self.unload_mnemosyne()

    def stop(self):
        if self.wsgi_server:
            self.wsgi_server.stop()
        self.unload_mnemosyne()

    def load_mnemosyne(self):
        self.mnemosyne = Mnemosyne(upload_science_logs=True,
                                   interested_in_old_reps=True)
        self.mnemosyne.components.insert(
            0, (("mnemosyne.libmnemosyne.translators.gettext_translator",
                 "GetTextTranslator")))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.main_widget",
             "MainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne.web_server.web_server_render_chain",
             "WebServerRenderChain"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = [\
            ("mnemosyne.web_server.review_wdgt",
             "ReviewWdgt")]
        self.mnemosyne.initialise(self.data_dir,
                                  config_dir=self.config_dir,
                                  filename=self.filename,
                                  automatic_upgrades=False)
        self.save_after_n_reps = self.mnemosyne.config()["save_after_n_reps"]
        self.mnemosyne.config()["save_after_n_reps"] = 1
        self.mnemosyne.config()["study_mode"] = "ScheduledForgottenNew"
        self.mnemosyne.config()["QA_split"] = "fixed"
        self.mnemosyne.start_review()
        self.mnemosyne.review_widget().set_client_on_same_machine_as_server(\
            self.client_on_same_machine_as_server)
        self.is_mnemosyne_loaded = True
        self.release_database_after_timeout = \
            ReleaseDatabaseAfterTimeout(self.port)
        self.release_database_after_timeout.start()

    def unload_mnemosyne(self):
        if not self.is_mnemosyne_loaded:
            return
        self.mnemosyne.config()["save_after_n_reps"] = self.save_after_n_reps
        self.mnemosyne.finalise()
        self.is_mnemosyne_loaded = False

    def wsgi_app(self, environ, start_response):
        filename = environ["PATH_INFO"]
        if filename == "/status":
            response_headers = [("Content-type", "text/html")]
            start_response("200 OK", response_headers)
            return [b"200 OK"]
        # Sometimes, even after the user has clicked 'exit' in the page,
        # a browser sends a request for e.g. an audio file.
        if self.is_shutting_down and filename != "/release_database":
            response_headers = [("Content-type", "text/html")]
            start_response("503 Service Unavailable", response_headers)
            return [b"Server stopped"]
        # Load database if needed.
        if not self.is_mnemosyne_loaded and filename != "/release_database":
            self.load_mnemosyne()
        self.release_database_after_timeout.ping()
        # All our request return to the root page, so if the path is '/',
        # return the html of the review widget.
        if filename == "/":
            # Process clicked buttons in the form.
            form = cgi.FieldStorage(fp=environ["wsgi.input"], environ=environ)
            if "show_answer" in form and not self.is_just_started:
                self.mnemosyne.review_widget().show_answer()
                page = self.mnemosyne.review_widget().to_html()
            elif "grade" in form and not self.is_just_started:
                grade = int(form["grade"].value)
                self.mnemosyne.review_widget().grade_answer(grade)
                page = self.mnemosyne.review_widget().to_html()
            elif "star" in form:
                self.mnemosyne.controller().star_current_card()
                page = self.mnemosyne.review_widget().to_html()
            elif "exit" in form:
                self.unload_mnemosyne()
                page = "Server stopped"
                self.wsgi_server.stop()
                self.stop_server_after_timeout = \
                    StopServerAfterTimeout(self.wsgi_server)
                self.stop_server_after_timeout.start()
                self.is_shutting_down = True
            else:
                page = self.mnemosyne.review_widget().to_html()
            if self.is_just_started:
                self.is_just_started = False
            # Serve the web page.
            response_headers = [("Content-type", "text/html")]
            start_response("200 OK", response_headers)
            return [page]
        elif filename == "/release_database":
            self.unload_mnemosyne()
            response_headers = [("Content-type", "text/html")]
            start_response("200 OK", response_headers)
            return [b"200 OK"]
        # We need to serve a media file.
        else:
            # Late import to speed up application startup.
            from webob import Request
            from webob.static import FileApp
            full_path = self.mnemosyne.database().media_dir()
            for word in filename.split("/"):
                full_path = os.path.join(full_path, word)
            request = Request(environ)
            if os.path.exists(full_path):
                etag = "%s-%s-%s" % (os.path.getmtime(full_path),
                                     os.path.getsize(full_path),
                                     hash(full_path))
            else:
                etag = "none"
            app = FileApp(full_path, etag=etag)
            return app(request)(environ, start_response)
Esempio n. 7
0
class WebServer(Component):

    def __init__(self, component_manager, port, data_dir, config_dir,
                 filename, is_server_local=False):
        Component.__init__(self, component_manager)
        self.port = port
        self.data_dir = data_dir
        self.config_dir = config_dir
        self.filename = filename
        self.is_server_local = is_server_local
        # When restarting the server, make sure we discard info from the
        # browser resending the form from the previous session.
        self.is_just_started = True
        self.is_mnemosyne_loaded = False
        self.is_shutting_down = False
        self.wsgi_server = wsgiserver.CherryPyWSGIServer(\
            ("0.0.0.0", port), self.wsgi_app, server_name="localhost",
            numthreads=1, timeout=5)
        # We need to set the timeout relatively low, otherwise it will take
        # too long for the server to process a 'stop' request.

    def serve_until_stopped(self):
        try:
            self.wsgi_server.start() # Sets self.wsgi_server.ready
        except KeyboardInterrupt:
            self.wsgi_server.stop()
            self.unload_mnemosyne()

    def stop(self):
        self.wsgi_server.stop()
        self.unload_mnemosyne()

    def load_mnemosyne(self):
        self.mnemosyne = Mnemosyne(upload_science_logs=True,
            interested_in_old_reps=True)
        self.mnemosyne.components.insert(0, (
            ("mnemosyne.libmnemosyne.translators.gettext_translator",
             "GetTextTranslator")))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.main_widget",
             "MainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne.web_server.review_wdgt",
             "ReviewWdgt"))
        self.mnemosyne.components.append(\
            ("mnemosyne.web_server.web_server_render_chain",
             "WebServerRenderChain"))
        self.mnemosyne.initialise(self.data_dir, config_dir=self.config_dir,
            filename=self.filename, automatic_upgrades=False)
        self.mnemosyne.review_controller().set_render_chain("web_server")
        self.save_after_n_reps = self.mnemosyne.config()["save_after_n_reps"]
        self.mnemosyne.config()["save_after_n_reps"] = 1
        self.mnemosyne.start_review()
        self.mnemosyne.review_widget().set_is_server_local(\
            self.is_server_local)
        self.is_mnemosyne_loaded = True
        self.release_database_after_timeout = \
            ReleaseDatabaseAfterTimeout(self.port)
        self.release_database_after_timeout.start()

    def unload_mnemosyne(self):
        if not self.is_mnemosyne_loaded:
            return
        self.mnemosyne.config()["save_after_n_reps"] = self.save_after_n_reps
        self.mnemosyne.finalise()
        self.is_mnemosyne_loaded = False

    def wsgi_app(self, environ, start_response):
        filename = environ["PATH_INFO"].decode("utf-8")
        if filename == "/status":
            response_headers = [("Content-type", "text/html")]
            start_response("200 OK", response_headers)
            return ["200 OK"]
        # Sometimes, even after the user has clicked 'exit' in the page,
        # a browser sends a request for e.g. an audio file.
        if self.is_shutting_down and filename != "/release_database":
            response_headers = [("Content-type", "text/html")]
            start_response("503 Service Unavailable", response_headers)
            return ["Server stopped"]
        # Load database if needed.
        if not self.is_mnemosyne_loaded and filename != "/release_database":
            self.load_mnemosyne()
        self.release_database_after_timeout.ping()
        # All our request return to the root page, so if the path is '/',
        # return the html of the review widget.
        if filename == "/":
            # Process clicked buttons in the form.
            form = cgi.FieldStorage(fp=environ["wsgi.input"], environ=environ)
            if "show_answer" in form and not self.is_just_started:
                self.mnemosyne.review_widget().show_answer()
                page = self.mnemosyne.review_widget().to_html()
            elif "grade" in form and not self.is_just_started:
                grade = int(form["grade"].value)
                self.mnemosyne.review_widget().grade_answer(grade)
                page = self.mnemosyne.review_widget().to_html()
            elif "star" in form:
                self.mnemosyne.controller().star_current_card()
                page = self.mnemosyne.review_widget().to_html()
            elif "exit" in form:
                self.unload_mnemosyne()
                page = "Server stopped"
                self.wsgi_server.stop()
                self.stop_server_after_timeout = \
                    StopServerAfterTimeout(self.wsgi_server)
                self.stop_server_after_timeout.start()
                self.is_shutting_down = True
            else:
                page = self.mnemosyne.review_widget().to_html()
            if self.is_just_started:
                self.is_just_started = False
            # Serve the web page.
            response_headers = [("Content-type", "text/html")]
            start_response("200 OK", response_headers)
            return [page]
        elif filename == "/release_database":
            self.unload_mnemosyne()
            response_headers = [("Content-type", "text/html")]
            start_response("200 OK", response_headers)
            return ["200 OK"]
        # We need to serve a media file.
        else:
            full_path = self.mnemosyne.database().media_dir()
            for word in filename.split("/"):
                full_path = os.path.join(full_path, word)
            request = Request(environ)
            # Check if file exists, but work around Android not reporting
            # the correct filesystem encoding.
            try:
                exists = os.path.exists(full_path)
            except (UnicodeEncodeError, UnicodeDecodeError):
                _ENCODING = sys.getfilesystemencoding() or \
                    locale.getdefaultlocale()[1] or "utf-8"              
                full_path = full_path.encode(_ENCODING)
            if os.path.exists(full_path):
                etag = "%s-%s-%s" % (os.path.getmtime(full_path),
                    os.path.getsize(full_path), hash(full_path))
            else:
                etag = "none"
            app = FileApp(full_path, etag=etag)
            return app(request)(environ, start_response)
mnemosyne.components = [
    ("mnemosyne.libmnemosyne.translators.no_translator", "NoTranslator"),
    ("mnemosyne.ppygui_ui.main_wdgt", "MainWdgt"),
    ("mnemosyne.ppygui_ui.review_wdgt", "ReviewWdgt"),
    ("mnemosyne.ppygui_ui.render_chain_WM", "RenderChain_WM"),
    ("mnemosyne.libmnemosyne.databases.SQLite_no_pregenerated_data",
     "SQLite_NoPregeneratedData"),
    ("mnemosyne.libmnemosyne.configuration", "Configuration"),
    ("mnemosyne.libmnemosyne.loggers.database_logger", "DatabaseLogger"),
    ("mnemosyne.libmnemosyne.schedulers.SM2_mnemosyne", "SM2Mnemosyne"),
    ("mnemosyne.libmnemosyne.stopwatch", "Stopwatch"),
    ("mnemosyne.libmnemosyne.card_types.front_to_back", "FrontToBack"),
    ("mnemosyne.libmnemosyne.card_types.both_ways", "BothWays"),
    ("mnemosyne.libmnemosyne.card_types.vocabulary", "Vocabulary"),
    ("mnemosyne.libmnemosyne.controllers.default_controller",
     "DefaultController"),
    ("mnemosyne.libmnemosyne.review_controllers.SM2_controller",
     "SM2Controller"), ("mnemosyne.libmnemosyne.card_types.map", "MapPlugin"),
    ("mnemosyne.libmnemosyne.card_types.cloze", "ClozePlugin"),
    ("mnemosyne.libmnemosyne.criteria.default_criterion", "DefaultCriterion"),
    ("mnemosyne.libmnemosyne.databases.SQLite_criterion_applier",
     "DefaultCriterionApplier")
]

# Run Mnemosyne.
mnemosyne.initialise(data_dir=data_dir)
mnemosyne.start_review()
app.mainframe = mnemosyne.main_widget()
app.run()
mnemosyne.finalise()
Esempio n. 9
0
class WebServer(Component):
    def __init__(self,
                 component_manager,
                 port,
                 data_dir,
                 config_dir,
                 filename,
                 is_server_local=False):
        Component.__init__(self, component_manager)
        self.port = port
        self.data_dir = data_dir
        self.config_dir = config_dir
        self.filename = filename
        self.is_server_local = is_server_local
        # When restarting the server, make sure we discard info from the
        # browser resending the form from the previous session.
        self.is_just_started = True
        self.is_mnemosyne_loaded = False
        self.is_shutting_down = False
        self.wsgi_server = wsgiserver.CherryPyWSGIServer(\
            ("0.0.0.0", port), self.wsgi_app, server_name="localhost",
            numthreads=1, timeout=5)
        # We need to set the timeout relatively low, otherwise it will take
        # too long for the server to process a 'stop' request.

    def serve_until_stopped(self):
        try:
            self.wsgi_server.start()  # Sets self.wsgi_server.ready
        except KeyboardInterrupt:
            self.wsgi_server.stop()
            self.unload_mnemosyne()

    def stop(self):
        self.wsgi_server.stop()
        self.unload_mnemosyne()

    def load_mnemosyne(self):
        self.mnemosyne = Mnemosyne(upload_science_logs=True,
                                   interested_in_old_reps=True)
        self.mnemosyne.components.insert(
            0, (("mnemosyne.libmnemosyne.translators.gettext_translator",
                 "GetTextTranslator")))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.main_widget",
             "MainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne.web_server.review_wdgt",
             "ReviewWdgt"))
        self.mnemosyne.components.append(\
            ("mnemosyne.web_server.web_server_render_chain",
             "WebServerRenderChain"))
        self.mnemosyne.initialise(self.data_dir,
                                  config_dir=self.config_dir,
                                  filename=self.filename,
                                  automatic_upgrades=False)
        self.mnemosyne.review_controller().set_render_chain("web_server")
        self.save_after_n_reps = self.mnemosyne.config()["save_after_n_reps"]
        self.mnemosyne.config()["save_after_n_reps"] = 1
        self.mnemosyne.start_review()
        self.mnemosyne.review_widget().set_is_server_local(\
            self.is_server_local)
        self.is_mnemosyne_loaded = True
        self.release_database_after_timeout = \
            ReleaseDatabaseAfterTimeout(self.port)
        self.release_database_after_timeout.start()

    def unload_mnemosyne(self):
        if not self.is_mnemosyne_loaded:
            return
        self.mnemosyne.config()["save_after_n_reps"] = self.save_after_n_reps
        self.mnemosyne.finalise()
        self.is_mnemosyne_loaded = False

    def wsgi_app(self, environ, start_response):
        filename = environ["PATH_INFO"].decode("utf-8")
        if filename == "/status":
            response_headers = [("Content-type", "text/html")]
            start_response("200 OK", response_headers)
            return ["200 OK"]
        # Sometimes, even after the user has clicked 'exit' in the page,
        # a browser sends a request for e.g. an audio file.
        if self.is_shutting_down and filename != "/release_database":
            response_headers = [("Content-type", "text/html")]
            start_response("503 Service Unavailable", response_headers)
            return ["Server stopped"]
        # Load database if needed.
        if not self.is_mnemosyne_loaded and filename != "/release_database":
            self.load_mnemosyne()
        self.release_database_after_timeout.ping()
        # All our request return to the root page, so if the path is '/',
        # return the html of the review widget.
        if filename == "/":
            # Process clicked buttons in the form.
            form = cgi.FieldStorage(fp=environ["wsgi.input"], environ=environ)
            if "show_answer" in form and not self.is_just_started:
                self.mnemosyne.review_widget().show_answer()
                page = self.mnemosyne.review_widget().to_html()
            elif "grade" in form and not self.is_just_started:
                grade = int(form["grade"].value)
                self.mnemosyne.review_widget().grade_answer(grade)
                page = self.mnemosyne.review_widget().to_html()
            elif "star" in form:
                self.mnemosyne.controller().star_current_card()
                page = self.mnemosyne.review_widget().to_html()
            elif "exit" in form:
                self.unload_mnemosyne()
                page = "Server stopped"
                self.wsgi_server.stop()
                self.stop_server_after_timeout = \
                    StopServerAfterTimeout(self.wsgi_server)
                self.stop_server_after_timeout.start()
                self.is_shutting_down = True
            else:
                page = self.mnemosyne.review_widget().to_html()
            if self.is_just_started:
                self.is_just_started = False
            # Serve the web page.
            response_headers = [("Content-type", "text/html")]
            start_response("200 OK", response_headers)
            return [page]
        elif filename == "/release_database":
            self.unload_mnemosyne()
            response_headers = [("Content-type", "text/html")]
            start_response("200 OK", response_headers)
            return ["200 OK"]
        # We need to serve a media file.
        else:
            full_path = self.mnemosyne.database().media_dir()
            for word in filename.split("/"):
                full_path = os.path.join(full_path, word)
            request = Request(environ)
            # Check if file exists, but work around Android not reporting
            # the correct filesystem encoding.
            try:
                exists = os.path.exists(full_path)
            except (UnicodeEncodeError, UnicodeDecodeError):
                _ENCODING = sys.getfilesystemencoding() or \
                    locale.getdefaultlocale()[1] or "utf-8"
                full_path = full_path.encode(_ENCODING)
            if os.path.exists(full_path):
                etag = "%s-%s-%s" % (os.path.getmtime(full_path),
                                     os.path.getsize(full_path),
                                     hash(full_path))
            else:
                etag = "none"
            app = FileApp(full_path, etag=etag)
            return app(request)(environ, start_response)
Esempio n. 10
0
class TestCrammingScheduler(MnemosyneTest):

    def setup(self):
        self.initialise_data_dir()

        self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True,
            asynchronous_database=True)
        self.mnemosyne.components.insert(0,
           ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_cramming", "Widget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)

        from mnemosyne.libmnemosyne.plugins.cramming_plugin import CrammingPlugin
        for plugin in self.plugins():
            if isinstance(plugin, CrammingPlugin):
                plugin.activate()
                break
        self.mnemosyne.start_review()

    def test_1(self):
        from mnemosyne.libmnemosyne.schedulers.cramming import Cramming

        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]
        fact_data = {"f": "2", "b": "b"}
        card_2 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]
        fact_data = {"f": "3", "b": "b"}
        card_3 = self.controller().create_new_cards(fact_data, card_type,
                     grade=2, tag_names=["default"])[0]
        fact_data = {"f": "4", "b": "b"}
        card_4 = self.controller().create_new_cards(fact_data, card_type,
                     grade=2, tag_names=["default"])[0]
        card_4.next_rep -= 1000
        self.database().update_card(card_4)
        self.review_controller().start_review()

        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4
        assert self.database().scheduler_data_count(Cramming.WRONG) == 0
        self.review_controller().grade_answer(0)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        self.review_controller().grade_answer(5)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 2
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        # Fail the cards a couple of times.
        for i in range(8):
            self.review_controller().grade_answer(0)
        # Pass the cards a couple of times.
        for i in range(8):
            self.review_controller().grade_answer(5)

    def test_reset(self):
        from mnemosyne.libmnemosyne.schedulers.cramming import Cramming

        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]
        fact_data = {"f": "2", "b": "b"}
        card_2 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]
        fact_data = {"f": "3", "b": "b"}
        card_3 = self.controller().create_new_cards(fact_data, card_type,
                     grade=2, tag_names=["default"])[0]
        fact_data = {"f": "4", "b": "b"}
        card_4 = self.controller().create_new_cards(fact_data, card_type,
                     grade=2, tag_names=["default"])[0]
        card_4.next_rep -= 1000
        self.database().update_card(card_4)
        self.review_controller().start_review()

        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4
        assert self.database().scheduler_data_count(Cramming.WRONG) == 0
        assert self.review_controller().counters() == (0, 4, 4)
        self.review_controller().grade_answer(0)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        assert self.review_controller().counters() == (1, 3, 4)
        self.review_controller().reset_but_try_to_keep_current_card()
        self.review_controller().update_dialog(redraw_all=True)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        assert self.review_controller().counters() == (1, 3, 4)

    def test_2(self):
        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]

        self.review_controller().show_new_question()
        self.controller().delete_current_card()
        assert self.review_controller().card == None

    def test_3(self):
        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]

        self.review_controller().show_new_question()
        self.review_controller().show_answer()
        self.review_controller().grade_answer(0)
        self.review_controller().counters()

        self.mnemosyne.finalise()
        self.mnemosyne.components.insert(0,
                                         ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_cramming", "Widget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))        
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)
        self.mnemosyne.start_review()

        assert self.scheduler().name == "cramming"

    def test_4(self):
        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]

        self.review_controller().show_new_question()
        self.database().unload()
        self.review_controller().reset()
        self.restart()
Esempio n. 11
0
class MnemosyneTest():
    
    def initialise_data_dir(self, data_dir="dot_test"):
        # Creating a new database seems a very time-consuming operation,
        # so we don't delete the test directory everytime, but take a short
        # cut.
        
        # Note: disabled this, as it does not seem to be very reliable.
        shutil.rmtree(data_dir, ignore_errors=True)
        
        if os.path.exists(data_dir):
            shutil.copy(os.path.join("tests", "files", "empty.db"), 
                        os.path.join(data_dir, "default.db"))
            for directory in ["default.db_media", "plugins", "backups",
                              "history"]:
                full_path = unicode(os.path.join(data_dir, directory))
                if os.path.exists(full_path):
                    shutil.rmtree(full_path)
            for file in ["default.db-journal", "config", 
                         "config.py", "machine.id", "log.txt"]:
                full_path = unicode(os.path.join(data_dir, file))
                if os.path.exists(full_path):
                    os.remove(full_path)
 
    def setup(self):
        self.initialise_data_dir()
        self.restart()

    def restart(self):
        # If there is another Mnemosyne still running, finalise it so as to
        # avoid having multiple component_managers active.
        if hasattr(self, "mnemosyne"):
            try:
                self.mnemosyne.finalise()
            except:
                pass
        self.mnemosyne = Mnemosyne(upload_science_logs=False, 
            interested_in_old_reps=True, asynchronous_database=True)
        self.mnemosyne.components.insert(0,
            ("mnemosyne.libmnemosyne.translators.gettext_translator",
             "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.mnemosyne.start_review()

    def teardown(self):
        self.mnemosyne.finalise()
        # Avoid having multiple component_managers active.
        from mnemosyne.libmnemosyne.component_manager import clear_component_managers
        clear_component_managers()

    def config(self):
        return self.mnemosyne.component_manager.current("config")

    def log(self):
        return self.mnemosyne.component_manager.current("log")

    def database(self):
        return self.mnemosyne.component_manager.current("database")

    def scheduler(self):
        return self.mnemosyne.component_manager.current("scheduler")

    def main_widget(self):
        return self.mnemosyne.component_manager.current("main_widget")

    def review_widget(self):
        return self.mnemosyne.component_manager.current("review_widget")

    def controller(self):
        return self.mnemosyne.component_manager.current("controller")

    def review_controller(self):
        return self.mnemosyne.component_manager.current("review_controller")

    def card_types(self):
        return self.mnemosyne.component_manager.all("card_type")

    def filters(self):
        return self.mnemosyne.component_manager.all("filter")

    def plugins(self):
        return self.mnemosyne.component_manager.all("plugin")

    def render_chain(self, id="default"):
        return self.mnemosyne.component_manager.render_chain_by_id[id]

    def card_type_with_id(self, id):
        return self.mnemosyne.component_manager.card_type_with_id[id]
Esempio n. 12
0
     "DatabaseLogger"),
    ("mnemosyne.libmnemosyne.schedulers.SM2_mnemosyne",
     "SM2Mnemosyne"),
    ("mnemosyne.libmnemosyne.stopwatch",
     "Stopwatch"),
    ("mnemosyne.libmnemosyne.card_types.front_to_back",
     "FrontToBack"),
    ("mnemosyne.libmnemosyne.card_types.both_ways",
     "BothWays"),
    ("mnemosyne.libmnemosyne.card_types.vocabulary",
     "Vocabulary"),
    ("mnemosyne.libmnemosyne.controllers.default_controller",
     "DefaultController"),
    ("mnemosyne.libmnemosyne.review_controllers.SM2_controller",
     "SM2Controller"),
    ("mnemosyne.libmnemosyne.card_types.map",
     "MapPlugin"),
    ("mnemosyne.libmnemosyne.card_types.cloze",
     "ClozePlugin"),
    ("mnemosyne.libmnemosyne.criteria.default_criterion",
     "DefaultCriterion"),
    ("mnemosyne.libmnemosyne.databases.SQLite_criterion_applier",
     "DefaultCriterionApplier") ]

# Run Mnemosyne.
mnemosyne.initialise(data_dir=data_dir)
mnemosyne.start_review()
app.mainframe = mnemosyne.main_widget()
app.run()
mnemosyne.finalise()
Esempio n. 13
0
class TestCrammingScheduler(MnemosyneTest):
    def setup(self):
        self.initialise_data_dir()
        path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne",
                            "renderers")
        if path not in sys.path:
            sys.path.append(path)
        self.mnemosyne = Mnemosyne(upload_science_logs=False,
                                   interested_in_old_reps=True,
                                   asynchronous_database=True)
        self.mnemosyne.components.insert(
            0, ("mnemosyne.libmnemosyne.translators.gettext_translator",
                "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_cramming", "Widget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.gui_for_component["CramAll"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.config()["study_mode"] = "CramAll"
        self.mnemosyne.start_review()

    def test_1(self):
        from mnemosyne.libmnemosyne.schedulers.cramming import Cramming

        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=-1,
                                                    tag_names=["default"])[0]
        fact_data = {"f": "2", "b": "b"}
        card_2 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=-1,
                                                    tag_names=["default"])[0]
        fact_data = {"f": "3", "b": "b"}
        card_3 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=2,
                                                    tag_names=["default"])[0]
        fact_data = {"f": "4", "b": "b"}
        card_4 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=2,
                                                    tag_names=["default"])[0]
        card_4.next_rep -= 1000
        self.database().update_card(card_4)
        self.review_controller().reset()

        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4
        assert self.database().scheduler_data_count(Cramming.WRONG) == 0
        self.review_controller().grade_answer(0)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        self.review_controller().grade_answer(5)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 2
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        # Fail the cards a couple of times.
        for i in range(8):
            self.review_controller().grade_answer(0)
        # Pass the cards a couple of times.
        for i in range(8):
            self.review_controller().grade_answer(5)

    def test_reset(self):
        from mnemosyne.libmnemosyne.schedulers.cramming import Cramming

        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=-1,
                                                    tag_names=["default"])[0]
        fact_data = {"f": "2", "b": "b"}
        card_2 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=-1,
                                                    tag_names=["default"])[0]
        fact_data = {"f": "3", "b": "b"}
        card_3 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=2,
                                                    tag_names=["default"])[0]
        fact_data = {"f": "4", "b": "b"}
        card_4 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=2,
                                                    tag_names=["default"])[0]
        card_4.next_rep -= 1000
        self.database().update_card(card_4)
        self.review_controller().reset()

        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4
        assert self.database().scheduler_data_count(Cramming.WRONG) == 0
        assert self.review_controller().counters() == (0, 4, 4)
        self.review_controller().grade_answer(0)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        assert self.review_controller().counters() == (1, 3, 4)
        self.review_controller().reset_but_try_to_keep_current_card()
        self.review_controller().update_dialog(redraw_all=True)
        assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3
        assert self.database().scheduler_data_count(Cramming.WRONG) == 1
        assert self.review_controller().counters() == (1, 3, 4)

    def test_2(self):
        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=-1,
                                                    tag_names=["default"])[0]

        self.review_controller().show_new_question()
        self.controller().delete_current_card()
        assert self.review_controller().card == None

    def test_3(
            self
    ):  # suffers from some sort of race condition with the finalise.
        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=-1,
                                                    tag_names=["default"])[0]

        self.review_controller().show_new_question()
        self.review_controller().show_answer()
        self.review_controller().grade_answer(0)
        self.review_controller().counters()

        self.mnemosyne.finalise()

        self.mnemosyne.components.insert(
            0, ("mnemosyne.libmnemosyne.translators.gettext_translator",
                "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_cramming", "Widget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.mnemosyne.start_review()

        assert self.scheduler().name == "cramming"

    def test_4(self):
        card_type = self.card_type_with_id("1")

        fact_data = {"f": "1", "b": "b"}
        card_1 = self.controller().create_new_cards(fact_data,
                                                    card_type,
                                                    grade=-1,
                                                    tag_names=["default"])[0]

        self.review_controller().reset()
        self.review_controller().show_new_question()
        self.database().unload()
        self.review_controller().reset()
        self.restart()
Esempio n. 14
0
class TestLogging(MnemosyneTest):

    def restart(self):
        self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True,
            asynchronous_database=True)
        self.mnemosyne.components.insert(0,
           ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)
        self.mnemosyne.start_review()

    def test_logging(self):
        card_type = self.card_type_with_id("1")
        fact_data = {"f": "1", "b": "b"}
        card = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]
        card_id_1 = card.id
        self.review_controller().show_new_question()
        self.review_controller().grade_answer(0)
        self.review_controller().show_new_question()
        self.review_controller().grade_answer(1)
        self.review_controller().grade_answer(4)

        self.mnemosyne.finalise()
        self.restart()
        card_type = self.card_type_with_id("1")
        fact_data = {"f": "2", "b": "b"}
        card = self.controller().create_new_cards(fact_data, card_type,
                     grade=-1, tag_names=["default"])[0]
        self.review_controller().show_new_question()
        self.controller().delete_current_card()

        self.log().dump_to_science_log()

        sql_res = self.database().con.execute(\
            "select * from log where _id=1").fetchone()
        assert sql_res[1] == EventTypes.STARTED_PROGRAM

        sql_res = self.database().con.execute(\
            "select * from log where _id=2").fetchone()
        assert sql_res[1] == EventTypes.STARTED_SCHEDULER

        sql_res = self.database().con.execute(\
            "select * from log where _id=3").fetchone()
        assert sql_res[1] == EventTypes.LOADED_DATABASE
        assert sql_res[6] == 0
        assert sql_res[7] == 0
        assert sql_res[8] == 0

        sql_res = self.database().con.execute(\
            "select * from log where _id=11").fetchone()
        assert sql_res[1] == EventTypes.ADDED_TAG
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=12").fetchone()
        assert sql_res[1] == EventTypes.EDITED_CRITERION
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=13").fetchone()
        assert sql_res[1] == EventTypes.ADDED_FACT
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=14").fetchone()
        assert sql_res[1] == EventTypes.ADDED_CARD
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=15").fetchone()
        assert sql_res[1] == EventTypes.REPETITION
        assert sql_res[6] == 1
        assert sql_res[7] == 0
        assert sql_res[11] == 0
        assert sql_res[12] == 0
        assert sql_res[14] - sql_res[2] == 0
        assert sql_res[13] == 0
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=16").fetchone()
        assert sql_res[1] == EventTypes.REPETITION
        assert sql_res[6] == 2
        assert sql_res[7] == 0
        assert sql_res[11] == 0
        assert sql_res[12] <= 10 # Depends on CPU load.
        assert sql_res[14] - sql_res[2] == 0
        assert sql_res[13] == 0

        sql_res = self.database().con.execute(\
            "select * from log where _id=17").fetchone()
        assert sql_res[1] == EventTypes.REPETITION
        assert sql_res[6] == 3
        assert sql_res[7] == 0
        assert sql_res[11] == 0
        assert sql_res[12] <= 10 # Depends on CPU load.
        new_interval = sql_res[14] - sql_res[2]
        assert new_interval > 0
        assert sql_res[13] == 0

        sql_res = self.database().con.execute(\
            "select * from log where _id=18").fetchone()
        assert sql_res[1] == EventTypes.SAVED_DATABASE
        assert sql_res[6] == 0
        assert sql_res[7] == 0
        assert sql_res[8] == 1

        sql_res = self.database().con.execute(\
            "select * from log where _id=19").fetchone()
        assert sql_res[1] == EventTypes.STOPPED_PROGRAM

        sql_res = self.database().con.execute(\
            "select * from log where _id=20").fetchone()
        assert sql_res[1] == EventTypes.STARTED_PROGRAM

        sql_res = self.database().con.execute(\
            "select * from log where _id=21").fetchone()
        assert sql_res[1] == EventTypes.STARTED_SCHEDULER

        sql_res = self.database().con.execute(\
            "select * from log where _id=22").fetchone()
        assert sql_res[1] == EventTypes.LOADED_DATABASE
        assert sql_res[6] == 0
        assert sql_res[7] == 0
        assert sql_res[8] == 1

        sql_res = self.database().con.execute(\
            "select * from log where _id=30").fetchone()
        assert sql_res[1] == EventTypes.ADDED_FACT
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=31").fetchone()
        assert sql_res[1] == EventTypes.ADDED_CARD

        sql_res = self.database().con.execute(\
            "select * from log where _id=32").fetchone()
        assert sql_res[1] == EventTypes.DELETED_CARD
        assert sql_res[3] is not None

        sql_res = self.database().con.execute(\
            "select * from log where _id=33").fetchone()
        assert sql_res[1] == EventTypes.DELETED_FACT
        assert sql_res[3] is not None

        self.config()["upload_science_logs"] = True
        self.database().dump_to_science_log()

        logfile = os.path.join(os.path.abspath("dot_test"), "log.txt")
        found = False
        for line in file(logfile):
            if "R " + card_id_1 + " 4" in line:
                found = True
                assert str(new_interval) + " 0 | 0.0" in line
        assert found == True

    def test_unique_index(self):
        fact_data = {"f": "question",
                     "b": "answer"}
        card_type_2 = self.card_type_with_id("2")
        card_1, card_2 = self.controller().create_new_cards(fact_data, card_type_2,
                                              grade=-1, tag_names=["default"])
        log_index = self.database().con.execute(\
            """select _id from log order by _id desc limit 1""").fetchone()[0]
        # Note: we need to keep the last log entry intact, otherwise indexes
        # start again at 1 and mess up the sync.
        self.database().con.execute("""delete from log where _id <?""", (log_index,))
        self.database().con.execute("""vacuum""")
        fact_data = {"f": "question2",
                     "b": "answer2"}
        card_type_2 = self.card_type_with_id("1")
        card_1  = self.controller().create_new_cards(fact_data, card_type_2,
                                              grade=-1, tag_names=["default"])
        assert self.database().con.execute(\
            """select _id from log order by _id limit 1""").fetchone()[0] \
            == log_index

    def test_recover_user_id(self):
        assert self.config()["user_id"] is not None
        MnemosyneTest.teardown(self)

        file(os.path.join(os.getcwd(), "dot_test", "history", "userid_001.bz2"), "w")
        os.remove(os.path.join(os.getcwd(), "dot_test", "config.db"))

        self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True,
            asynchronous_database=True)
        self.mnemosyne.components.insert(0,
           ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)

        assert self.config()["user_id"] == "userid"

    def test_recover_user_id_2(self):
        assert self.config()["user_id"] is not None
        MnemosyneTest.teardown(self)

        file(os.path.join(os.getcwd(), "dot_test", "history", "userid_machine_001.bz2"), "w")
        os.remove(os.path.join(os.getcwd(), "dot_test", "config.db"))

        self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True,
            asynchronous_database=True)
        self.mnemosyne.components.insert(0,
           ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)

        assert self.config()["user_id"] == "userid"

    def test_log_index_of_last_upload_1(self):
        assert self.log().log_index_of_last_upload() == 0

    def test_log_index_of_last_upload_2(self):
        machine_id = self.config().machine_id()
        for filename in ["user_001.bz2", "user_%s_2.bz2" % machine_id]:
            file(os.path.join(os.getcwd(), "dot_test", "history", filename), "w")
        assert self.log().log_index_of_last_upload() == 2

    def test_log_index_of_last_upload_3(self):
        machine_id = self.config().machine_id()
        for filename in ["user_001.bz2"]:
            file(os.path.join(os.getcwd(), "dot_test", "history", filename), "w")
        assert self.log().log_index_of_last_upload() == 1

    def test_log_index_of_last_upload_4(self):
        machine_id = self.config().machine_id()
        for filename in ["user_005.bz2"]:
            file(os.path.join(os.getcwd(), "dot_test", "history", filename), "w")
        assert self.log().log_index_of_last_upload() == 5

    def test_log_index_of_last_upload_5(self):
        machine_id = self.config().machine_id()
        for filename in ["user_othermachine_005.bz2"]:
            file(os.path.join(os.getcwd(), "dot_test", "history", filename), "w")
        assert self.log().log_index_of_last_upload() == 0

    def test_log_index_of_last_upload_6(self):
        machine_id = self.config().machine_id()
        for filename in ["user_othermachine_005.bz2", "user_%s_2.bz2" % machine_id]:
            file(os.path.join(os.getcwd(), "dot_test", "history", filename), "w")
        assert self.log().log_index_of_last_upload() == 2

    def test_log_index_of_last_upload_7(self):
        machine_id = self.config().machine_id()
        for filename in ["user_001.bz2", "user_othermachine_005.bz2", "user_%s_2.bz2" % machine_id]:
            file(os.path.join(os.getcwd(), "dot_test", "history", filename), "w")
        assert self.log().log_index_of_last_upload() == 2

    def test_log_upload(self):
        machine_id_file = os.path.join(self.mnemosyne.config().config_dir, "machine.id")
        f = file(machine_id_file, "w")
        print >> f, "TESTMACHINE"
        f.close()
        self.config().change_user_id("UPLOADTEST")
        self.config()["max_log_size_before_upload"] = 1
        MnemosyneTest.teardown(self)

        self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True,
            asynchronous_database=True)
        self.mnemosyne.components.insert(0,
           ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)
        self.mnemosyne.start_review()
        MnemosyneTest.teardown(self)

        self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True,
            asynchronous_database=True)
        self.mnemosyne.components.insert(0,
           ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)
        self.mnemosyne.start_review()
        MnemosyneTest.teardown(self)

        self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True,
            asynchronous_database=True)
        self.mnemosyne.components.insert(0,
           ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)
        self.mnemosyne.start_review()


    def test_log_upload_bad_server(self):
        # Most reliable way of setting this variable is throug config.py, otherwise
        # it will stay alive in a dangling imported userconfig.
        config_py_file = os.path.join(self.mnemosyne.config().config_dir, "config.py")
        f = file(config_py_file, "w")
        print >> f, "science_server = \"noserver:80\""
        f.close()

        machine_id_file = os.path.join(self.mnemosyne.config().config_dir, "machine.id")
        f = file(machine_id_file, "w")
        print >> f, "TESTMACHINE"
        f.close()
        self.config().change_user_id("UPLOADTEST")
        self.config()["max_log_size_before_upload"] = 1
        MnemosyneTest.teardown(self)

        self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True,
            asynchronous_database=True)
        self.mnemosyne.components.insert(0,
           ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)
        self.mnemosyne.start_review()
        MnemosyneTest.teardown(self)

        self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True,
            asynchronous_database=True)
        self.mnemosyne.components.insert(0,
           ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))
        self.mnemosyne.components.append(\
            ("test_logging", "MyMainWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)
        self.mnemosyne.start_review()
        
    def mem_importer(self):
        for format in self.mnemosyne.component_manager.all("file_format"):
            if format.__class__.__name__ == "Mnemosyne1Mem":
                return format        

    def test_archive_old_logs(self):
        # Import old history.
        filename = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2",
                                "default.mem")
        self.mem_importer().do_import(filename)        
        assert self.database().con.execute("select count() from log").fetchone()[0] == 23
        assert not os.path.exists(os.path.join("dot_test", "archive"))
        # Archive.
        self.database().archive_old_logs()
        assert self.database().con.execute("select count() from log").fetchone()[0] == 12
        archive_name = os.listdir(os.path.join(os.getcwd(), "dot_test", "archive"))[0]
        archive_path = os.path.join(os.getcwd(), "dot_test", "archive", archive_name)
        import sqlite3
        arch_con = sqlite3.connect(archive_path)
        assert arch_con.execute("select count() from log").fetchone()[0] == 11