Example #1
0
 def __init__(self, host, port, uri, database, controller, config, log, \
     ui_controller):
     self.config = config
     self.log = log
     self.host = host
     self.port = port
     self.uri = uri
     self.ui_controller = ui_controller
     self.eman = EventManager(database, log, controller, \
         self.config.mediadir(), self.get_media_file, self.ui_controller)
     self.login = ''
     self.passwd = ''
     self.id = hex(uuid.getnode())
     self.name = 'Mnemosyne'
     self.version = mnemosyne.version.version
     self.deck = 'default'
     self.protocol = PROTOCOL_VERSION
     self.cardtypes = N_SIDED_CARD_TYPE
     self.extra = ''
     self.stopped = False
Example #2
0
 def __init__(self, uri, database, config, log, ui_controller):
     params = urlparse(uri)
     self.host = params[0]
     self.port = int(params[2])
     self.config = config
     self.log = log
     self.ui_controller = ui_controller
     self.eman = EventManager(database, self.log, None, \
         self.config.mediadir(), None, self.ui_controller)
     self.httpd = MyWSGIServer(self.host, self.port, self.wsgi_app)
     self.httpd.update_events = self.ui_controller.update_events
     self.login = None
     self.passwd = None
     self.logged = False
     self.machine_id = hex(uuid.getnode())
     self.name = 'Mnemosyne'
     self.version = mnemosyne.version.version
     self.protocol = PROTOCOL_VERSION
     self.cardtypes = N_SIDED_CARD_TYPE
     self.upload_media = True
     self.read_only = False
Example #3
0
class Server:
    """Base server class for syncing."""

    DEFAULT_MIME = "xml/text"

    def __init__(self, uri, database, config, log, ui_controller):
        params = urlparse(uri)
        self.host = params[0]
        self.port = int(params[2])
        self.config = config
        self.log = log
        self.ui_controller = ui_controller
        self.eman = EventManager(database, self.log, None, \
            self.config.mediadir(), None, self.ui_controller)
        self.httpd = MyWSGIServer(self.host, self.port, self.wsgi_app)
        self.httpd.update_events = self.ui_controller.update_events
        self.login = None
        self.passwd = None
        self.logged = False
        self.machine_id = hex(uuid.getnode())
        self.name = 'Mnemosyne'
        self.version = mnemosyne.version.version
        self.protocol = PROTOCOL_VERSION
        self.cardtypes = N_SIDED_CARD_TYPE
        self.upload_media = True
        self.read_only = False

    def set_user(self, login, passwd):
        """Sets server login and password."""

        self.login = login
        self.passwd = passwd

    def get_method(self, environ):
        """
        Checks for method existence in service
        and checks for right request params.
        """

        def compare_args(list1, list2):
            """Compares two lists or tuples."""
            for item in list1:
                if not item in list2:
                    return False
            return True

        if environ.has_key('HTTP_AUTHORIZATION'):
            clogin, cpasswd = base64.decodestring(\
                environ['HTTP_AUTHORIZATION'].split(' ')[-1]).split(':')
            if clogin == self.login and cpasswd == self.passwd:
                self.logged = True
                status = '200 OK'
            else:
                status = '403 Forbidden'
            return status, "text/plain", None, None
        else:
            if not self.logged:
                return '403 Forbidden', "text/plain", None, None
            method = (environ['REQUEST_METHOD'] + \
                '_'.join(environ['PATH_INFO'].split('/'))).lower()
            if hasattr(self, method) and callable(getattr(self, method)):
                args = cgi.parse_qs(environ['QUERY_STRING'])
                args = dict([(key, val[0]) for key, val in args.iteritems()])
                if getattr(self, method).func_code.co_argcount-2 == len(args) \
                    and compare_args(args.keys(), getattr(self, method). \
                        func_code.co_varnames):                
                    return '200 OK', self.DEFAULT_MIME, method, args
                else:
                    return '400 Bad Request', "text/plain", None, None
            else:
                return '404 Not Found', "text/plain", None, None

    def wsgi_app(self, environ, start_response):
        """Simple Server wsgi application."""

        status, mime, method, args = self.get_method(environ)
        headers = [('Content-type', mime)]
        start_response(status, headers)
        if method:
            return getattr(self, method)(environ, **args)
        else:
            return status
    
    def start(self):
        """Activate server."""

        self.ui_controller.update_status("Waiting for client connection...")
        print "Server started at HOST:%s, PORT:%s" % (self.host, self.port)
        self.httpd.serve_forever()

    def stop(self):
        """Stops Server."""

        self.httpd.stop()
        self.eman.stop()

    def set_params(self, params):
        """Uses for setting non-default params."""

        for key in params.keys():
            setattr(self, key, params[key])

    def get_sync_server_params(self, environ):
        """Gets server specific params and sends it to client."""

        self.ui_controller.update_status(\
            "Sending server params to the client. Please, wait...")
        return "<params><server id='%s' name='%s' ver='%s' protocol='%s' " \
            "cardtypes='%s' upload='%s' readonly='%s'/></params>" % (\
            self.machine_id, self.name, self.version, self.protocol, \
            self.cardtypes, self.upload_media, self.read_only)

    def put_sync_client_params(self, environ):
        """Gets client specific params."""

        self.ui_controller.update_status(\
            "Receiving client params. Please, wait...")
        try:
            socket = environ['wsgi.input']
            client_params = socket.readline()
        except:
            return "CANCEL"
        else:
            self.eman.set_sync_params(client_params)
            self.eman.update_partnerships_table()
            return "OK"

    def get_sync_server_history_media_count(self, environ):
        """Gets self media files count."""

        return str(self.eman.get_media_count())

    def get_sync_server_history_length(self, environ):
        """Gets length of self history."""

        return str(self.eman.get_history_length())

    def get_sync_server_history(self, environ):
        """Gets self history events."""

        self.ui_controller.update_status(\
            "Sending history to the client. Please, wait...")
        count = 0
        hsize = float(self.eman.get_history_length() + 2)
        self.ui_controller.show_progressbar()
        for chunk in self.eman.get_history():
            count += 1
            fraction = count / hsize
            self.ui_controller.update_progressbar(fraction)
            if fraction == 1.0:
                self.ui_controller.hide_progressbar()
                self.ui_controller.update_status(\
                    "Waiting for the client complete. Please, wait...")
            yield (chunk + '\n')

    def get_sync_server_mediahistory(self, environ):
        """Gets self. media history."""

        self.ui_controller.update_status(\
            "Sending media history to client. Please, wait...")
        return self.eman.get_media_history()

    def put_sync_client_history(self, environ):
        """Gets client history and applys to self."""
       
        socket = environ['wsgi.input']

        count = 0
        # gets client history size
        hsize = float(socket.readline()) + 2

        self.eman.make_backup()
        self.ui_controller.update_status(\
            "Applying client history. Please, wait...")

        socket.readline()  #get "<history>"
        chunk = socket.readline()  #get first xml-event
        self.ui_controller.show_progressbar()
        while chunk != "</history>\r\n":
            self.eman.apply_event(chunk)
            chunk = socket.readline()
            count += 1
            self.ui_controller.update_progressbar(count / hsize)

        self.ui_controller.hide_progressbar()
        self.ui_controller.update_status(\
            "Waiting for the client complete. Please, wait...")
        return "OK"

    def get_sync_finish(self, environ):
        """Finishes syncing."""

        self.eman.remove_backup()
        self.ui_controller.update_status(\
            "Waiting for the client complete. Please, wait...")
        self.eman.update_last_sync_event()
        self.logged = False
        self.stop()
        return "OK"

    def get_sync_server_media(self, environ, fname):
        """Gets server media file and sends it to client."""

        self.ui_controller.update_status(\
            "Sending media to the client. Please, wait...")
        try:
            mediafile = open(os.path.join(self.config.mediadir(), fname))
            data = mediafile.read()
            mediafile.close()
        except IOError:
            return "CANCEL"
        else:
            return data

    def put_sync_client_media(self, environ, fname):
        """Gets client media and applys to self."""

        self.ui_controller.update_status(\
            "Receiving client media. Please, wait...")
        try:
            socket = environ['wsgi.input']
            size = int(environ['CONTENT_LENGTH'])
            data = socket.read(size)
        except:
            return "CANCEL"
        else:
            mfile = open(os.path.join(self.config.mediadir(), fname), 'w')
            mfile.write(data)
            mfile.close()
            return "OK"
