from IXMLRPCClient import IXMLRPCClient
import xmlrpclib, socket, exceptions

class XMLRPCClientError(Exception):
    """ XMLRPCClient Error class """


class XMLRPCClient(object):
    """
      XML-RPC Client

      Usage: XMLRPCClient(address, port, user, password, uri)
    """

    __implements__ = IXMLRPCClient

    def __init__(self, address, port=8765, user=None, password=None, uri=None):
        self.address = address
        self.port = port
        self.user = user
        self.password = password
        self.uri = uri
        self._creds()
        self.serverPath = 'http://%s%s:%d/%s'%(self.creds, self.address, int(self.port), self.uri)

    def _connect(self):
        return xmlrpclib.ServerProxy(self.serverPath)

    def _creds(self):
        c = ''
        if self.user:
            c += '%s' % self.user
            if self.password:
                c += ':%s' % self.password
        if c != '':
            c+='@'
        self.creds = c

    def update(self, address, port=8765, user=None, password=None, uri=None):
        self.address = address
        self.port = port
        self.user = user
        self.password = password
        self.uri = uri
        self._creds()
        self.serverPath = 'http://%s%s:%d/%s'%(self.creds, self.address, int(self.port), self.uri)

    def browse(self):
        try:
            server = self._connect()
            methods = server.system.listMethods()
            d = {}
            for i in range(len(methods)):
                s = methods[i]
                if s.find('system') == -1:
                    d[methods[i]] = server.system.methodHelp(methods[i])
                else:
                    continue
            return d
        except socket.error, e:
            raise XMLRPCClientError, "%s: %s" % (self.serverPath, e[1])
        except:
            return None

    def callMethod(self, method, *args):
        try:
            server = self._connect()
            m = getattr(server, method)
            return m(*args)
        except xmlrpclib.ProtocolError:
            raise
        except socket.error, e:
            raise XMLRPCClientError, "%s: %s" % (self.serverPath, e[1])
        except exceptions.Exception, e:
            raise XMLRPCClientError, "%s: %s" % (self.serverPath, e)
