File: move.py

package info (click to toggle)
python-fs 2.4.16-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,944 kB
  • sloc: python: 13,048; makefile: 226; sh: 3
file content (145 lines) | stat: -rw-r--r-- 5,424 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
"""Functions for moving files between filesystems.
"""

from __future__ import print_function, unicode_literals

import typing

from ._pathcompat import commonpath
from .copy import copy_dir, copy_file
from .errors import FSError
from .opener import manage_fs
from .osfs import OSFS
from .path import frombase

if typing.TYPE_CHECKING:
    from typing import Text, Union

    from .base import FS


def move_fs(
    src_fs,  # type: Union[Text, FS]
    dst_fs,  # type:Union[Text, FS]
    workers=0,  # type: int
    preserve_time=False,  # type: bool
):
    # type: (...) -> None
    """Move the contents of a filesystem to another filesystem.

    Arguments:
        src_fs (FS or str): Source filesystem (instance or URL).
        dst_fs (FS or str): Destination filesystem (instance or URL).
        workers (int): Use `worker` threads to copy data, or ``0`` (default) for
            a single-threaded copy.
        preserve_time (bool): If `True`, try to preserve mtime of the
            resources (defaults to `False`).

    """
    move_dir(src_fs, "/", dst_fs, "/", workers=workers, preserve_time=preserve_time)


def move_file(
    src_fs,  # type: Union[Text, FS]
    src_path,  # type: Text
    dst_fs,  # type: Union[Text, FS]
    dst_path,  # type: Text
    preserve_time=False,  # type: bool
    cleanup_dst_on_error=True,  # type: bool
):
    # type: (...) -> None
    """Move a file from one filesystem to another.

    Arguments:
        src_fs (FS or str): Source filesystem (instance or URL).
        src_path (str): Path to a file on ``src_fs``.
        dst_fs (FS or str): Destination filesystem (instance or URL).
        dst_path (str): Path to a file on ``dst_fs``.
        preserve_time (bool): If `True`, try to preserve mtime of the
            resources (defaults to `False`).
        cleanup_dst_on_error (bool): If `True`, tries to delete the file copied to
            ``dst_fs`` if deleting the file from ``src_fs`` fails (defaults to `True`).

    """
    with manage_fs(src_fs, writeable=True) as _src_fs:
        with manage_fs(dst_fs, writeable=True, create=True) as _dst_fs:
            if _src_fs is _dst_fs:
                # Same filesystem, may be optimized
                _src_fs.move(
                    src_path, dst_path, overwrite=True, preserve_time=preserve_time
                )
                return

            if _src_fs.hassyspath(src_path) and _dst_fs.hassyspath(dst_path):
                # if both filesystems have a syspath we create a new OSFS from a
                # common parent folder and use it to move the file.
                try:
                    src_syspath = _src_fs.getsyspath(src_path)
                    dst_syspath = _dst_fs.getsyspath(dst_path)
                    common = commonpath([src_syspath, dst_syspath])
                    if common:
                        rel_src = frombase(common, src_syspath)
                        rel_dst = frombase(common, dst_syspath)
                        with _src_fs.lock(), _dst_fs.lock():
                            with OSFS(common) as base:
                                base.move(rel_src, rel_dst, preserve_time=preserve_time)
                                return  # optimization worked, exit early
                except ValueError:
                    # This is raised if we cannot find a common base folder.
                    # In this case just fall through to the standard method.
                    pass

            # Standard copy and delete
            with _src_fs.lock(), _dst_fs.lock():
                copy_file(
                    _src_fs,
                    src_path,
                    _dst_fs,
                    dst_path,
                    preserve_time=preserve_time,
                )
                try:
                    _src_fs.remove(src_path)
                except FSError as e:
                    # if the source cannot be removed we delete the copy on the
                    # destination
                    if cleanup_dst_on_error:
                        _dst_fs.remove(dst_path)
                    raise e


def move_dir(
    src_fs,  # type: Union[Text, FS]
    src_path,  # type: Text
    dst_fs,  # type: Union[Text, FS]
    dst_path,  # type: Text
    workers=0,  # type: int
    preserve_time=False,  # type: bool
):
    # type: (...) -> None
    """Move a directory from one filesystem to another.

    Arguments:
        src_fs (FS or str): Source filesystem (instance or URL).
        src_path (str): Path to a directory on ``src_fs``
        dst_fs (FS or str): Destination filesystem (instance or URL).
        dst_path (str): Path to a directory on ``dst_fs``.
        workers (int): Use ``worker`` threads to copy data, or ``0``
            (default) for a single-threaded copy.
        preserve_time (bool): If `True`, try to preserve mtime of the
            resources (defaults to `False`).

    """
    with manage_fs(src_fs, writeable=True) as _src_fs:
        with manage_fs(dst_fs, writeable=True, create=True) as _dst_fs:
            with _src_fs.lock(), _dst_fs.lock():
                _dst_fs.makedir(dst_path, recreate=True)
                copy_dir(
                    src_fs,
                    src_path,
                    dst_fs,
                    dst_path,
                    workers=workers,
                    preserve_time=preserve_time,
                )
                _src_fs.removetree(src_path)