Esempio n. 1
0
class MyClient(Client):
    
    program_name = "Mnemosyne"
    program_version = "test"
    capabilities = "TODO"
    
    def __init__(self):
        os.system("rm -fr dot_benchmark")
        self.mnemosyne = Mnemosyne()
        self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator",
                             "GetTextTranslator"))
        self.mnemosyne.components.append(("test_sync", "Widget"))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.dialogs", "ProgressDialog"))
        self.mnemosyne.initialise(os.path.abspath(os.path.join(os.getcwdu(),
                                  "dot_benchmark")))
        self.mnemosyne.review_controller().reset()        
        Client.__init__(self, "client_machine_id", self.mnemosyne.database(),
                        self.mnemosyne.main_widget())
        
    def do_sync(self):
        self.sync("127.0.0.1", 8190, "user", "pass")
        self.mnemosyne.database().save()
Esempio n. 2
0
class MyServer(Server):

    program_name = "Mnemosyne"
    program_version = "test"
    capabilities = "TODO"

    def __init__(self):
        shutil.rmtree(os.path.abspath("dot_sync_server"), ignore_errors=True)
        self.mnemosyne = Mnemosyne(upload_science_logs=False,
                                   interested_in_old_reps=True)
        self.mnemosyne.components.insert(
            0,
            ("mnemosyne.libmnemosyne.gui_translator", "GetTextGuiTranslator"))
        self.mnemosyne.components.append(("test_sync", "Widget"))
        self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \
            [("mnemosyne_test", "TestReviewWidget")]
        self.mnemosyne.initialise(os.path.abspath("dot_sync_server"),
                                  automatic_upgrades=False)
        self.mnemosyne.config().change_user_id("user_id")
        self.mnemosyne.review_controller().reset()
        self.supports_binary_transfer = lambda x: False
        # Add 20 cards to database.
        card_type = self.mnemosyne.card_type_with_id("1")
        for i in range(20):
            fact_data = {"f": "question %d" % (i, ), "b": "answer"}
            self.mnemosyne.controller().create_new_cards(fact_data,
                                                         card_type,
                                                         grade=-1,
                                                         tag_names=["default"
                                                                    ])[0]
        self.mnemosyne.database().save()
        self.mnemosyne.database().release_connection()

    def authorise(self, login, password):
        return login == "user" and password == "pass"

    def load_database(self, database_name):
        self.mnemosyne.database().load(database_name)
        return self.mnemosyne.database()

    def unload_database(self, database):
        self.mnemosyne.database().release_connection()
        # Dirty way to make sure we restart the server and create a new database
        # (as opposed to keep sending old history back and forth)'
        self.wsgi_server.stop()

    def run(self):
        Server.__init__(self, "client_machine_id", 8186,
                        self.mnemosyne.main_widget())
        self.serve_until_stopped()
Esempio n. 3
0
class MyServer(Server):

    program_name = "Mnemosyne"
    program_version = "test"
    capabilities = "TODO"

    stop_after_sync = True

    def __init__(self):
        os.system("rm -rf sync_from_here")
        self.mnemosyne = Mnemosyne()
        self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator",
                             "GetTextTranslator"))
        self.mnemosyne.components.append(("test_sync", "Widget"))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.dialogs", "ProgressDialog"))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("sync_from_here"))
        self.mnemosyne.config().change_user_id("user_id")
        self.mnemosyne.review_controller().reset()
        # Add 20 cards to database.
        card_type = self.mnemosyne.card_type_by_id("1")
        for i in range (20):
            fact_data = {"q": "question %d" % (i,),
                         "a": "answer"}
            self.mnemosyne.controller().create_new_cards(fact_data, card_type,
                grade=-1, tag_names=["default"])[0]
        self.mnemosyne.database().save()
     
    def authorise(self, login, password):
        return login == "user" and password == "pass"

    def open_database(self, database_name):
        return self.mnemosyne.database()

    def run(self):
        Server.__init__(self, "client_machine_id", "192.168.2.54", 8186,
                        self.mnemosyne.main_widget())                
        # Because we stop_after_sync is True, serve_forever will actually stop
        # after one sync.
        self.serve_forever()
        self.mnemosyne.finalise()
