1- from contextlib import closing
1+ # coding: utf-8
2+
23import io
34import os
45import six
@@ -35,21 +36,24 @@ def __init__(self, wdfs, path, mode):
3536 self .path = path
3637 self .res = self .fs .get_resource (self .path )
3738 self .mode = mode
38- self ._mode = Mode (mode )
3939 self ._lock = threading .RLock ()
4040 self .data = self ._get_file_data ()
4141
4242 self .pos = 0
4343
44- if 'a' in mode :
45- self .pos = self ._get_data_size ()
44+ if self .mode .appending :
45+ self .pos = self .__length_hint__ ()
46+ if self .mode .writing :
47+ self .write (b'' )
48+ if self .mode .reading :
49+ self .read (0 )
4650
4751 def _get_file_data (self ):
4852 with self ._lock :
4953 data = io .BytesIO ()
5054 try :
5155 self .res .write_to (data )
52- if 'a' not in self .mode :
56+ if not self .mode . appending :
5357 data .seek (io .SEEK_SET )
5458 except we .RemoteResourceNotFound :
5559 data .write (b'' )
@@ -65,7 +69,7 @@ def __length_hint__(self):
6569
6670 def __repr__ (self ):
6771 _repr = "WebDAVFile({!r}, {!r}, {!r})"
68- return _repr .format (self .fs , self .path , self .mode )
72+ return _repr .format (self .fs , self .path , self .mode . to_platform_bin () )
6973
7074 def close (self ):
7175 if not self .closed :
@@ -75,7 +79,7 @@ def close(self):
7579 self .data .close ()
7680
7781 def flush (self ):
78- if self ._mode .writing :
82+ if self .mode .writing :
7983 log .debug ("flush" )
8084 self .data .seek (io .SEEK_SET )
8185 self .res .read_from (self .data )
@@ -84,10 +88,10 @@ def readline(self, size=-1):
8488 return next (line_iterator (self , None if size == - 1 else size ))
8589
8690 def readable (self ):
87- return self ._mode .reading
91+ return self .mode .reading
8892
8993 def read (self , size = - 1 ):
90- if not self ._mode .reading :
94+ if not self .mode .reading :
9195 raise IOError ("File is not in read mode" )
9296 self .pos = self .pos + size if size != - 1 else self .__length_hint__ ()
9397 return self .data .read (size )
@@ -123,10 +127,10 @@ def truncate(self, size=None):
123127 return size or data_size
124128
125129 def writable (self ):
126- return self ._mode .writing
130+ return self .mode .writing
127131
128132 def write (self , data ):
129- if not self ._mode .writing :
133+ if not self .mode .writing :
130134 raise IOError ("File is not in write mode" )
131135 bytes_written = self .data .write (data )
132136 self .seek (bytes_written , Seek .current )
@@ -192,44 +196,46 @@ def _create_info_dict(info):
192196
193197 return info_dict
194198
195- def isdir (self , path ):
196- try :
197- return self .client .is_dir (path )
198- except we .RemoteResourceNotFound :
199- return False
199+ def create (self , path , wipe = False ):
200+ with self ._lock :
201+ if not wipe and self .exists (path ):
202+ return False
203+ with self .openbin (path , 'wb' ) as new_file :
204+ new_file .truncate (0 )
205+ return True
200206
201207 def exists (self , path ):
202- return self .client .check (path )
208+ _path = self .validatepath (path )
209+ return self .client .check (_path )
203210
204211 def getinfo (self , path , namespaces = None ):
205212 _path = self .validatepath (path )
206213 namespaces = namespaces or ()
207214
208215 if _path in '/' :
209- return Info ({
210- "basic" :
211- {
216+ info_dict = {
217+ "basic" : {
212218 "name" : "" ,
213219 "is_dir" : True
214220 },
215- "details" :
216- {
217- "type" : int (ResourceType .directory )
221+ "details" : {
222+ "type" : ResourceType .directory
218223 }
219- })
220-
221- try :
222- info = self .client .info (path )
223- info_dict = self ._create_info_dict (info )
224- if self .isdir (path ):
225- info_dict ['basic' ]['is_dir' ] = True
226- info_dict ['details' ]['type' ] = ResourceType .directory
227- return Info (info_dict )
228- except we .RemoteResourceNotFound as exc :
229- raise errors .ResourceNotFound (path , exc = exc )
224+ }
225+
226+ else :
227+ try :
228+ info = self .client .info (_path )
229+ info_dict = self ._create_info_dict (info )
230+ if self .client .is_dir (_path ):
231+ info_dict ['basic' ]['is_dir' ] = True
232+ info_dict ['details' ]['type' ] = ResourceType .directory
233+ except we .RemoteResourceNotFound as exc :
234+ raise errors .ResourceNotFound (path , exc = exc )
235+
236+ return Info (info_dict )
230237
231238 def listdir (self , path ):
232- self .check ()
233239 _path = self .validatepath (path )
234240
235241 if not self .getinfo (_path ).is_dir :
@@ -239,10 +245,9 @@ def listdir(self, path):
239245 return map (six .u , dir_list ) if six .PY2 else dir_list
240246
241247 def makedir (self , path , permissions = None , recreate = False ):
242- self .validatepath (path )
243- _path = abspath (normpath (path ))
248+ _path = self .validatepath (path )
244249
245- if _path == '/' :
250+ if _path in '/' :
246251 if not recreate :
247252 raise errors .DirectoryExists (path )
248253
@@ -259,90 +264,77 @@ def makedir(self, path, permissions=None, recreate=False):
259264 def openbin (self , path , mode = 'r' , buffering = - 1 , ** options ):
260265 _mode = Mode (mode )
261266 _mode .validate_bin ()
262- self .validatepath (path )
267+ _path = self .validatepath (path )
263268
264269 log .debug ("openbin: %s, %s" , path , mode )
265270 with self ._lock :
266271 try :
267- info = self .getinfo (path )
272+ info = self .getinfo (_path )
268273 log .debug ("Info: %s" , info )
269274 except errors .ResourceNotFound :
270- if _mode .reading :
275+ if not _mode .create :
271276 raise errors .ResourceNotFound (path )
272277 else :
273278 if info .is_dir :
274279 raise errors .FileExpected (path )
275280 if _mode .exclusive :
276281 raise errors .FileExists (path )
277- wdfile = WebDAVFile (self , abspath (normpath (path )), mode )
278- return wdfile
282+ return WebDAVFile (self , _path , _mode )
279283
280284 def remove (self , path ):
281- if not self .exists (path ):
282- raise errors .ResourceNotFound (path )
283-
285+ _path = self .validatepath (path )
284286 if self .getinfo (path ).is_dir :
285287 raise errors .FileExpected (path )
286-
287- self .client .clean (path )
288+ self .client .clean (_path )
288289
289290 def removedir (self , path ):
290- if path == '/' :
291- raise errors .RemoveRootError
292-
293- if not self .exists (path ):
294- raise errors .ResourceNotFound (path )
295-
296- if not self .isdir (path ):
291+ _path = self .validatepath (path )
292+ if path in '/' :
293+ raise errors .RemoveRootError ()
294+ if not self .getinfo (path ).is_dir :
297295 raise errors .DirectoryExpected (path )
298-
299- checklist = self .client .list (path )
300- if checklist :
296+ if not self .isempty (_path ):
301297 raise errors .DirectoryNotEmpty (path )
302-
303- self .client .clean (path )
298+ self .client .clean (_path )
304299
305300 def setbytes (self , path , contents ):
306301 if not isinstance (contents , bytes ):
307302 raise ValueError ('contents must be bytes' )
308- _path = abspath (normpath (path ))
309- self .validatepath (path )
303+ _path = self .validatepath (path )
310304 bin_file = io .BytesIO (contents )
311305 with self ._lock :
312306 resource = self ._create_resource (_path )
313307 resource .read_from (bin_file )
314308
315309 def setinfo (self , path , info ):
316- if not self .exists (path ):
310+ _path = self .validatepath (path )
311+ if not self .exists (_path ):
317312 raise errors .ResourceNotFound (path )
318313
319- def create (self , path , wipe = False ):
320- with self ._lock :
321- if not wipe and self .exists (path ):
322- return False
323- with self .open (path , 'wb' ) as new_file :
324- # log.debug("CREATE %s", new_file)
325- new_file .truncate (0 )
326- return True
327-
328314 def copy (self , src_path , dst_path , overwrite = False ):
315+ _src_path = self .validatepath (src_path )
316+ _dst_path = self .validatepath (dst_path )
317+
329318 with self ._lock :
330- if not overwrite and self .exists (dst_path ):
319+ if not overwrite and self .exists (_dst_path ):
331320 raise errors .DestinationExists (dst_path )
332321 try :
333- self .client .copy (src_path , dst_path )
334- except we .RemoteResourceNotFound :
335- raise errors .ResourceNotFound (src_path )
336- except we .RemoteParentNotFound :
337- raise errors .ResourceNotFound (dst_path )
322+ self .client .copy (_src_path , _dst_path )
323+ except we .RemoteResourceNotFound as exc :
324+ raise errors .ResourceNotFound (src_path , exc = exc )
325+ except we .RemoteParentNotFound as exc :
326+ raise errors .ResourceNotFound (dst_path , exc = exc )
338327
339328 def move (self , src_path , dst_path , overwrite = False ):
340- if not overwrite and self .exists (dst_path ):
329+ _src_path = self .validatepath (src_path )
330+ _dst_path = self .validatepath (dst_path )
331+
332+ if not overwrite and self .exists (_dst_path ):
341333 raise errors .DestinationExists (dst_path )
342334 with self ._lock :
343335 try :
344- self .client .move (src_path , dst_path , overwrite = overwrite )
345- except we .RemoteResourceNotFound :
346- raise errors .ResourceNotFound (src_path )
347- except we .RemoteParentNotFound :
348- raise errors .ResourceNotFound (dst_path )
336+ self .client .move (_src_path , _dst_path , overwrite = overwrite )
337+ except we .RemoteResourceNotFound as exc :
338+ raise errors .ResourceNotFound (src_path , exc = exc )
339+ except we .RemoteParentNotFound as exc :
340+ raise errors .ResourceNotFound (dst_path , exc = exc )
0 commit comments