@@ -249,10 +249,10 @@ async def list_directory(self, path: str = "") -> List[Dict[str, Any]]:
249249 webdav_path = f"{ self ._get_webdav_base_path ()} /{ path .lstrip ('/' )} "
250250 if not webdav_path .endswith ("/" ):
251251 webdav_path += "/"
252-
252+
253253 logger .info (f"Listing directory: { webdav_path } " )
254-
255- propfind_body = ''' <?xml version="1.0"?>
254+
255+ propfind_body = """ <?xml version="1.0"?>
256256 <d:propfind xmlns:d="DAV:">
257257 <d:prop>
258258 <d:displayname/>
@@ -261,73 +261,80 @@ async def list_directory(self, path: str = "") -> List[Dict[str, Any]]:
261261 <d:getlastmodified/>
262262 <d:resourcetype/>
263263 </d:prop>
264- </d:propfind>'''
265-
266- headers = {
267- "Depth" : "1" ,
268- "Content-Type" : "text/xml" ,
269- "OCS-APIRequest" : "true"
270- }
271-
264+ </d:propfind>"""
265+
266+ headers = {"Depth" : "1" , "Content-Type" : "text/xml" , "OCS-APIRequest" : "true" }
267+
272268 try :
273269 response = await self ._client .request (
274270 "PROPFIND" , webdav_path , content = propfind_body , headers = headers
275271 )
276272 response .raise_for_status ()
277-
273+
278274 # Parse the XML response
279275 root = ET .fromstring (response .content )
280276 items = []
281-
277+
282278 # Skip the first response (the directory itself)
283279 responses = root .findall (".//{DAV:}response" )[1 :]
284-
280+
285281 for response_elem in responses :
286282 href = response_elem .find (".//{DAV:}href" )
287283 if href is None :
288284 continue
289-
285+
290286 # Extract file/directory name from href
291287 href_text = href .text or ""
292288 name = href_text .rstrip ("/" ).split ("/" )[- 1 ]
293289 if not name :
294290 continue
295-
291+
296292 # Get properties
297293 propstat = response_elem .find (".//{DAV:}propstat" )
298294 if propstat is None :
299295 continue
300-
296+
301297 prop = propstat .find (".//{DAV:}prop" )
302298 if prop is None :
303299 continue
304-
300+
305301 # Determine if it's a directory
306302 resourcetype = prop .find (".//{DAV:}resourcetype" )
307- is_directory = resourcetype is not None and resourcetype .find (".//{DAV:}collection" ) is not None
308-
303+ is_directory = (
304+ resourcetype is not None
305+ and resourcetype .find (".//{DAV:}collection" ) is not None
306+ )
307+
309308 # Get other properties
310309 size_elem = prop .find (".//{DAV:}getcontentlength" )
311- size = int (size_elem .text ) if size_elem is not None and size_elem .text else 0
312-
310+ size = (
311+ int (size_elem .text )
312+ if size_elem is not None and size_elem .text
313+ else 0
314+ )
315+
313316 content_type_elem = prop .find (".//{DAV:}getcontenttype" )
314- content_type = content_type_elem .text if content_type_elem is not None else None
315-
317+ content_type = (
318+ content_type_elem .text if content_type_elem is not None else None
319+ )
320+
316321 modified_elem = prop .find (".//{DAV:}getlastmodified" )
317322 modified = modified_elem .text if modified_elem is not None else None
318-
319- items .append ({
320- "name" : name ,
321- "path" : f"{ path .rstrip ('/' )} /{ name } " if path else name ,
322- "is_directory" : is_directory ,
323- "size" : size if not is_directory else None ,
324- "content_type" : content_type ,
325- "last_modified" : modified
326- })
327-
323+
324+ items .append (
325+ {
326+ "name" : name ,
327+ "path" : f"{ path .rstrip ('/' )} /{ name } " if path else name ,
328+ "is_directory" : is_directory ,
329+ "size" : size if not is_directory else None ,
330+ "content_type" : content_type ,
331+ "last_modified" : modified ,
332+ }
333+ )
334+
328335 logger .info (f"Found { len (items )} items in directory: { webdav_path } " )
329336 return items
330-
337+
331338 except HTTPStatusError as e :
332339 logger .error (f"HTTP error listing directory '{ webdav_path } ': { e } " )
333340 raise e
@@ -338,49 +345,56 @@ async def list_directory(self, path: str = "") -> List[Dict[str, Any]]:
338345 async def read_file (self , path : str ) -> Tuple [bytes , str ]:
339346 """Read a file's content via WebDAV GET."""
340347 webdav_path = f"{ self ._get_webdav_base_path ()} /{ path .lstrip ('/' )} "
341-
348+
342349 logger .info (f"Reading file: { webdav_path } " )
343-
350+
344351 try :
345352 response = await self ._client .get (webdav_path )
346353 response .raise_for_status ()
347-
354+
348355 content = response .content
349- content_type = response .headers .get ("content-type" , "application/octet-stream" )
350-
351- logger .info (f"Successfully read file '{ path } ' ({ content_type } , { len (content )} bytes)" )
356+ content_type = response .headers .get (
357+ "content-type" , "application/octet-stream"
358+ )
359+
360+ logger .info (
361+ f"Successfully read file '{ path } ' ({ content_type } , { len (content )} bytes)"
362+ )
352363 return content , content_type
353-
364+
354365 except HTTPStatusError as e :
355366 logger .error (f"HTTP error reading file '{ path } ': { e } " )
356367 raise e
357368 except Exception as e :
358369 logger .error (f"Unexpected error reading file '{ path } ': { e } " )
359370 raise e
360371
361- async def write_file (self , path : str , content : bytes , content_type : Optional [str ] = None ) -> Dict [str , Any ]:
372+ async def write_file (
373+ self , path : str , content : bytes , content_type : Optional [str ] = None
374+ ) -> Dict [str , Any ]:
362375 """Write content to a file via WebDAV PUT."""
363376 webdav_path = f"{ self ._get_webdav_base_path ()} /{ path .lstrip ('/' )} "
364-
377+
365378 logger .info (f"Writing file: { webdav_path } " )
366-
379+
367380 if not content_type :
368381 content_type , _ = mimetypes .guess_type (path )
369382 if not content_type :
370383 content_type = "application/octet-stream"
371-
372- headers = {
373- "Content-Type" : content_type ,
374- "OCS-APIRequest" : "true"
375- }
376-
384+
385+ headers = {"Content-Type" : content_type , "OCS-APIRequest" : "true" }
386+
377387 try :
378- response = await self ._client .put (webdav_path , content = content , headers = headers )
388+ response = await self ._client .put (
389+ webdav_path , content = content , headers = headers
390+ )
379391 response .raise_for_status ()
380-
381- logger .info (f"Successfully wrote file '{ path } ' (Status: { response .status_code } )" )
392+
393+ logger .info (
394+ f"Successfully wrote file '{ path } ' (Status: { response .status_code } )"
395+ )
382396 return {"status_code" : response .status_code }
383-
397+
384398 except HTTPStatusError as e :
385399 logger .error (f"HTTP error writing file '{ path } ': { e } " )
386400 raise e
@@ -393,20 +407,24 @@ async def create_directory(self, path: str) -> Dict[str, Any]:
393407 webdav_path = f"{ self ._get_webdav_base_path ()} /{ path .lstrip ('/' )} "
394408 if not webdav_path .endswith ("/" ):
395409 webdav_path += "/"
396-
410+
397411 logger .info (f"Creating directory: { webdav_path } " )
398-
412+
399413 headers = {"OCS-APIRequest" : "true" }
400-
414+
401415 try :
402416 response = await self ._client .request ("MKCOL" , webdav_path , headers = headers )
403417 response .raise_for_status ()
404-
405- logger .info (f"Successfully created directory '{ path } ' (Status: { response .status_code } )" )
418+
419+ logger .info (
420+ f"Successfully created directory '{ path } ' (Status: { response .status_code } )"
421+ )
406422 return {"status_code" : response .status_code }
407-
423+
408424 except HTTPStatusError as e :
409- if e .response .status_code == 405 : # Method Not Allowed - directory already exists
425+ if (
426+ e .response .status_code == 405
427+ ): # Method Not Allowed - directory already exists
410428 logger .info (f"Directory '{ path } ' already exists" )
411429 return {"status_code" : 405 , "message" : "Directory already exists" }
412430 logger .error (f"HTTP error creating directory '{ path } ': { e } " )
0 commit comments