Esempio n. 4
0
class MyServer(Server):

    program_name = "Mnemosyne"
    program_version = "test"
    capabilities = "TODO"

    def __init__(self):
        shutil.rmtree(os.path.abspath("dot_sync_server"), ignore_errors=True)
        self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True)
        self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator",
            "GetTextTranslator"))
        self.mnemosyne.components.append(("test_sync", "Widget"))
        self.mnemosyne.components.append(("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_sync_server"), automatic_upgrades=False)
        self.mnemosyne.config().change_user_id("user_id")
        self.mnemosyne.review_controller().reset()
        self.supports_binary_transfer = lambda x : False
        # Add 20 cards to database.
        card_type = self.mnemosyne.card_type_with_id("1")
        for i in range (20):
            fact_data = {"f": "question %d" % (i,),
                         "b": "answer"}
            self.mnemosyne.controller().create_new_cards(fact_data, card_type,
                grade=-1, tag_names=["default"])[0]
        self.mnemosyne.database().save()
        self.mnemosyne.database().release_connection()
     
    def authorise(self, login, password):
        return login == "user" and password == "pass"
    
    def load_database(self, database_name):
        self.mnemosyne.database().load(database_name)
        return self.mnemosyne.database()

    def unload_database(self, database):
        self.mnemosyne.database().release_connection()
        # Dirty way to make sure we restart the server and create a new database
        # (as opposed to keep sending old history back and forth)'
        self.wsgi_server.stop()
        
    def run(self):
        Server.__init__(self, "client_machine_id", 8186,
                        self.mnemosyne.main_widget())
        self.serve_until_stopped()
Esempio n. 5
0
class MyServer(Server, Thread):

    program_name = "Mnemosyne"
    program_version = "test"
    capabilities = "TODO"

    stop_after_sync = True

    def __init__(self):
        Thread.__init__(self)
        self.mnemosyne = Mnemosyne()
        self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator",
                             "GetTextTranslator"))
        self.mnemosyne.components.append(("test_sync", "Widget"))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.dialogs", "ProgressDialog"))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget"))
     
    def authorise(self, login, password):
        return login == "user" and password == "pass"

    def open_database(self, database_name):
        return self.mnemosyne.database()

    def run(self):
        # We only open the database connection inside the thread to prevent
        # access problems, as a single connection can only be used inside a
        # single thread.
        self.mnemosyne.initialise(os.path.abspath("sync_from_here"))
        self.mnemosyne.review_controller().reset()
        Server.__init__(self, "server_machine_id", "127.0.0.1", 8190,
                        self.mnemosyne.main_widget())
        # Because we stop_after_sync is True, serve_forever will actually stop
        # after one sync.
        self.serve_forever()
        self.mnemosyne.finalise()
Esempio n. 6
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. 7
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.gui_translators.gettext_gui_translator",
              "GetTextGuiTranslator")))
        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.gui_for_component["NewOnly"] = [\
            ("mnemosyne.web_server.review_wdgt",
             "ReviewWdgt")]
        self.mnemosyne.gui_for_component["CramAll"] = [\
            ("mnemosyne.web_server.review_wdgt",
             "ReviewWdgt")]
        self.mnemosyne.gui_for_component["CramRecent"] = [\
            ("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.review_widget().set_client_on_same_machine_as_server(\
            self.client_on_same_machine_as_server)
        self.mnemosyne.controller().reset_study_mode()
        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. 8
0
          "CurrentCard"),
         ("main_wdgt",
          "MainWdgt")]
mnemosyne.initialise(data_dir, filename=filename)

# Sync before starting the review server.
if mnemosyne.main_widget().show_question(\
    "Perform sync?", "Yes", "No", "") == 0:
    mnemosyne.controller().sync(sync_server, sync_port, sync_username,
                                sync_password)
    # Make sure the config gets picked up when starting a new
    # Mnemosyne instance in the web server.
    mnemosyne.config().save()

# Start review server.
mnemosyne.database().release_connection()
from mnemosyne.web_server.web_server import WebServerThread
web_server_thread = WebServerThread\
        (mnemosyne.component_manager, is_server_local=True)
web_server_thread.daemon = True
web_server_thread.start()
if mnemosyne.main_widget().show_question(\
    "Review server started. Either let Mnemosyne start Chrome, or, if you have problems with sound, start Firefox yourself and go to 127.0.0.1:8513, otherwise click below to start Chrome.",
    "Start Chrome", "Don't start Chrome", "") == 0:
    mnemosyne.main_widget().start_native_browser()
web_server_thread.join()

