remote_client.py :  » Database » PyDO » skunkweb-3.4.4 » SkunkWeb » Services » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Database » PyDO 
PyDO » skunkweb 3.4.4 » SkunkWeb » Services » remote_client.py
#  
#  Copyright (C) 2001 Jacob Smullyan <smulloni@smullyan.org>
#  
#      You may distribute under the terms of either the GNU General
#      Public License or the SkunkWeb License, as specified in the
#      README file.
#   
# Time-stamp: <01/05/09 14:36:02 smulloni>
########################################################################

import AE.Component
import exceptions
import new
import socket
import SocketScience
import cPickle
import types
from SkunkWeb.LogObj import DEBUG,logException
from SkunkWeb import ServiceRegistry

ServiceRegistry.registerService('remote_client')
REMOTE_CLIENT=ServiceRegistry.REMOTE_CLIENT

SWRC_PROTOCOL="swrc"
DEFAULT_PORT=9887

class RemoteException(Exception):
    """
    a class that wraps a remotely raised exception
    """
    def __init__(self, remoteInstance):
        if isinstance(remoteInstance, Exception):
            Exception.__init__(self, remoteInstance.args)
        else:
            Exception.__init__(self, remoteInstance)
        self.remoteInstance=remoteInstance


def getRemoteExceptionClass(exceptionClass):
    gl=globals()
    classname='Remote%s' % exceptionClass.__name__
    if gl.has_key(classname):
        return gl[classname]
    
    newclass=new.classobj(classname,
                          (RemoteException, exceptionClass),
                          RemoteException.__dict__)
    gl[classname]=newclass
    return newclass

def getRemoteException(realException):
    """
    dynamically creates a RemoteException mixin
    with the realException's class, and keeps
    a copy of the realException in the 'remoteInstance'
    field
    """
    if isinstance(realException, Exception):
        newclass=getRemoteExceptionClass(realException.__class__)
        return newclass(realException)
    else:
        return RemoteException(realException)
    
class SkunkWebRemoteComponentHandler(AE.Component.ComponentHandler):

    def callComponent(self,
                      callProtocol,
                      name,
                      argDict,
                      cache,
                      compType,
                      srcModTime):
        """
        client-side handler for remote component calls
        """
        # we don't need the callProtocol argument in this case
        unPickled=None
        host, port, path=self.__parseComponentName(name)
        args = cPickle.dumps((path, argDict, cache,
                              compType, srcModTime))
        msg="%10d%s" %(len(args), args) 
        sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.connect((host, port))
        data=sock.recv(1)
        if data=='\0':
            SocketScience.send_it_all(sock, msg)
            length=int(SocketScience.read_this_many(sock, 10))
            data=SocketScience.read_this_many(sock, length)
            unPickled=cPickle.loads(data)
            DEBUG(REMOTE_CLIENT, 'unp was %s' % str(unPickled))
            if unPickled[0] == 0: #ok
                return unPickled[1]
            else:
                raise getRemoteException(unPickled[2])
        raise RemoteException, ("remote host did not speak "
                                "protocol: %s:%s") % (host, port)

    def __parseComponentName(self, name):
        """
        I expect a name of the following sort: host[:port]absolutePath,
        where absolutePath begins with a slash, and contains no colons,
        and port is an integer, and host contains neither a colon nor a slash.
        """
        DEBUG(REMOTE_CLIENT, "in __parseComponentName with name %s" % name)
        try:
            slashIndex=name.find('/')
            assert(slashIndex>0)
            path=name[1+slashIndex:]
            DEBUG(REMOTE_CLIENT, "path is %s" % path)
            colonIndex=name.find(':')
            assert(colonIndex<slashIndex)
            if colonIndex>-1:
                assert(colonIndex>0)
                host=name[:colonIndex]
                DEBUG(REMOTE_CLIENT, "host is %s" % host)
                port=int(name[1+colonIndex:slashIndex])
            else:
                host=name[:slashIndex]
                port=DEFAULT_PORT
        except:
            logException()
            raise ValueError, "component name could not be parsed"
        return host, port, path

################################ MAIN ##################################

AE.Component.componentHandlers[SWRC_PROTOCOL]=SkunkWebRemoteComponentHandler()

########################################################################
# $Log: remote_client.py,v $
# Revision 1.5  2003/05/01 20:45:53  drew_csillag
# Changed license text
#
# Revision 1.4  2002/02/03 05:31:33  smulloni
# fix to remote_client handling of string exceptions.
#
# Revision 1.3  2001/10/30 15:44:36  drew_csillag
# now deals properly with new protocol
#
# Revision 1.2  2001/10/30 15:02:17  drew_csillag
# fixed bug so remote components work again
#
# Revision 1.1.1.1  2001/08/05 14:59:55  drew_csillag
# take 2 of import
#
#
# Revision 1.7  2001/07/30 16:44:45  smulloni
# fixed remote services to work with changed API of AE.Component.
#
# Revision 1.6  2001/07/09 20:38:40  drew
# added licence comments
#
# Revision 1.5  2001/05/09 18:37:02  smullyan
# changes to RemoteException -- now it is an empty class, and getRemoteException
# dynamically creates a mixin appropriate for the given exception
#
# Revision 1.4  2001/05/04 18:38:47  smullyan
# architectural overhaul, possibly a reductio ad absurdum of the current
# config overlay technique.
#
# Revision 1.3  2001/04/16 17:52:58  smullyan
# some long lines split; bug in Server.py fixed (reference to deleted
# Configuration module on reload); logging of multiline messages can now
# configurably have or not have a log stamp on every line.
#
# Revision 1.2  2001/04/13 04:21:23  smullyan
# removed "file://" protocol for component calls, which made no sense.
#
# Revision 1.1  2001/04/12 22:06:36  smullyan
# adding remote_client service, which adds remote call capability to STML
# component tags.
#
########################################################################
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.