3 Provide an OS-neutral view on a file system, locally or remotely.
4 The functionality is geared towards implementing some sort of
5 rdist-like utility between a Mac and a UNIX system.
7 The module defines three classes:
9 FSProxyLocal -- used for local access
10 FSProxyServer -- used on the server side of remote access
11 FSProxyClient -- used on the client side of remote access
13 The remote classes are instantiated with an IP address and an optional
28 skipnames
= (os
.curdir
, os
.pardir
)
35 self
._ignore
= ['*.pyc'] + self
._readignore
()
41 def _readignore(self
):
42 file = self
._hide
('ignore')
46 file = self
._hide
('synctree.ignorefiles')
55 if line
[-1] == '\n': line
= line
[:-1]
60 def _hidden(self
, name
):
63 def _hide(self
, name
):
66 def visible(self
, name
):
67 if len(name
) > maxnamelen
: return 0
68 if name
[-1] == '~': return 0
69 if name
in skipnames
: return 0
70 if self
._hidden
(name
): return 0
71 head
, tail
= os
.path
.split(name
)
72 if head
or not tail
: return 0
73 if os
.path
.islink(name
): return 0
74 if '\0' in open(name
, 'rb').read(512): return 0
75 for ign
in self
._ignore
:
76 if fnmatch
.fnmatch(name
, ign
): return 0
79 def check(self
, name
):
80 if not self
.visible(name
):
81 raise os
.error
, "protected name %s" % repr(name
)
83 def checkfile(self
, name
):
85 if not os
.path
.isfile(name
):
86 raise os
.error
, "not a plain file %s" % repr(name
)
93 save
= os
.getcwd(), self
._ignore
95 self
._dirstack
.append(save
)
96 self
._ignore
= self
._ignore
+ self
._readignore
()
99 if not self
._dirstack
:
100 raise os
.error
, "empty directory stack"
101 dir, ignore
= self
._dirstack
[-1]
103 del self
._dirstack
[-1]
104 self
._ignore
= ignore
106 def _filter(self
, files
, pat
= None):
108 def keep(name
, pat
= pat
):
109 return fnmatch
.fnmatch(name
, pat
)
110 files
= filter(keep
, files
)
111 files
= filter(self
.visible
, files
)
115 def list(self
, pat
= None):
116 files
= os
.listdir(os
.curdir
)
117 return self
._filter
(files
, pat
)
119 def listfiles(self
, pat
= None):
120 files
= os
.listdir(os
.curdir
)
121 files
= filter(os
.path
.isfile
, files
)
122 return self
._filter
(files
, pat
)
124 def listsubdirs(self
, pat
= None):
125 files
= os
.listdir(os
.curdir
)
126 files
= filter(os
.path
.isdir
, files
)
127 return self
._filter
(files
, pat
)
129 def exists(self
, name
):
130 return self
.visible(name
) and os
.path
.exists(name
)
132 def isdir(self
, name
):
133 return self
.visible(name
) and os
.path
.isdir(name
)
135 def islink(self
, name
):
136 return self
.visible(name
) and os
.path
.islink(name
)
138 def isfile(self
, name
):
139 return self
.visible(name
) and os
.path
.isfile(name
)
147 buffer = f
.read(BUFFERSIZE
)
153 def size(self
, name
):
155 return os
.stat(name
)[ST_SIZE
]
157 def mtime(self
, name
):
159 return time
.localtime(os
.stat(name
)[ST_MTIME
])
161 def stat(self
, name
):
163 size
= os
.stat(name
)[ST_SIZE
]
164 mtime
= time
.localtime(os
.stat(name
)[ST_MTIME
])
167 def info(self
, name
):
169 size
= os
.stat(name
)[ST_SIZE
]
170 mtime
= time
.localtime(os
.stat(name
)[ST_MTIME
])
171 return sum, size
, mtime
173 def _list(self
, function
, list):
175 list = self
.listfiles()
179 res
.append((name
, function(name
)))
180 except (os
.error
, IOError):
181 res
.append((name
, None))
184 def sumlist(self
, list = None):
185 return self
._list
(self
.sum, list)
187 def statlist(self
, list = None):
188 return self
._list
(self
.stat
, list)
190 def mtimelist(self
, list = None):
191 return self
._list
(self
.mtime
, list)
193 def sizelist(self
, list = None):
194 return self
._list
(self
.size
, list)
196 def infolist(self
, list = None):
197 return self
._list
(self
.info
, list)
199 def _dict(self
, function
, list):
201 list = self
.listfiles()
205 dict[name
] = function(name
)
206 except (os
.error
, IOError):
210 def sumdict(self
, list = None):
211 return self
.dict(self
.sum, list)
213 def sizedict(self
, list = None):
214 return self
.dict(self
.size
, list)
216 def mtimedict(self
, list = None):
217 return self
.dict(self
.mtime
, list)
219 def statdict(self
, list = None):
220 return self
.dict(self
.stat
, list)
222 def infodict(self
, list = None):
223 return self
._dict
(self
.info
, list)
225 def read(self
, name
, offset
= 0, length
= -1):
234 data
= f
.read(length
)
238 def create(self
, name
):
240 if os
.path
.exists(name
):
247 os
.rename(name
, bname
)
251 def write(self
, name
, data
, offset
= 0):
258 def mkdir(self
, name
):
262 def rmdir(self
, name
):
267 class FSProxyServer(FSProxyLocal
, server
.Server
):
269 def __init__(self
, address
, verbose
= server
.VERBOSE
):
270 FSProxyLocal
.__init
__(self
)
271 server
.Server
.__init
__(self
, address
, verbose
)
274 server
.Server
._close
(self
)
275 FSProxyLocal
._close
(self
)
278 server
.Server
._serve
(self
)
279 # Retreat into start directory
280 while self
._dirstack
: self
.back()
283 class FSProxyClient(client
.Client
):
285 def __init__(self
, address
, verbose
= client
.VERBOSE
):
286 client
.Client
.__init
__(self
, address
, verbose
)
293 port
= string
.atoi(sys
.argv
[1])
296 proxy
= FSProxyServer(('', port
))
300 if __name__
== '__main__':