# Sync again after the user has closed the program from the web server.
if mnemosyne.main_widget().show_question(\
    "Perform sync?", "Yes", "No", "") == 0:
    mnemosyne.controller().sync(sync_server, sync_port, sync_username,
Esempio n. 9
0
class TestCardType(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_card_type", "DecoratedThreeSided"))
        self.mnemosyne.components.append(\
            ("test_card_type", "Widget"))
        self.mnemosyne.components.append(\
            ("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"),
                                  automatic_upgrades=False)
        self.review_controller().reset()

    def test_card_types(self):
        card_type = self.card_type_with_id("1")
        assert self.database().is_in_use(card_type) is False
        assert card_type.fact_key_with_name("Front") == "f"
        assert card_type.is_fact_data_valid({"f": "foo"}) == True
        assert self.card_type_with_id("1") == self.card_type_with_id("1")
        assert self.card_type_with_id("1") != None

    def test_database(self):
        card_type = self.card_type_with_id("1")
        card_type.fact_views[0].type_answer = True
        card_type.fact_views[0].extra_data = {"b": "b"}
        card_type = self.controller().clone_card_type(\
            card_type, ("1 clone"))
        card_type.extra_data = {"b": "b"}
        self.database().update_card_type(card_type)
        self.mnemosyne.component_manager.unregister(card_type)
        card_type_out = self.database().card_type(card_type.id,
                                                  is_id_internal=False)
        assert card_type_out.id == "1::1 clone"
        assert card_type_out.fact_key_with_name("Front") == "f"
        assert card_type_out.required_fact_keys == ["f"]
        assert card_type_out.is_fact_data_valid({"f": "foo"}) == True
        assert card_type_out.is_fact_data_valid({"q": "foo"}) == False
        assert card_type_out.fact_key_names() == ["Front", "Back"]

        assert card_type_out.fact_keys_and_names == card_type.fact_keys_and_names
        assert card_type_out.unique_fact_keys == card_type.unique_fact_keys
        assert card_type_out.keyboard_shortcuts == card_type.keyboard_shortcuts
        assert card_type_out.fact_views[0].type_answer == True
        assert card_type_out.fact_views[0].extra_data == {"b": "b"}
        assert card_type_out.extra_data == {"b": "b"}
        assert len(card_type.fact_views) == 1
        assert len(card_type_out.fact_views) == 1
        assert card_type_out.fact_views[0].id == \
               card_type.fact_views[0].id
        assert card_type_out.fact_views[0].name == \
               card_type.fact_views[0].name
        assert card_type_out.fact_views[0].q_fact_keys == \
               card_type.fact_views[0].q_fact_keys
        assert card_type_out.fact_views[0].a_fact_keys == \
               card_type.fact_views[0].a_fact_keys
        assert card_type_out.fact_views[0].a_on_top_of_q == \
               card_type.fact_views[0].a_on_top_of_q

        # Reset global variables.
        self.mnemosyne.component_manager.register(card_type)
        card_type = self.card_type_with_id("1")
        card_type.fact_views[0].type_answer = False
        card_type.fact_views[0].extra_data = {}

        card_type_orig = self.database().card_type("1", is_id_internal=False)
        assert card_type_orig.fact_views[0].type_answer == False

    def test_rename_two_clones(self):
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(\
            card_type, "1 clone")
        card_type = self.card_type_with_id("2")
        card_type_2 = self.controller().clone_card_type(\
                      card_type, "2 clone")

        self.controller().rename_card_type(card_type_1, "1 clone new")

        assert set([c.name for c in self.card_types() if \
            self.database().is_user_card_type(c)]) == \
            set(["1 clone new", "2 clone"])

    def test_rename_two_clones_b(self):
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(\
            card_type, "1 clone")
        card_type = self.card_type_with_id("2")
        card_type_2 = self.controller().clone_card_type(\
                      card_type, "2 clone")

        self.controller().rename_card_type(card_type_2, "2 clone new")

        assert set([c.name for c in self.card_types() if \
            self.database().is_user_card_type(c)]) == \
            set(["1 clone", "2 clone new"])

    def test_delete(self):
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(\
            card_type, "1 clone")
        card_type = self.card_type_with_id("2")
        card_type_2 = self.controller().clone_card_type(\
                      card_type, "2 clone")

        self.controller().delete_card_type(card_type_1)

        card_type_out = self.database().card_type(card_type_2.id,
                                                  is_id_internal=False)

        assert card_type_out.fact_views[0].id == \
               card_type_2.fact_views[0].id
        assert card_type_out.fact_views[0].name == \
               card_type_2.fact_views[0].name
        assert card_type_out.fact_views[0].q_fact_keys == \
               card_type_2.fact_views[0].q_fact_keys
        assert card_type_out.fact_views[0].a_fact_keys == \
               card_type_2.fact_views[0].a_fact_keys
        assert card_type_out.fact_views[0].a_on_top_of_q == \
               card_type_2.fact_views[0].a_on_top_of_q
        assert card_type_out.fact_views[1].id == \
               card_type_2.fact_views[1].id
        assert card_type_out.fact_views[1].name == \
               card_type_2.fact_views[1].name
        assert card_type_out.fact_views[1].q_fact_keys == \
               card_type_2.fact_views[1].q_fact_keys
        assert card_type_out.fact_views[1].a_fact_keys == \
               card_type_2.fact_views[1].a_fact_keys
        assert card_type_out.fact_views[1].a_on_top_of_q == \
               card_type_2.fact_views[1].a_on_top_of_q

    def test_delete_with_formatting(self):
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(\
            card_type, "1 clone")
        card_type = self.card_type_with_id("2")
        card_type_2 = self.controller().clone_card_type(\
                      card_type, "2 clone")

        self.config().set_card_type_property("background_colour", "black",
                                             card_type_1)

        self.controller().delete_card_type(card_type_1)

    def test_cannot_delete(self):
        global last_error
        last_error = None

        card_type = self.card_type_with_id("1")
        self.controller().delete_card_type(card_type)
        assert "in use" in last_error
        last_error = None

        card_type_1 = self.controller().clone_card_type(\
            card_type, "1 clone")
        card_type = self.card_type_with_id("2")
        card_type_2 = self.controller().clone_card_type(\
                      card_type, "2 clone")
        fact_data = {"f": "question", "b": "answer"}
        old_card = self.controller().create_new_cards(fact_data,
                                                      card_type_1,
                                                      grade=-1,
                                                      tag_names=["default"])[0]
        self.controller().delete_card_type(card_type_1)
        assert "in use" in last_error
        last_error = None

    def test_rename(self):
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(\
            card_type, "1 clone")
        self.controller().rename_card_type(card_type_1, "newname")
        card_type_out = self.database().card_type(card_type_1.id,
                                                  is_id_internal=False)
        assert card_type_out.name == "newname"

    def test_cannot_rename(self):
        global last_error
        last_error = None
        card_type = self.card_type_with_id("1")
        self.controller().rename_card_type(card_type, "newname")
        assert last_error.startswith("Cannot rename")
        last_error = None

    def test_cannot_rename_duplicate(self):
        global last_error
        last_error = None
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(\
            card_type, "1 clone")
        self.controller().rename_card_type(card_type_1, "Vocabulary")
        assert "in use" in last_error
        last_error = None

    def test_has_clones(self):
        global last_error
        last_error = None
        card_type = self.card_type_with_id("1")
        assert self.database().has_clones(card_type) == False
        card_type_1 = self.controller().clone_card_type(\
            card_type, "1 clone")
        card_type_2 = self.controller().clone_card_type(\
            card_type_1, "1 clone clone")
        assert self.database().has_clones(card_type) == True
        assert self.database().has_clones(card_type_1) == True
        self.controller().delete_card_type(card_type_1)
        assert "clone" in last_error
        last_error = None

    def test_clone_of_clone(self):
        card_type = self.card_type_with_id("1")
        assert self.database().is_user_card_type(card_type) == False
        card_type.fact_views[0].type_answer = True
        card_type.fact_views[0].extra_data = {"b": "b"}
        card_type = self.controller().clone_card_type(\
            card_type, ("1 clone"))
        assert self.database().is_user_card_type(card_type) == True
        card_type = self.controller().clone_card_type(\
            card_type, ("1 clone cloned"))
        assert self.database().is_user_card_type(card_type) == True
        card_type.extra_data = {"b": "b"}
        self.database().update_card_type(card_type)
        self.mnemosyne.component_manager.unregister(card_type)
        card_type_out = self.database().card_type(card_type.id,
                                                  is_id_internal=False)
        assert card_type_out.fact_key_with_name("Front") == "f"
        assert card_type_out.required_fact_keys == ["f"]
        assert card_type_out.is_fact_data_valid({"f": "foo"}) == True

        assert card_type_out.fact_keys_and_names == card_type.fact_keys_and_names
        assert card_type_out.unique_fact_keys == card_type.unique_fact_keys
        assert card_type_out.keyboard_shortcuts == card_type.keyboard_shortcuts
        assert card_type_out.fact_views[0].type_answer == True
        assert card_type_out.fact_views[0].extra_data == {"b": "b"}
        assert card_type_out.extra_data == {"b": "b"}
        assert len(card_type.fact_views) == 1
        assert len(card_type_out.fact_views) == 1
        assert card_type_out.fact_views[0].id == \
               card_type.fact_views[0].id
        assert card_type_out.fact_views[0].name == \
               card_type.fact_views[0].name
        assert card_type_out.fact_views[0].q_fact_keys == \
               card_type.fact_views[0].q_fact_keys
        assert card_type_out.fact_views[0].a_fact_keys == \
               card_type.fact_views[0].a_fact_keys
        assert card_type_out.fact_views[0].a_on_top_of_q == \
               card_type.fact_views[0].a_on_top_of_q

        # Reset global variables.
        self.mnemosyne.component_manager.register(card_type)
        card_type.fact_views[0].type_answer = False
        card_type.fact_views[0].extra_data = {}

        fact_data = {"f": "question", "b": "answer"}
        card = self.mnemosyne.controller().create_new_cards(
            fact_data, card_type, grade=-1, tag_names=["default"])[0]
        path = self.mnemosyne.database().path()
        self.mnemosyne.database().unload()
        self.mnemosyne.database().load(path)

    def test_decorators(self):
        fact_data = {
            "f": "foreign word",
            "p_1": "pronunciation",
            "m_1": "translation"
        }
        card_type = self.card_type_with_id("3_decorated")
        card = self.controller().create_new_cards(fact_data,
                                                  card_type,
                                                  grade=-1,
                                                  tag_names=["default"])[0]
        assert "What is the translation of foreign word?" in card.question()

    def test_properties(self):
        card_type = self.card_type_with_id("1")
        self.config().set_card_type_property("font", "myfont", card_type)
        self.config().set_card_type_property("background_colour", "mycolour",
                                             card_type)
        card_type = self.controller().clone_card_type(\
            card_type, ("1 clone"))
        assert self.config().card_type_property("font", card_type,
                                                'f') == "myfont"
        assert self.config().card_type_property("background_colour",
                                                card_type) == "mycolour"
Esempio n. 10
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)
class MyClient(Client):
    
    program_name = "Mnemosyne"
    program_version = "test"
    capabilities = "TODO"
    
    def __init__(self):
        shutil.rmtree(os.path.abspath("dot_sync_client"), ignore_errors=True)
        self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True)
        self.mnemosyne.components = [
            ("mnemosyne.libmnemosyne.translator",
             "NoTranslation"),    
            ("mnemosyne.libmnemosyne.databases.SQLite",
             "SQLite"), 
            ("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.renderers.html_css",
             "HtmlCss"),
            ("mnemosyne.libmnemosyne.filters.escape_to_html",
             "EscapeToHtml"),
            ("mnemosyne.libmnemosyne.filters.expand_paths",
             "ExpandPaths"),
            ("mnemosyne.libmnemosyne.filters.latex",
             "Latex"),
            ("mnemosyne.libmnemosyne.render_chains.default_render_chain",
             "DefaultRenderChain"),
            ("mnemosyne.libmnemosyne.render_chains.plain_text_chain",
             "PlainTextChain"), 
            ("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"), 
            ("mnemosyne.libmnemosyne.plugins.cramming_plugin",
             "CrammingPlugin") ]
        self.mnemosyne.components.append(("benchmark_sync_client", "Widget"))
        self.mnemosyne.components.append(("benchmark_sync_client", "MyReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath(os.path.join(os.getcwd(),
                                  "dot_sync_client")), automatic_upgrades=False)
        self.mnemosyne.config().change_user_id("user_id")
        self.check_for_edited_local_media_files = False
        self.do_backup = False     
        self.mnemosyne.review_controller().reset()
        # Do 200 reviews.
        card_type = self.mnemosyne.card_type_with_id("1")
        fact_data = {"f": "question",
                     "b": "answer"}
        card = self.mnemosyne.controller().create_new_cards(fact_data, card_type,
                grade=-1, tag_names=["default"])[0]
        self.mnemosyne.database().save()
        self.mnemosyne.review_controller().show_new_question()
        for i in range(200):
            self.mnemosyne.review_controller().show_answer()
            self.mnemosyne.review_controller().grade_answer(0)
        Client.__init__(self, "client_machine_id", self.mnemosyne.database(),
                        self.mnemosyne.main_widget())
        
    def do_sync(self):
        #self.BUFFER_SIZE = 10*8192
        #self.behind_proxy = True
        self.sync("localhost", 8186, "user", "pass")
        self.mnemosyne.database().save()
