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
33
skipnames = (os.curdir, os.pardir)
40
self._ignore = ['*.pyc'] + self._readignore()
46
def _readignore(self):
47
file = self._hide('ignore')
51
file = self._hide('synctree.ignorefiles')
60
if line[-1] == '\n': line = line[:-1]
65
def _hidden(self, name):
67
return name[0] == '(' and name[-1] == ')'
71
def _hide(self, name):
77
def visible(self, name):
78
if len(name) > maxnamelen: return 0
79
if name[-1] == '~': return 0
80
if name in skipnames: return 0
81
if self._hidden(name): return 0
82
head, tail = os.path.split(name)
83
if head or not tail: return 0
85
if os.path.exists(name) and not os.path.isdir(name):
87
fs = macfs.FSSpec(name)
88
c, t = fs.GetCreatorType()
89
if t != 'TEXT': return 0
90
except macfs.error as msg:
91
print("***", name, msg)
94
if os.path.islink(name): return 0
95
if '\0' in open(name, 'rb').read(512): return 0
96
for ign in self._ignore:
97
if fnmatch.fnmatch(name, ign): return 0
100
def check(self, name):
101
if not self.visible(name):
102
raise os.error("protected name %s" % repr(name))
104
def checkfile(self, name):
106
if not os.path.isfile(name):
107
raise os.error("not a plain file %s" % repr(name))
114
save = os.getcwd(), self._ignore
116
self._dirstack.append(save)
117
self._ignore = self._ignore + self._readignore()
120
if not self._dirstack:
121
raise os.error("empty directory stack")
122
dir, ignore = self._dirstack[-1]
124
del self._dirstack[-1]
125
self._ignore = ignore
127
def _filter(self, files, pat = None):
129
def keep(name, pat = pat):
130
return fnmatch.fnmatch(name, pat)
131
files = list(filter(keep, files))
132
files = list(filter(self.visible, files))
136
def list(self, pat = None):
137
files = os.listdir(os.curdir)
138
return self._filter(files, pat)
140
def listfiles(self, pat = None):
141
files = os.listdir(os.curdir)
142
files = list(filter(os.path.isfile, files))
143
return self._filter(files, pat)
145
def listsubdirs(self, pat = None):
146
files = os.listdir(os.curdir)
147
files = list(filter(os.path.isdir, files))
148
return self._filter(files, pat)
150
def exists(self, name):
151
return self.visible(name) and os.path.exists(name)
153
def isdir(self, name):
154
return self.visible(name) and os.path.isdir(name)
156
def islink(self, name):
157
return self.visible(name) and os.path.islink(name)
159
def isfile(self, name):
160
return self.visible(name) and os.path.isfile(name)
168
buffer = f.read(BUFFERSIZE)
174
def size(self, name):
176
return os.stat(name)[ST_SIZE]
178
def mtime(self, name):
180
return time.localtime(os.stat(name)[ST_MTIME])
182
def stat(self, name):
184
size = os.stat(name)[ST_SIZE]
185
mtime = time.localtime(os.stat(name)[ST_MTIME])
188
def info(self, name):
190
size = os.stat(name)[ST_SIZE]
191
mtime = time.localtime(os.stat(name)[ST_MTIME])
192
return sum, size, mtime
194
def _list(self, function, list):
196
list = self.listfiles()
200
res.append((name, function(name)))
201
except (os.error, IOError):
202
res.append((name, None))
205
def sumlist(self, list = None):
206
return self._list(self.sum, list)
208
def statlist(self, list = None):
209
return self._list(self.stat, list)
211
def mtimelist(self, list = None):
212
return self._list(self.mtime, list)
214
def sizelist(self, list = None):
215
return self._list(self.size, list)
217
def infolist(self, list = None):
218
return self._list(self.info, list)
220
def _dict(self, function, list):
222
list = self.listfiles()
226
dict[name] = function(name)
227
except (os.error, IOError):
231
def sumdict(self, list = None):
232
return self.dict(self.sum, list)
234
def sizedict(self, list = None):
235
return self.dict(self.size, list)
237
def mtimedict(self, list = None):
238
return self.dict(self.mtime, list)
240
def statdict(self, list = None):
241
return self.dict(self.stat, list)
243
def infodict(self, list = None):
244
return self._dict(self.info, list)
246
def read(self, name, offset = 0, length = -1):
255
data = f.read(length)
259
def create(self, name):
261
if os.path.exists(name):
268
os.rename(name, bname)
272
def write(self, name, data, offset = 0):
279
def mkdir(self, name):
281
os.mkdir(name, 0o777)
283
def rmdir(self, name):
288
class FSProxyServer(FSProxyLocal, server.Server):
290
def __init__(self, address, verbose = server.VERBOSE):
291
FSProxyLocal.__init__(self)
292
server.Server.__init__(self, address, verbose)
295
server.Server._close(self)
296
FSProxyLocal._close(self)
299
server.Server._serve(self)
300
# Retreat into start directory
301
while self._dirstack: self.back()
304
class FSProxyClient(client.Client):
306
def __init__(self, address, verbose = client.VERBOSE):
307
client.Client.__init__(self, address, verbose)
314
port = string.atoi(sys.argv[1])
317
proxy = FSProxyServer(('', port))
321
if __name__ == '__main__':