ftp_download

 1from . import ensure
 2from . import timings
 3from .prefs import Conf
 4
 5from os import path, makedirs
 6import asyncio
 7import ftplib  # https://github.com/python/cpython/blob/3.12/Lib/ftplib.py
 8from typing import Optional
 9
10
11def file(
12        ftp: ftplib.FTP,
13        remote_file_path: str,
14        local_path: str = Conf.download_folder
15        ) -> None:
16
17    """
18    Download a single file from a FTP server. Uses full path to file on the server, and full path to the download directory.
19
20    Can use relative path to the file on the server, if `ftp.cwd('/path/to/folder/')` was called before.
21
22    ### Args:
23
24    - **ftp** (`ftplib.FTP`): A `ftplib.FTP` object, expects to be already connected and logged in
25    - **remote_file_path** (`str`):  Full path including filename of the file that will be downloaded
26    - **local_path** (`str`): Full path to local directory where the file will be downloaded, defaults to `Conf.download_folder`'s value
27    """ # noqa
28
29    ensure.login(ftp=ftp)
30
31    if not path.exists(local_path):
32        makedirs(local_path)
33
34    if Conf.use_async:
35        task = timings.download_task(ftp, remote_file_path, local_path)
36        timings.run(task)
37
38    else:
39        timings.blocking_download_task(ftp, remote_file_path, local_path)
40
41
42def from_folder(
43        ftp: ftplib.FTP,
44        remote_path: str,
45        local_path: str = Conf.download_folder,
46        stops_with: Optional[int] = None
47        ) -> None:
48
49    """
50    Download multiple files from a folder on a FTP Server.
51
52    ### Args:
53
54    - **ftp** (`ftplib.FTP`): An instance of the FTP class;
55    - **remote_path** (`str`): Remote path on FTP server to desired files;
56    - **local_path** (`str`): Local path where files should be dumped;
57    - **stops_with** (`int` or `None`): If not `None`, defines the maximum amount of files to be downloaded, otherwise download every file in `remote_path`. Defaults to `None`.
58    """ # noqa
59
60    ensure.login(ftp=ftp)
61
62    remote_path = ensure.posix_path(remote_path)
63    local_path = path.normpath(local_path)
64
65    if not path.exists(local_path):
66        makedirs(local_path)
67
68    filenames = ensure.describe_dir(ftp, remote_path)["files"]
69    if Conf.verbose:
70        if (stops_with is int) and (stops_with >= 0):
71            print(f"Processing {stops_with} files from {remote_path}...")
72        else:
73            print(f"Processing {len(filenames)} files from {remote_path}...")
74
75    tasks = []
76    for idx, filename in enumerate(filenames):
77
78        if stops_with == idx:
79            break
80
81        remote_file_path = ensure.posix_path(path.join(remote_path, filename))
82
83        if Conf.use_async:
84            task = timings.download_task(ftp, remote_file_path, local_path)
85            tasks.append(task)
86        else:
87            timings.blocking_download_task(ftp, remote_file_path, local_path)
88
89    if Conf.use_async:
90        try:
91            loop = asyncio.get_event_loop()
92            loop.create_task(timings.run_multiple(tasks))
93
94        except RuntimeError:
95            timings.run(timings.run_multiple(tasks))
def file( ftp: ftplib.FTP, remote_file_path: str, local_path: str = '/home/user/Downloads/ftp_download') -> None:
12def file(
13        ftp: ftplib.FTP,
14        remote_file_path: str,
15        local_path: str = Conf.download_folder
16        ) -> None:
17
18    """
19    Download a single file from a FTP server. Uses full path to file on the server, and full path to the download directory.
20
21    Can use relative path to the file on the server, if `ftp.cwd('/path/to/folder/')` was called before.
22
23    ### Args:
24
25    - **ftp** (`ftplib.FTP`): A `ftplib.FTP` object, expects to be already connected and logged in
26    - **remote_file_path** (`str`):  Full path including filename of the file that will be downloaded
27    - **local_path** (`str`): Full path to local directory where the file will be downloaded, defaults to `Conf.download_folder`'s value
28    """ # noqa
29
30    ensure.login(ftp=ftp)
31
32    if not path.exists(local_path):
33        makedirs(local_path)
34
35    if Conf.use_async:
36        task = timings.download_task(ftp, remote_file_path, local_path)
37        timings.run(task)
38
39    else:
40        timings.blocking_download_task(ftp, remote_file_path, local_path)

Download a single file from a FTP server. Uses full path to file on the server, and full path to the download directory.

Can use relative path to the file on the server, if ftp.cwd('/path/to/folder/') was called before.

Args:

  • ftp (ftplib.FTP): A ftplib.FTP object, expects to be already connected and logged in
  • remote_file_path (str): Full path including filename of the file that will be downloaded
  • local_path (str): Full path to local directory where the file will be downloaded, defaults to Conf.download_folder's value
def from_folder( ftp: ftplib.FTP, remote_path: str, local_path: str = '/home/user/Downloads/ftp_download', stops_with: Optional[int] = None) -> None:
43def from_folder(
44        ftp: ftplib.FTP,
45        remote_path: str,
46        local_path: str = Conf.download_folder,
47        stops_with: Optional[int] = None
48        ) -> None:
49
50    """
51    Download multiple files from a folder on a FTP Server.
52
53    ### Args:
54
55    - **ftp** (`ftplib.FTP`): An instance of the FTP class;
56    - **remote_path** (`str`): Remote path on FTP server to desired files;
57    - **local_path** (`str`): Local path where files should be dumped;
58    - **stops_with** (`int` or `None`): If not `None`, defines the maximum amount of files to be downloaded, otherwise download every file in `remote_path`. Defaults to `None`.
59    """ # noqa
60
61    ensure.login(ftp=ftp)
62
63    remote_path = ensure.posix_path(remote_path)
64    local_path = path.normpath(local_path)
65
66    if not path.exists(local_path):
67        makedirs(local_path)
68
69    filenames = ensure.describe_dir(ftp, remote_path)["files"]
70    if Conf.verbose:
71        if (stops_with is int) and (stops_with >= 0):
72            print(f"Processing {stops_with} files from {remote_path}...")
73        else:
74            print(f"Processing {len(filenames)} files from {remote_path}...")
75
76    tasks = []
77    for idx, filename in enumerate(filenames):
78
79        if stops_with == idx:
80            break
81
82        remote_file_path = ensure.posix_path(path.join(remote_path, filename))
83
84        if Conf.use_async:
85            task = timings.download_task(ftp, remote_file_path, local_path)
86            tasks.append(task)
87        else:
88            timings.blocking_download_task(ftp, remote_file_path, local_path)
89
90    if Conf.use_async:
91        try:
92            loop = asyncio.get_event_loop()
93            loop.create_task(timings.run_multiple(tasks))
94
95        except RuntimeError:
96            timings.run(timings.run_multiple(tasks))

Download multiple files from a folder on a FTP Server.

Args:

  • ftp (ftplib.FTP): An instance of the FTP class;
  • remote_path (str): Remote path on FTP server to desired files;
  • local_path (str): Local path where files should be dumped;
  • stops_with (int or None): If not None, defines the maximum amount of files to be downloaded, otherwise download every file in remote_path. Defaults to None.