Esempio n. 12
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. 13
0
class TestCardType(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_card_type", "DecoratedThreeSided"))
        self.mnemosyne.components.append(("test_card_type", "Widget"))
        self.mnemosyne.components.append(("mnemosyne_test", "TestReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False)
        self.review_controller().reset()

    def test_card_types(self):
        card_type = self.card_type_with_id("1")
        assert self.database().is_in_use(card_type) is False
        assert card_type.fact_key_with_name("Front") == "f"
        assert card_type.is_fact_data_valid({"f": "foo"}) == True
        assert self.card_type_with_id("1") == self.card_type_with_id("1")
        assert self.card_type_with_id("1") != None

    def test_database(self):
        card_type = self.card_type_with_id("1")
        card_type.fact_views[0].type_answer = True
        card_type.fact_views[0].extra_data = {"b": "b"}
        card_type = self.controller().clone_card_type(card_type, ("1 clone"))
        card_type.extra_data = {"b": "b"}
        self.database().update_card_type(card_type)
        self.mnemosyne.component_manager.unregister(card_type)
        card_type_out = self.database().card_type(card_type.id, is_id_internal=False)
        assert card_type_out.id == "1::1 clone"
        assert card_type_out.fact_key_with_name("Front") == "f"
        assert card_type_out.required_fact_keys == ["f"]
        assert card_type_out.is_fact_data_valid({"f": "foo"}) == True
        assert card_type_out.is_fact_data_valid({"q": "foo"}) == False
        assert card_type_out.fact_key_names() == ["Front", "Back"]

        assert card_type_out.fact_keys_and_names == card_type.fact_keys_and_names
        assert card_type_out.unique_fact_keys == card_type.unique_fact_keys
        assert card_type_out.keyboard_shortcuts == card_type.keyboard_shortcuts
        assert card_type_out.fact_views[0].type_answer == True
        assert card_type_out.fact_views[0].extra_data == {"b": "b"}
        assert card_type_out.extra_data == {"b": "b"}
        assert len(card_type.fact_views) == 1
        assert len(card_type_out.fact_views) == 1
        assert card_type_out.fact_views[0].id == card_type.fact_views[0].id
        assert card_type_out.fact_views[0].name == card_type.fact_views[0].name
        assert card_type_out.fact_views[0].q_fact_keys == card_type.fact_views[0].q_fact_keys
        assert card_type_out.fact_views[0].a_fact_keys == card_type.fact_views[0].a_fact_keys
        assert card_type_out.fact_views[0].a_on_top_of_q == card_type.fact_views[0].a_on_top_of_q

        # Reset global variables.
        self.mnemosyne.component_manager.register(card_type)
        card_type = self.card_type_with_id("1")
        card_type.fact_views[0].type_answer = False
        card_type.fact_views[0].extra_data = {}

        card_type_orig = self.database().card_type("1", is_id_internal=False)
        assert card_type_orig.fact_views[0].type_answer == False

    def test_rename_two_clones(self):
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(card_type, "1 clone")
        card_type = self.card_type_with_id("2")
        card_type_2 = self.controller().clone_card_type(card_type, "2 clone")

        self.controller().rename_card_type(card_type_1, "1 clone new")

        assert set([c.name for c in self.card_types() if self.database().is_user_card_type(c)]) == set(
            ["1 clone new", "2 clone"]
        )

    def test_rename_two_clones_b(self):
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(card_type, "1 clone")
        card_type = self.card_type_with_id("2")
        card_type_2 = self.controller().clone_card_type(card_type, "2 clone")

        self.controller().rename_card_type(card_type_2, "2 clone new")

        assert set([c.name for c in self.card_types() if self.database().is_user_card_type(c)]) == set(
            ["1 clone", "2 clone new"]
        )

    def test_delete(self):
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(card_type, "1 clone")
        card_type = self.card_type_with_id("2")
        card_type_2 = self.controller().clone_card_type(card_type, "2 clone")

        self.controller().delete_card_type(card_type_1)

        card_type_out = self.database().card_type(card_type_2.id, is_id_internal=False)

        assert card_type_out.fact_views[0].id == card_type_2.fact_views[0].id
        assert card_type_out.fact_views[0].name == card_type_2.fact_views[0].name
        assert card_type_out.fact_views[0].q_fact_keys == card_type_2.fact_views[0].q_fact_keys
        assert card_type_out.fact_views[0].a_fact_keys == card_type_2.fact_views[0].a_fact_keys
        assert card_type_out.fact_views[0].a_on_top_of_q == card_type_2.fact_views[0].a_on_top_of_q
        assert card_type_out.fact_views[1].id == card_type_2.fact_views[1].id
        assert card_type_out.fact_views[1].name == card_type_2.fact_views[1].name
        assert card_type_out.fact_views[1].q_fact_keys == card_type_2.fact_views[1].q_fact_keys
        assert card_type_out.fact_views[1].a_fact_keys == card_type_2.fact_views[1].a_fact_keys
        assert card_type_out.fact_views[1].a_on_top_of_q == card_type_2.fact_views[1].a_on_top_of_q

    def test_delete_with_formatting(self):
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(card_type, "1 clone")
        card_type = self.card_type_with_id("2")
        card_type_2 = self.controller().clone_card_type(card_type, "2 clone")

        self.config().set_card_type_property("background_colour", "black", card_type_1)

        self.controller().delete_card_type(card_type_1)

    def test_cannot_delete(self):
        global last_error
        last_error = None

        card_type = self.card_type_with_id("1")
        self.controller().delete_card_type(card_type)
        assert "in use" in last_error
        last_error = None

        card_type_1 = self.controller().clone_card_type(card_type, "1 clone")
        card_type = self.card_type_with_id("2")
        card_type_2 = self.controller().clone_card_type(card_type, "2 clone")
        fact_data = {"f": "question", "b": "answer"}
        old_card = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["default"])[0]
        self.controller().delete_card_type(card_type_1)
        assert "in use" in last_error
        last_error = None

    def test_rename(self):
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(card_type, "1 clone")
        self.controller().rename_card_type(card_type_1, "newname")
        card_type_out = self.database().card_type(card_type_1.id, is_id_internal=False)
        assert card_type_out.name == "newname"

    def test_cannot_rename(self):
        global last_error
        last_error = None
        card_type = self.card_type_with_id("1")
        self.controller().rename_card_type(card_type, "newname")
        assert last_error.startswith("Cannot rename")
        last_error = None

    def test_cannot_rename_duplicate(self):
        global last_error
        last_error = None
        card_type = self.card_type_with_id("1")
        card_type_1 = self.controller().clone_card_type(card_type, "1 clone")
        self.controller().rename_card_type(card_type_1, "Vocabulary")
        assert "in use" in last_error
        last_error = None

    def test_has_clones(self):
        global last_error
        last_error = None
        card_type = self.card_type_with_id("1")
        assert self.database().has_clones(card_type) == False
        card_type_1 = self.controller().clone_card_type(card_type, "1 clone")
        card_type_2 = self.controller().clone_card_type(card_type_1, "1 clone clone")
        assert self.database().has_clones(card_type) == True
        assert self.database().has_clones(card_type_1) == True
        self.controller().delete_card_type(card_type_1)
        assert "clone" in last_error
        last_error = None

    def test_clone_of_clone(self):
        card_type = self.card_type_with_id("1")
        assert self.database().is_user_card_type(card_type) == False
        card_type.fact_views[0].type_answer = True
        card_type.fact_views[0].extra_data = {"b": "b"}
        card_type = self.controller().clone_card_type(card_type, ("1 clone"))
        assert self.database().is_user_card_type(card_type) == True
        card_type = self.controller().clone_card_type(card_type, ("1 clone cloned"))
        assert self.database().is_user_card_type(card_type) == True
        card_type.extra_data = {"b": "b"}
        self.database().update_card_type(card_type)
        self.mnemosyne.component_manager.unregister(card_type)
        card_type_out = self.database().card_type(card_type.id, is_id_internal=False)
        assert card_type_out.fact_key_with_name("Front") == "f"
        assert card_type_out.required_fact_keys == ["f"]
        assert card_type_out.is_fact_data_valid({"f": "foo"}) == True

        assert card_type_out.fact_keys_and_names == card_type.fact_keys_and_names
        assert card_type_out.unique_fact_keys == card_type.unique_fact_keys
        assert card_type_out.keyboard_shortcuts == card_type.keyboard_shortcuts
        assert card_type_out.fact_views[0].type_answer == True
        assert card_type_out.fact_views[0].extra_data == {"b": "b"}
        assert card_type_out.extra_data == {"b": "b"}
        assert len(card_type.fact_views) == 1
        assert len(card_type_out.fact_views) == 1
        assert card_type_out.fact_views[0].id == card_type.fact_views[0].id
        assert card_type_out.fact_views[0].name == card_type.fact_views[0].name
        assert card_type_out.fact_views[0].q_fact_keys == card_type.fact_views[0].q_fact_keys
        assert card_type_out.fact_views[0].a_fact_keys == card_type.fact_views[0].a_fact_keys
        assert card_type_out.fact_views[0].a_on_top_of_q == card_type.fact_views[0].a_on_top_of_q

        # Reset global variables.
        self.mnemosyne.component_manager.register(card_type)
        card_type.fact_views[0].type_answer = False
        card_type.fact_views[0].extra_data = {}

        fact_data = {"f": "question", "b": "answer"}
        card = self.mnemosyne.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0]
        path = self.mnemosyne.database().path()
        self.mnemosyne.database().unload()
        self.mnemosyne.database().load(path)

    def test_decorators(self):
        fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"}
        card_type = self.card_type_with_id("3_decorated")
        card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0]
        assert "What is the translation of foreign word?" in card.question()

    def test_properties(self):
        card_type = self.card_type_with_id("1")
        self.config().set_card_type_property("font", "myfont", card_type)
        self.config().set_card_type_property("background_colour", "mycolour", card_type)
        card_type = self.controller().clone_card_type(card_type, ("1 clone"))
        assert self.config().card_type_property("font", card_type, "f") == "myfont"
        assert self.config().card_type_property("background_colour", card_type) == "mycolour"
