Class used by open_ftp() for cache of open FTP connections.
| 1772 | # Utility classes |
| 1773 | |
| 1774 | class ftpwrapper: |
| 1775 | """Class used by open_ftp() for cache of open FTP connections.""" |
| 1776 | |
| 1777 | def __init__(self, user, passwd, host, port, dirs, timeout=None, |
| 1778 | persistent=True): |
| 1779 | self.user = user |
| 1780 | self.passwd = passwd |
| 1781 | self.host = host |
| 1782 | self.port = port |
| 1783 | self.dirs = dirs |
| 1784 | self.timeout = timeout |
| 1785 | self.refcount = 0 |
| 1786 | self.keepalive = persistent |
| 1787 | try: |
| 1788 | self.init() |
| 1789 | except: |
| 1790 | self.close() |
| 1791 | raise |
| 1792 | |
| 1793 | def init(self): |
| 1794 | import ftplib |
| 1795 | self.busy = 0 |
| 1796 | self.ftp = ftplib.FTP() |
| 1797 | self.ftp.connect(self.host, self.port, self.timeout) |
| 1798 | self.ftp.login(self.user, self.passwd) |
| 1799 | _target = '/'.join(self.dirs) |
| 1800 | self.ftp.cwd(_target) |
| 1801 | |
| 1802 | def retrfile(self, file, type): |
| 1803 | import ftplib |
| 1804 | self.endtransfer() |
| 1805 | if type in ('d', 'D'): cmd = 'TYPE A'; isdir = 1 |
| 1806 | else: cmd = 'TYPE ' + type; isdir = 0 |
| 1807 | try: |
| 1808 | self.ftp.voidcmd(cmd) |
| 1809 | except ftplib.all_errors: |
| 1810 | self.init() |
| 1811 | self.ftp.voidcmd(cmd) |
| 1812 | conn = None |
| 1813 | if file and not isdir: |
| 1814 | # Try to retrieve as a file |
| 1815 | try: |
| 1816 | cmd = 'RETR ' + file |
| 1817 | conn, retrlen = self.ftp.ntransfercmd(cmd) |
| 1818 | except ftplib.error_perm as reason: |
| 1819 | if str(reason)[:3] != '550': |
| 1820 | raise URLError(f'ftp error: {reason}') from reason |
| 1821 | if not conn: |
| 1822 | # Set transfer mode to ASCII! |
| 1823 | self.ftp.voidcmd('TYPE A') |
| 1824 | # Try a directory listing. Verify that directory exists. |
| 1825 | if file: |
| 1826 | pwd = self.ftp.pwd() |
| 1827 | try: |
| 1828 | try: |
| 1829 | self.ftp.cwd(file) |
| 1830 | except ftplib.error_perm as reason: |
| 1831 | raise URLError('ftp error: %r' % reason) from reason |
no outgoing calls
no test coverage detected