rclone-api 1.0.49__py2.py3-none-any.whl → 1.0.51__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rclone_api/file.py +54 -47
 - rclone_api/group_files.py +29 -8
 - rclone_api/rclone.py +680 -677
 - {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/METADATA +1 -1
 - {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/RECORD +9 -9
 - {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/LICENSE +0 -0
 - {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/WHEEL +0 -0
 - {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/entry_points.txt +0 -0
 - {rclone_api-1.0.49.dist-info → rclone_api-1.0.51.dist-info}/top_level.txt +0 -0
 
    
        rclone_api/file.py
    CHANGED
    
    | 
         @@ -1,47 +1,54 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            import json
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            from rclone_api.rpath import RPath
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
            class File:
         
     | 
| 
       7 
     | 
    
         
            -
                """Remote file dataclass."""
         
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                def __init__(
         
     | 
| 
       10 
     | 
    
         
            -
                    self,
         
     | 
| 
       11 
     | 
    
         
            -
                    path: RPath,
         
     | 
| 
       12 
     | 
    
         
            -
                ) -> None:
         
     | 
| 
       13 
     | 
    
         
            -
                    self.path = path
         
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
                @property
         
     | 
| 
       16 
     | 
    
         
            -
                def name(self) -> str:
         
     | 
| 
       17 
     | 
    
         
            -
                    return self.path.name
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                def read_text(self) -> str:
         
     | 
| 
       20 
     | 
    
         
            -
                    """Read the file contents as bytes.
         
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
                    Returns:
         
     | 
| 
       23 
     | 
    
         
            -
                        bytes: The file contents
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
                    Raises:
         
     | 
| 
       26 
     | 
    
         
            -
                        RuntimeError: If no rclone instance is associated with this file
         
     | 
| 
       27 
     | 
    
         
            -
                        RuntimeError: If the path represents a directory
         
     | 
| 
       28 
     | 
    
         
            -
                    """
         
     | 
| 
       29 
     | 
    
         
            -
                    if self.path.rclone is None:
         
     | 
| 
       30 
     | 
    
         
            -
                        raise RuntimeError("No rclone instance associated with this file")
         
     | 
| 
       31 
     | 
    
         
            -
                    if self.path.is_dir:
         
     | 
| 
       32 
     | 
    
         
            -
                        raise RuntimeError("Cannot read a directory as bytes")
         
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
       34 
     | 
    
         
            -
                    result = self.path.rclone._run(["cat", self.path.path], check=True)
         
     | 
| 
       35 
     | 
    
         
            -
                    return result.stdout
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
                def to_json(self) -> dict:
         
     | 
| 
       38 
     | 
    
         
            -
                    """Convert the File to a JSON serializable dictionary."""
         
     | 
| 
       39 
     | 
    
         
            -
                    return self.path.to_json()
         
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
                def  
     | 
| 
       42 
     | 
    
         
            -
                     
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
                     
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            import json
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            from rclone_api.rpath import RPath
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            class File:
         
     | 
| 
      
 7 
     | 
    
         
            +
                """Remote file dataclass."""
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def __init__(
         
     | 
| 
      
 10 
     | 
    
         
            +
                    self,
         
     | 
| 
      
 11 
     | 
    
         
            +
                    path: RPath,
         
     | 
| 
      
 12 
     | 
    
         
            +
                ) -> None:
         
     | 
| 
      
 13 
     | 
    
         
            +
                    self.path = path
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                @property
         
     | 
| 
      
 16 
     | 
    
         
            +
                def name(self) -> str:
         
     | 
| 
      
 17 
     | 
    
         
            +
                    return self.path.name
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def read_text(self) -> str:
         
     | 
| 
      
 20 
     | 
    
         
            +
                    """Read the file contents as bytes.
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    Returns:
         
     | 
| 
      
 23 
     | 
    
         
            +
                        bytes: The file contents
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    Raises:
         
     | 
| 
      
 26 
     | 
    
         
            +
                        RuntimeError: If no rclone instance is associated with this file
         
     | 
| 
      
 27 
     | 
    
         
            +
                        RuntimeError: If the path represents a directory
         
     | 
| 
      
 28 
     | 
    
         
            +
                    """
         
     | 
| 
      
 29 
     | 
    
         
            +
                    if self.path.rclone is None:
         
     | 
| 
      
 30 
     | 
    
         
            +
                        raise RuntimeError("No rclone instance associated with this file")
         
     | 
| 
      
 31 
     | 
    
         
            +
                    if self.path.is_dir:
         
     | 
| 
      
 32 
     | 
    
         
            +
                        raise RuntimeError("Cannot read a directory as bytes")
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                    result = self.path.rclone._run(["cat", self.path.path], check=True)
         
     | 
| 
      
 35 
     | 
    
         
            +
                    return result.stdout
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def to_json(self) -> dict:
         
     | 
| 
      
 38 
     | 
    
         
            +
                    """Convert the File to a JSON serializable dictionary."""
         
     | 
| 
      
 39 
     | 
    
         
            +
                    return self.path.to_json()
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                def to_string(self, include_remote: bool = True) -> str:
         
     | 
| 
      
 42 
     | 
    
         
            +
                    """Convert the File to a string."""
         
     | 
| 
      
 43 
     | 
    
         
            +
                    out = str(self.path)
         
     | 
| 
      
 44 
     | 
    
         
            +
                    if not include_remote:
         
     | 
| 
      
 45 
     | 
    
         
            +
                        _, out = out.split(":", 1)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    return out
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                def __str__(self) -> str:
         
     | 
| 
      
 49 
     | 
    
         
            +
                    return str(self.path)
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                def __repr__(self) -> str:
         
     | 
| 
      
 52 
     | 
    
         
            +
                    data = self.path.to_json()
         
     | 
| 
      
 53 
     | 
    
         
            +
                    data_str = json.dumps(data)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    return data_str
         
     | 
    
        rclone_api/group_files.py
    CHANGED
    
    | 
         @@ -112,12 +112,19 @@ def _make_tree(files: list[str]) -> dict[str, TreeNode]: 
     | 
|
| 
       112 
112 
     | 
    
         
             
                    parts = parse_file(file)
         
     | 
| 
       113 
113 
     | 
    
         
             
                    remote = parts.remote
         
     | 
| 
       114 
114 
     | 
    
         
             
                    node: TreeNode = tree.setdefault(remote, TreeNode(remote))
         
     | 
| 
       115 
     | 
    
         
            -
                     
     | 
| 
       116 
     | 
    
         
            -
                         
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
     | 
    
         
            -
             
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
       120 
     | 
    
         
            -
                             
     | 
| 
      
 115 
     | 
    
         
            +
                    if parts.parents:
         
     | 
| 
      
 116 
     | 
    
         
            +
                        for parent in parts.parents:
         
     | 
| 
      
 117 
     | 
    
         
            +
                            is_last = parent == parts.parents[-1]
         
     | 
| 
      
 118 
     | 
    
         
            +
                            node = node.child_nodes.setdefault(
         
     | 
| 
      
 119 
     | 
    
         
            +
                                parent, TreeNode(parent, parent=node)
         
     | 
| 
      
 120 
     | 
    
         
            +
                            )
         
     | 
| 
      
 121 
     | 
    
         
            +
                            if is_last:
         
     | 
| 
      
 122 
     | 
    
         
            +
                                node.files.append(parts.name)
         
     | 
| 
      
 123 
     | 
    
         
            +
                                node.add_count_bubble_up()
         
     | 
| 
      
 124 
     | 
    
         
            +
                    else:
         
     | 
| 
      
 125 
     | 
    
         
            +
                        node.files.append(parts.name)
         
     | 
| 
      
 126 
     | 
    
         
            +
                        node.add_count_bubble_up()
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
       121 
128 
     | 
    
         
             
                return tree
         
     | 
| 
       122 
129 
     | 
    
         | 
| 
       123 
130 
     | 
    
         | 
| 
         @@ -134,13 +141,27 @@ def _fixup_rclone_paths(outpaths: dict[str, list[str]]) -> dict[str, list[str]]: 
     | 
|
| 
       134 
141 
     | 
    
         
             
                return out
         
     | 
| 
       135 
142 
     | 
    
         | 
| 
       136 
143 
     | 
    
         | 
| 
       137 
     | 
    
         
            -
            def group_files(files: list[str]) -> dict[str, list[str]]:
         
     | 
| 
      
 144 
     | 
    
         
            +
            def group_files(files: list[str], fully_qualified: bool = True) -> dict[str, list[str]]:
         
     | 
| 
       138 
145 
     | 
    
         
             
                """split between filename and parent directory path"""
         
     | 
| 
      
 146 
     | 
    
         
            +
                if fully_qualified is False:
         
     | 
| 
      
 147 
     | 
    
         
            +
                    for i, file in enumerate(files):
         
     | 
| 
      
 148 
     | 
    
         
            +
                        file = "root:" + file
         
     | 
| 
      
 149 
     | 
    
         
            +
                        files[i] = file
         
     | 
| 
       139 
150 
     | 
    
         
             
                tree: dict[str, TreeNode] = _make_tree(files)
         
     | 
| 
       140 
151 
     | 
    
         
             
                outpaths: dict[str, list[str]] = {}
         
     | 
| 
       141 
152 
     | 
    
         
             
                for _, node in tree.items():
         
     | 
| 
       142 
153 
     | 
    
         
             
                    _merge(node, "", outpaths)
         
     | 
| 
       143 
     | 
    
         
            -
                 
     | 
| 
      
 154 
     | 
    
         
            +
                tmp: dict[str, list[str]] = _fixup_rclone_paths(outpaths=outpaths)
         
     | 
| 
      
 155 
     | 
    
         
            +
                out: dict[str, list[str]] = {}
         
     | 
| 
      
 156 
     | 
    
         
            +
                if fully_qualified is False:
         
     | 
| 
      
 157 
     | 
    
         
            +
                    for path, files in tmp.items():
         
     | 
| 
      
 158 
     | 
    
         
            +
                        if path.startswith("root"):
         
     | 
| 
      
 159 
     | 
    
         
            +
                            path = path.replace("root", "")
         
     | 
| 
      
 160 
     | 
    
         
            +
                            if path.startswith(":"):
         
     | 
| 
      
 161 
     | 
    
         
            +
                                path = path[1:]
         
     | 
| 
      
 162 
     | 
    
         
            +
                        out[path] = [file.replace("/root/", "") for file in files]
         
     | 
| 
      
 163 
     | 
    
         
            +
                else:
         
     | 
| 
      
 164 
     | 
    
         
            +
                    out = tmp
         
     | 
| 
       144 
165 
     | 
    
         
             
                return out
         
     | 
| 
       145 
166 
     | 
    
         | 
| 
       146 
167 
     | 
    
         |