Esempio n. 14
0
class MyClient(Client):
    
    program_name = "Mnemosyne"
    program_version = "test"
    capabilities = "TODO"
    
    def __init__(self):
        shutil.rmtree(os.path.abspath("dot_sync_client"), ignore_errors=True)
        self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True)
        self.mnemosyne.components = [
            ("mnemosyne.libmnemosyne.translator",
             "NoTranslation"),    
            ("mnemosyne.libmnemosyne.databases.SQLite",
             "SQLite"), 
            ("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.renderers.html_css",
             "HtmlCss"),
            ("mnemosyne.libmnemosyne.filters.escape_to_html",
             "EscapeToHtml"),
            ("mnemosyne.libmnemosyne.filters.expand_paths",
             "ExpandPaths"),
            ("mnemosyne.libmnemosyne.filters.latex",
             "Latex"),
            ("mnemosyne.libmnemosyne.render_chains.default_render_chain",
             "DefaultRenderChain"),
            ("mnemosyne.libmnemosyne.render_chains.plain_text_chain",
             "PlainTextChain"), 
            ("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"), 
            ("mnemosyne.libmnemosyne.plugins.cramming_plugin",
             "CrammingPlugin") ]
        self.mnemosyne.components.append(("benchmark_sync_client", "Widget"))
        self.mnemosyne.components.append(("benchmark_sync_client", "MyReviewWidget"))
        self.mnemosyne.initialise(os.path.abspath(os.path.join(os.getcwdu(),
                                  "dot_sync_client")), automatic_upgrades=False)
        self.mnemosyne.config().change_user_id("user_id")
        self.check_for_edited_local_media_files = False
        self.do_backup = False     
        self.mnemosyne.review_controller().reset()
        # Do 200 reviews.
        card_type = self.mnemosyne.card_type_with_id("1")
        fact_data = {"f": "question",
                     "b": "answer"}
        card = self.mnemosyne.controller().create_new_cards(fact_data, card_type,
                grade=-1, tag_names=["default"])[0]
        self.mnemosyne.database().save()
        self.mnemosyne.review_controller().show_new_question()
        for i in range(200):
            self.mnemosyne.review_controller().show_answer()
            self.mnemosyne.review_controller().grade_answer(0)
        Client.__init__(self, "client_machine_id", self.mnemosyne.database(),
                        self.mnemosyne.main_widget())
        
    def do_sync(self):
        #self.BUFFER_SIZE = 10*8192
        #self.behind_proxy = True
        self.sync("localhost", 8186, "user", "pass")
        self.mnemosyne.database().save()