Example #4
0
class Client:
    """Base client class for syncing."""

    def __init__(self, host, port, uri, database, controller, config, log, \
        ui_controller):
        self.config = config
        self.log = log
        self.host = host
        self.port = port
        self.uri = uri
        self.ui_controller = ui_controller
        self.eman = EventManager(database, log, controller, \
            self.config.mediadir(), self.get_media_file, self.ui_controller)
        self.login = ''
        self.passwd = ''
        self.id = hex(uuid.getnode())
        self.name = 'Mnemosyne'
        self.version = mnemosyne.version.version
        self.deck = 'default'
        self.protocol = PROTOCOL_VERSION
        self.cardtypes = N_SIDED_CARD_TYPE
        self.extra = ''
        self.stopped = False

    def set_user(self, login, passwd):
        """Sets user login and password."""

        self.login, self.passwd = login, passwd

    def start(self):
        """Start syncing."""
       
        try:
            self.ui_controller.update_status("Authorization. Please, wait...")
            self.login_()

            self.ui_controller.update_status("Handshaking. Please, wait...")
            self.handshake()

            self.ui_controller.update_status("Creating backup. Please, wait...")
            backup_file = self.eman.make_backup()

            server_media_count = self.get_server_media_count()
            if server_media_count:
                self.ui_controller.update_status(\
                    "Applying server media. Please, wait...")
                self.eman.apply_media(self.get_media_history(), \
                    server_media_count)

            client_media_count = self.eman.get_media_count()
            if client_media_count:
                self.ui_controller.update_status(\
                    "Sending client media to the server. Please, wait...")
                self.send_client_media(self.eman.get_media_history(), \
                    client_media_count)

            server_history_length = self.get_server_history_length()
            if server_history_length:
                self.ui_controller.update_status(\
                    "Applying server history. Please, wait...")
                self.get_server_history(server_history_length)

            # save current database and open backuped database
            # to get history for server
            self.eman.replace_database(backup_file)
            
            client_history_length = self.eman.get_history_length()
            if client_history_length:
                self.ui_controller.update_status(\
                    "Sending client history to the server. Please, wait...")
                self.send_client_history(self.eman.get_history(), \
                    client_history_length)

            # close temp database and return worked database
            self.eman.return_databases()

            self.ui_controller.update_status(\
                "Waiting for the server complete. Please, wait...")
    
            self.send_finish_request()

            if self.stopped:
                raise SyncError("Aborted!")
        except SyncError, exception:
            self.eman.restore_backup()
            self.ui_controller.show_message("Error: " + str(exception))
        else: