this one looks like a duplicate. there is already one in monitor/Rpyc
[monitor.git] / Rpyc / Utils.py
diff --git a/Rpyc/Utils.py b/Rpyc/Utils.py
deleted file mode 100644 (file)
index 00963c2..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-"""\r
-convenience utilities:\r
- * provides dir(), getattr(), hasattr(), help() and reload() that support netproxies\r
- * provides obtain() for really transfering remote objects\r
- * provides upload() and download() for working with files\r
- * provides a nice interface for remote shell operations (like os.system)\r
-   and a openning a remote python interpreter (for debugging, etc.)\r
-\r
-i removed lots of stuff from the __all__, keeping only the useful things, \r
-so that import * wouldnt mess your namespace too much\r
-"""\r
-import __builtin__\r
-import sys\r
-import os\r
-import inspect\r
-from NetProxy import NetProxy\r
-\r
-__all__ = [\r
-    "dir", "getattr", "hasattr", "help", "reload", "obtain",\r
-    "upload", "download",\r
-]\r
-\r
-CHUNK_SIZE = 4096\r
-\r
-class UtilityError(Exception): \r
-    pass\r
-\r
-#\r
-# working with netproxies\r
-#\r
-def dir(*obj):\r
-    """a version of dir() that supports NetProxies"""\r
-    if not obj:\r
-        inspect_stack = [inspect.stack()[1][0].f_locals.keys()]\r
-        inspect_stack.sort()\r
-        return inspect_stack\r
-    if not len(obj) == 1:\r
-        raise TypeError("dir expected at most 1 arguments, got %d" % (len(obj),))\r
-    obj = obj[0]\r
-    if isinstance(obj, NetProxy):\r
-        return obj.__dict__["____conn"].modules["__builtin__"].dir(obj)\r
-    else:\r
-        return __builtin__.dir(obj)\r
-\r
-def getattr(obj, name, *default):\r
-    """a version of getattr() that supports NetProxies"""\r
-    if len(default) > 1:\r
-        raise TypeError("getattr expected at most 3 arguments, got %d" % (2 + len(default),))\r
-    if isinstance(obj, NetProxy):\r
-        try:\r
-            return obj.__getattr__(name)\r
-        except AttributeError:\r
-            if not default:\r
-                raise\r
-            return default[0]\r
-    else:\r
-        return __builtin__.getattr(obj, name, *default)\r
-\r
-def hasattr(obj, name):\r
-    """a version of hasattr() that supports NetProxies"""\r
-    try:\r
-        getattr(obj, name)\r
-    except AttributeError:\r
-        return False\r
-    else:\r
-        return True\r
-\r
-class _Helper(object):\r
-    """a version of help() that supports NetProxies"""\r
-    def __repr__(self):\r
-        return repr(__builtin__.help)\r
-    def __call__(self, obj = None):\r
-        if isinstance(obj, NetProxy):\r
-            print "Help on NetProxy object for an instance of %r:" % (obj.__getattr__("__class__").__name__,)\r
-            print\r
-            print "Doc:"\r
-            print obj.__doc__\r
-            print\r
-            print "Members:"\r
-            print dir(obj)\r
-        else:\r
-            __builtin__.help(obj)\r
-help = _Helper()\r
-\r
-def reload(module):\r
-    """a version of reload() that supports NetProxies"""\r
-    if isinstance(module, NetProxy):\r
-        return module.__dict__["____conn"].modules["__builtin__"].reload(module)\r
-    else:\r
-        return __builtin__.reload(module)\r
-\r
-def obtain(proxy):\r
-    """transfers a remote object to this process. this is done by pickling it, so it\r
-    must be a picklable object, and should be immutable (otherwise the local object\r
-    may be different from the remote one, which may cause problems). generally speaking, \r
-    you should not obtain remote objects, as NetProxies provide a stronger mechanism.\r
-    but there are times when you want to get the real object in your hand, for pickling\r
-    it locally (e.g., storing test results in a file), or if the connection is too slow."""\r
-    import cPickle\r
-    dumped = proxy.__dict__["____conn"].modules.cPickle.dumps(proxy)\r
-    return cPickle.loads(dumped)\r
-\r
-def getconn(obj):\r
-    """returns the connection of a NetProxy"""\r
-    if "____conn" not in obj.__dict__:\r
-        raise TypeError("`obj` is not a NetProxy")\r
-    return proxy.__dict__["____conn"]\r
-\r
-#\r
-# working with files\r
-#\r
-def upload(conn, localpath, remotepath, *a, **k):\r
-    """uploads a file or a directory recursively (depending on what `localpath` is)"""\r
-    if os.path.isdir(localpath):\r
-        upload_dir(conn, localpath, remotepath, *a, **k)\r
-    elif os.path.isfile(localpath):\r
-        upload_file(conn, localpath, remotepath, *a, **k)\r
-    else:\r
-        raise UtilityError("can only upload files or directories")\r
-\r
-def download(conn, remotepath, localpath, *a, **k):\r
-    """downloads a file or a directory recursively (depending on what `remotepath` is)"""\r
-    if conn.modules.os.path.isdir(remotepath):\r
-        download_dir(conn, remotepath, localpath, *a, **k)\r
-    elif conn.modules.os.path.isfile(remotepath):\r
-        download_file(conn, remotepath, localpath, *a, **k)\r
-    else:\r
-        raise UtilityError("can only download files or directories")\r
-\r
-def upload_file(conn, localpath, remotepath):\r
-    lf = open(localpath, "rb")\r
-    rf = conn.modules.__builtin__.open(remotepath, "wb")\r
-    while True:\r
-        chunk = lf.read(CHUNK_SIZE)\r
-        if not chunk:\r
-            break\r
-        rf.write(chunk)\r
-    lf.close()\r
-    rf.close()\r
-\r
-def download_file(conn, remotepath, localpath):\r
-    lf = open(localpath, "wb")\r
-    rf = conn.modules.__builtin__.open(remotepath, "rb")\r
-    while True:\r
-        chunk = rf.read(CHUNK_SIZE)\r
-        if not chunk:\r
-            break\r
-        lf.write(chunk)\r
-    lf.close()\r
-    rf.close()\r
-    \r
-def upload_dir(conn, localpath, remotepath, extensions = [""]):\r
-    if not conn.modules.os.path.exists(remotepath):\r
-        conn.modules.os.makedirs(remotepath)\r
-    for fn in os.listdir(localpath):\r
-        lfn = os.path.join(localpath, fn)\r
-        rfn = conn.modules.os.path.join(remotepath, fn)\r
-        if os.path.isdir(lfn):\r
-            upload_dir(conn, lfn, rfn, extensions)\r
-        elif os.path.isfile(lfn):\r
-            for ext in extensions:\r
-                if fn.endswith(ext):\r
-                    upload_file(conn, lfn, rfn)\r
-                    break\r
-\r
-def download_dir(conn, remotepath, localpath, extensions = [""]):\r
-    if not os.path.exists(localpath):\r
-        os.makedirs(localpath)\r
-    for fn in conn.modules.os.listdir(remotepath):\r
-        lfn = os.path.join(localpath, fn)\r
-        rfn = conn.modules.os.path.join(remotepath, fn)\r
-        if conn.modules.os.path.isdir(lfn):\r
-            download_dir(conn, rfn, lfn, extensions)\r
-        elif conn.modules.os.path.isfile(lfn):\r
-            for ext in extensions:\r
-                if fn.endswith(ext):\r
-                    download_file(conn, rfn, lfn)\r
-                    break\r
-\r
-#\r
-# distributing modules between hosts\r
-#\r
-def upload_package(conn, module, remotepath = None):\r
-    """uploads the given package to the server, storing it in `remotepath`. if \r
-    remotepath is None, it defaults to the server's site-packages. if the package\r
-    already exists, it is overwritten.\r
-    usage:\r
-        import xml\r
-        upload_package(conn, xml)"""\r
-    if remotepath is None:\r
-        remotepath = conn.modules["distutils.sysconfig"].get_python_lib()\r
-    localpath = os.path.dirname(module.__file__)\r
-    upload_dir(conn, localpath, remotepath, [".py", ".pyd", ".dll", ".so", ".zip"])\r
-\r
-def update_module(conn, module):\r
-    """updates an existing module on the server. the local module is transfered to the\r
-    server, overwriting the old one, and is reloaded. \r
-    usage:\r
-        import xml.dom.minidom\r
-        upload_module(conn, xml.dom.minidom)"""\r
-    remote_module = conn.modules[module.__name__]\r
-    local_file = inspect.getsourcefile(module)\r
-    remote_file = inspect.getsourcefile(remote_module)\r
-    upload_file(conn, local_filem, remote_file)\r
-    reload(remote_module)\r
-\r
-#\r
-# remote shell and interpreter\r
-#\r
-def _redirect_std(conn):\r
-    rsys = conn.modules.sys\r
-    orig = (rsys.stdin, rsys.stdout, rsys.stderr)\r
-    rsys.stdin = sys.stdin\r
-    rsys.stdout = sys.stdout\r
-    rsys.stderr = sys.stderr\r
-    return orig\r
-\r
-def _restore_std(conn, (stdin, stdout, stderr)):\r
-    rsys = conn.modules.sys\r
-    rsys.stdin = stdin\r
-    rsys.stdout = stdout\r
-    rsys.stderr = stderr\r
-    \r
-def remote_shell(conn, command = None):\r
-    """runs the given command on the server, just like os.system, but takes care\r
-    of redirecting the server's stdout/stdin to the client"""\r
-    # BUG: on windows, there's a problem with redirecting the output of spawned command.\r
-    # it runs fine and all, just the client can't see the output. again, windows sucks.\r
-    if command is None:\r
-        if sys.platform == "win32":\r
-            command = "%COMSPEC%"\r
-        else:\r
-            command = "/bin/sh"\r
-    try:\r
-        orig = _redirect_std(conn)\r
-        return conn.modules.os.system(command)\r
-    finally:\r
-        _restore_std(conn, orig)\r
-    \r
-def remote_interpreter(conn, namespace = None):\r
-    """starts an interactive interpreter on the server"""\r
-    if namespace is None:\r
-        #namespace = inspect.stack()[1][0].f_globals.copy()\r
-        #namespace.update(inspect.stack()[1][0].f_locals)\r
-        namespace = {"conn" : conn}\r
-    try:\r
-        orig = _redirect_std(conn)\r
-        return conn.modules["Rpyc.Utils"]._remote_interpreter_server_side(**namespace)\r
-    finally:\r
-        _restore_std(conn, orig)\r
-\r
-def _remote_interpreter_server_side(**namespace):\r
-    import code\r
-    namespace.update(globals())\r
-    code.interact(local = namespace)\r
-\r
-def remote_post_mortem(conn):\r
-    """a version of pdb.pm() that operates on exceptions at the remote side of the connection"""\r
-    import pdb\r
-    pdb.post_mortem(c.modules.sys.last_traceback)\r
-\r
-\r
-\r
-\r
-\r