Esempio n. 15
0
          "CurrentCard"),
         ("main_wdgt", 
          "MainWdgt")]
mnemosyne.initialise(data_dir, filename=filename)

# Sync before starting the review server.
if mnemosyne.main_widget().show_question(\
    "Perform sync?", "Yes", "No", "") == 0:
    mnemosyne.controller().sync(sync_server, sync_port, 
        sync_username, sync_password)
    # Make sure the config gets picked up when starting a new
    # Mnemosyne instance in the web server.
    mnemosyne.config().save()

# Start review server.
mnemosyne.database().release_connection()
from mnemosyne.web_server.web_server import WebServerThread
web_server_thread = WebServerThread\
        (mnemosyne.component_manager, is_server_local=True)
web_server_thread.daemon = True
web_server_thread.start() 
if mnemosyne.main_widget().show_question(\
    "Review server started. Either let Mnemosyne start Chrome, or, if you have problems with sound, start Firefox yourself and go to 127.0.0.1:8513, otherwise click below to start Chrome.",
    "Start Chrome", "Don't start Chrome", "") == 0:
    mnemosyne.main_widget().start_native_browser()
web_server_thread.join()

# Sync again after the user has closed the program from the web server.
if mnemosyne.main_widget().show_question(\
    "Perform sync?", "Yes", "No", "") == 0:
    mnemosyne.controller().sync(sync_server, sync_port, 
Esempio n. 16
0
class MyClient(Client):
    
    program_name = "Mnemosyne"
    program_version = "test"
    capabilities = "TODO"
    
    def __init__(self):
        self.mnemosyne = Mnemosyne()
        self.mnemosyne.components = [
            ("mnemosyne.libmnemosyne.translator",
             "NoTranslation"),    
            ("mnemosyne.libmnemosyne.databases.SQLite",
             "SQLite"), 
            ("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.three_sided",
             "ThreeSided"),
            ("mnemosyne.libmnemosyne.renderers.html_css_old",
             "HtmlCssOld"),
            ("mnemosyne.libmnemosyne.filters.escape_to_html",
             "EscapeToHtml"),
            ("mnemosyne.libmnemosyne.filters.expand_paths",
             "ExpandPaths"),
            ("mnemosyne.libmnemosyne.filters.latex",
             "Latex"),
            ("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.activity_criteria.default_criterion",
             "DefaultCriterion"),
            ("mnemosyne.libmnemosyne.databases.SQLite_criterion_applier",
             "DefaultCriterionApplier"), 
            ("mnemosyne.libmnemosyne.plugins.cramming_plugin",
             "CrammingPlugin") ]
        self.mnemosyne.components.append(("benchmark_sync_client", "Widget"))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget"))
        self.mnemosyne.components.append(\
            ("mnemosyne.libmnemosyne.ui_components.dialogs", "ProgressDialog"))
        self.mnemosyne.initialise(os.path.abspath(os.path.join(os.getcwdu(),
                                  "dot_benchmark")))
        self.mnemosyne.config().change_user_id("user_id")
        self.mnemosyne.review_controller().reset()
        # Do 200 reviews.
        card_type = self.mnemosyne.card_type_by_id("1")
        fact_data = {"q": "question",
                     "a": "answer"}
        card = self.mnemosyne.controller().create_new_cards(fact_data, card_type,
                grade=-1, tag_names=["default"])[0]
        self.mnemosyne.database().save()
        self.mnemosyne.review_controller().new_question()
        for i in range(200):
            self.mnemosyne.review_controller().show_answer()
            self.mnemosyne.review_controller().grade_answer(0)
        Client.__init__(self, "client_machine_id", self.mnemosyne.database(),
                        self.mnemosyne.main_widget())
        
    def do_sync(self):
        self.sync("192.168.2.54", 8186, "user", "pass")
        self.mnemosyne.database().save()