trio-ftplib/trio_ftplib/operations.py

36 lines
1.2 KiB
Python
Raw Normal View History

2020-03-09 18:13:45 -03:00
import ftplib
import posixpath
from typing import AsyncIterator
from async_generator import aclosing
from ._aftplib import AFTP
async def download_text(server: str, user: str, password: str, path: str,
encoding='cp1252', n_attempts: int = 10) -> AsyncIterator[str]:
nlines_sent = 0
for attempt in range(n_attempts):
ftp = AFTP(server, user, password)
await ftp.connect()
filename = posixpath.basename(path)
path = posixpath.dirname(path)
if path:
await ftp.cwd(path)
nlines_captured = 0
try:
async with aclosing(ftp.iretrlines(f"RETR '{filename}'")) as _iterator:
async for line in _iterator:
nlines_captured += 1
if nlines_captured <= nlines_sent:
continue
nlines_sent += 1
yield line.decode(encoding)
except ftplib.error_temp as e:
if '426-Data transfer timeout, aborted' not in e.args[0]:
raise
else:
break
else:
raise Exception(f'Failed {n_attempts} attempts, cancelling')