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
, 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
= filter(keep
, files
)
132 files
= 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
= 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
= 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
):
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__':