|
21 | 21 | import urllib.parse |
22 | 22 | from contextlib import asynccontextmanager |
23 | 23 | from copy import copy |
| 24 | +from datetime import datetime |
24 | 25 | from typing import Dict, List, Optional, Tuple |
25 | 26 |
|
26 | 27 | import aiohttp |
27 | 28 | import cachetools |
28 | 29 | import fsspec.implementations.http as fshttp |
29 | | -from aiowebdav2.client import Client |
| 30 | +from aiowebdav2.client import ( |
| 31 | + Client, |
| 32 | + Urn, |
| 33 | +) |
30 | 34 | from aiowebdav2.exceptions import ( |
31 | 35 | MethodNotSupportedError, |
32 | 36 | RemoteResourceNotFoundError, |
33 | 37 | ResponseErrorCodeError, |
34 | 38 | ) |
| 39 | +from aiowebdav2.parser import WebDavXmlUtils |
35 | 40 | from fsspec.asyn import AsyncFileSystem, sync |
36 | 41 | from fsspec.utils import glob_translate |
37 | 42 |
|
@@ -570,18 +575,44 @@ async def _ls_real(self, url, detail=True): |
570 | 575 |
|
571 | 576 | async def get_item_detail(item): |
572 | 577 | full_path = f"{base_url}{item}" |
| 578 | + urn = Urn(item) |
| 579 | + path = client.get_full_path(urn) |
| 580 | + response = await client.execute_request( |
| 581 | + action="info", |
| 582 | + path=urn.path(), |
| 583 | + headers_ext=["Depth: 0"], |
| 584 | + ) |
| 585 | + content = await response.read() |
| 586 | + |
| 587 | + # determine directory status |
573 | 588 | try: |
574 | | - is_directory = await client.is_dir(item) |
575 | | - type_ = "directory" if is_directory else "file" |
576 | | - except MethodNotSupportedError as e: |
577 | | - if getattr(e, "name", "") == "is_dir": |
578 | | - type_ = "file" |
579 | | - else: |
580 | | - raise |
| 589 | + is_directory = WebDavXmlUtils.parse_is_dir_response( |
| 590 | + content=content, |
| 591 | + path=path, |
| 592 | + hostname=client._url, |
| 593 | + ) |
| 594 | + except MethodNotSupportedError: |
| 595 | + # If the server does not support the is_dir method, we assume it is a file |
| 596 | + is_directory = False |
| 597 | + |
| 598 | + # get other info |
| 599 | + info = WebDavXmlUtils.parse_info_response( |
| 600 | + content=content, |
| 601 | + path=path, |
| 602 | + hostname=client._url, |
| 603 | + ) |
| 604 | + if (modtimestr := info.get("modified")) == "None": |
| 605 | + modtime = None |
| 606 | + else: |
| 607 | + modtime = datetime.strptime( |
| 608 | + info["modified"], |
| 609 | + "%a, %d %b %Y %H:%M:%S %Z", |
| 610 | + ) |
581 | 611 | return { |
582 | 612 | "name": full_path, |
583 | | - "size": None, |
584 | | - "type": type_, |
| 613 | + "size": int(info["size"]), |
| 614 | + "type": "directory" if is_directory else "file", |
| 615 | + "modified": modtime, |
585 | 616 | } |
586 | 617 |
|
587 | 618 | return await asyncio.gather(*(get_item_detail(item) for item in items)) |
|
0 commit comments