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