Home | History | Annotate | Download | only in pdist
      1 #! /usr/bin/env python

      2 
      3 """RCS Proxy.
      4 
      5 Provide a simplified interface on RCS files, locally or remotely.
      6 The functionality is geared towards implementing some sort of
      7 remote CVS like utility.  It is modeled after the similar module
      8 FSProxy.
      9 
     10 The module defines two classes:
     11 
     12 RCSProxyLocal  -- used for local access
     13 RCSProxyServer -- used on the server side of remote access
     14 
     15 The corresponding client class, RCSProxyClient, is defined in module
     16 rcsclient.
     17 
     18 The remote classes are instantiated with an IP address and an optional
     19 verbosity flag.
     20 """
     21 
     22 import server
     23 import md5
     24 import os
     25 import fnmatch
     26 import string
     27 import tempfile
     28 import rcslib
     29 
     30 
     31 class DirSupport:
     32 
     33     def __init__(self):
     34         self._dirstack = []
     35 
     36     def __del__(self):
     37         self._close()
     38 
     39     def _close(self):
     40         while self._dirstack:
     41             self.back()
     42 
     43     def pwd(self):
     44         return os.getcwd()
     45 
     46     def cd(self, name):
     47         save = os.getcwd()
     48         os.chdir(name)
     49         self._dirstack.append(save)
     50 
     51     def back(self):
     52         if not self._dirstack:
     53             raise os.error, "empty directory stack"
     54         dir = self._dirstack[-1]
     55         os.chdir(dir)
     56         del self._dirstack[-1]
     57 
     58     def listsubdirs(self, pat = None):
     59         files = os.listdir(os.curdir)
     60         files = filter(os.path.isdir, files)
     61         return self._filter(files, pat)
     62 
     63     def isdir(self, name):
     64         return os.path.isdir(name)
     65 
     66     def mkdir(self, name):
     67         os.mkdir(name, 0777)
     68 
     69     def rmdir(self, name):
     70         os.rmdir(name)
     71 
     72 
     73 class RCSProxyLocal(rcslib.RCS, DirSupport):
     74 
     75     def __init__(self):
     76         rcslib.RCS.__init__(self)
     77         DirSupport.__init__(self)
     78 
     79     def __del__(self):
     80         DirSupport.__del__(self)
     81         rcslib.RCS.__del__(self)
     82 
     83     def sumlist(self, list = None):
     84         return self._list(self.sum, list)
     85 
     86     def sumdict(self, list = None):
     87         return self._dict(self.sum, list)
     88 
     89     def sum(self, name_rev):
     90         f = self._open(name_rev)
     91         BUFFERSIZE = 1024*8
     92         sum = md5.new()
     93         while 1:
     94             buffer = f.read(BUFFERSIZE)
     95             if not buffer:
     96                 break
     97             sum.update(buffer)
     98         self._closepipe(f)
     99         return sum.digest()
    100 
    101     def get(self, name_rev):
    102         f = self._open(name_rev)
    103         data = f.read()
    104         self._closepipe(f)
    105         return data
    106 
    107     def put(self, name_rev, data, message=None):
    108         name, rev = self._unmangle(name_rev)
    109         f = open(name, 'w')
    110         f.write(data)
    111         f.close()
    112         self.checkin(name_rev, message)
    113         self._remove(name)
    114 
    115     def _list(self, function, list = None):
    116         """INTERNAL: apply FUNCTION to all files in LIST.
    117 
    118         Return a list of the results.
    119 
    120         The list defaults to all files in the directory if None.
    121 
    122         """
    123         if list is None:
    124             list = self.listfiles()
    125         res = []
    126         for name in list:
    127             try:
    128                 res.append((name, function(name)))
    129             except (os.error, IOError):
    130                 res.append((name, None))
    131         return res
    132 
    133     def _dict(self, function, list = None):
    134         """INTERNAL: apply FUNCTION to all files in LIST.
    135 
    136         Return a dictionary mapping files to results.
    137 
    138         The list defaults to all files in the directory if None.
    139 
    140         """
    141         if list is None:
    142             list = self.listfiles()
    143         dict = {}
    144         for name in list:
    145             try:
    146                 dict[name] = function(name)
    147             except (os.error, IOError):
    148                 pass
    149         return dict
    150 
    151 
    152 class RCSProxyServer(RCSProxyLocal, server.SecureServer):
    153 
    154     def __init__(self, address, verbose = server.VERBOSE):
    155         RCSProxyLocal.__init__(self)
    156         server.SecureServer.__init__(self, address, verbose)
    157 
    158     def _close(self):
    159         server.SecureServer._close(self)
    160         RCSProxyLocal._close(self)
    161 
    162     def _serve(self):
    163         server.SecureServer._serve(self)
    164         # Retreat into start directory

    165         while self._dirstack: self.back()
    166 
    167 
    168 def test_server():
    169     import string
    170     import sys
    171     if sys.argv[1:]:
    172         port = string.atoi(sys.argv[1])
    173     else:
    174         port = 4127
    175     proxy = RCSProxyServer(('', port))
    176     proxy._serverloop()
    177 
    178 
    179 def test():
    180     import sys
    181     if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789':
    182         test_server()
    183         sys.exit(0)
    184     proxy = RCSProxyLocal()
    185     what = sys.argv[1]
    186     if hasattr(proxy, what):
    187         attr = getattr(proxy, what)
    188         if callable(attr):
    189             print apply(attr, tuple(sys.argv[2:]))
    190         else:
    191             print repr(attr)
    192     else:
    193         print "%s: no such attribute" % what
    194         sys.exit(2)
    195 
    196 
    197 if __name__ == '__main__':
    198     test()
    199