⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftplib_client.py

📁 CoralFTP是一款用Python语言编写的工作在GTK2环境下的FTP客户端软件
💻 PY
📖 第 1 页 / 共 2 页
字号:
#!/usr/bin/env python# -*- coding: utf-8 -*-# Copyright (C) 1994  Ling Li## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# GNU Library General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.import gtkimport ftplib, os, re, select, string, sys, time, logging, socketfrom ftplib import FTP, error_temp, error_permfrom logging import debug, info, error, warningfrom threading import Threadimport ftp_enginefrom configuration import config_key, config_valuefrom ftp_exception import *from utils import *class AdvancedFTP(FTP):    '''AdvancedFTP is an enhancement of ftplib of Python.'''        timeout = None    charset = 'UTF-8'    def __init__(self, host='', user='', passwd='', acct=''):        FTP.__init__(self, host, user, passwd, acct)    def set_charset(self, charset):        self.charset = charset    def set_logger(self, logger):        self.logger = logger    def sanitize(self, s):        if s[:5] == 'pass ' or s[:5] == 'PASS ':            i = len(s)            while i > 5 and s[i-1] in '\r\n':                i = i-1            s = s[:5] + '*'*(i-5) + s[i:]        return s    def getline(self):        poll = select.poll()        poll.register(select.POLLIN)        poll.poll(1000)        line = None        while self.file != None and (line == None or line == ''):            line = self.file.readline()            if self.charset != None:                if not isinstance(line, unicode):                    try:                        line = unicode(line, self.charset)                    except UnicodeDecodeError:                        pass            if self.debugging > 1:                self.logger.write('*get* %s\n' % line)            if not line: raise EOFError            if line[-2:] == ftplib.CRLF: line = line[:-2]            elif line[-1:] in ftplib.CRLF: line = line[:-1]        return line    def putcmd(self, line):        if self.debugging:            self.logger.write('*cmd* %s\n' % self.sanitize(line))        self.putline(line)    def putline(self, line):        if self.charset != None and isinstance(line, unicode):            line = line.encode(self.charset) + ftplib.CRLF        else:            line = line + ftplib.CRLF        if self.debugging > 1:            if string.lowercase(line[:5]) == 'pass ':                i = len(line)                while i > 5 and line[i-1] in '\r\n':                    i = i-1                line = line[:5] + '*'*(i-5) + line[i:]            self.logger.write('*put* %s\n' % line)        self.sock.sendall(line)    def getresp(self):        resp = self.getmultiline()        if self.debugging:            self.logger.write('*resp* %s\n' % resp)        self.lastresp = resp[:3]        c = resp[:1]        if c == '4':            raise error_temp, resp        if c == '5':            raise error_perm, resp        if c not in '123':            raise error_proto, resp        return resp    def retrlines(self, cmd, callback = None):        def to_unicode(line):            if not isinstance(line, unicode):                try:                    line = unicode(line, self.charset)                except UnicodeDecodeError:                    pass            callback(line)                    if self.charset != None and callback != None:            FTP.retrlines(self, cmd, to_unicode)        else:            FTP.retrlines(self, cmd, callback)        return            def getwelcome(self):        return self.welcome    def connect(self, host = '', port = 0):        if host: self.host = host        if port: self.port = port        msg = "getaddrinfo returns an empty list"        for res in socket.getaddrinfo(self.host, self.port, 0, socket.SOCK_STREAM):            af, socktype, proto, canonname, sa = res            try:                self.sock = socket.socket(af, socktype, proto)                if self.timeout:                    self.sock.settimeout(self.timeout)                self.sock.connect(sa)            except socket.error, msg:                if self.sock:                    self.sock.close()                self.sock = None                continue            break        if not self.sock:            raise socket.error, msg        self.af = af        self.file = self.sock.makefile('rb')        self.welcome = self.getresp()        return self.welcome    def abort(self):        """The behaviou of abort method in Python's ftplib package is not        correct. Due to RFC 959, before sending ABOR command, an IP and        a Synch should send first, and ABOR should not send in urgent        mode.        Since usually ABOR and get/put command runned in different thread,        but when ABOR command is sent, a get/put reply and a abort reply        whould be returned in queue. So in order to made both of them        recieve reply correctly, ABOR should wait a while before reading        reply message, or all the reply message should read by one of them.        """        logging.debug('send IP')        self.sock.sendall(chr(255) + chr(244))        logging.debug('send Synch')        self.sock.sendall(chr(255) + chr(242), ftplib.MSG_OOB)                 line = 'ABOR'        if self.debugging > 1: print '*put urgent*', self.sanitize(line)        print '*cmd* ABOR'        logging.debug('send ABOR')        self.putline(line)        resp = None        while resp == None or resp[:3] != '226':            resp = self.getmultiline()            print resp        return    def on_timeout_change(self, config, id, entry, *args):        self.timeout = entry.value.get_int()        self.sock.settimeout(self.timeout)        returnclass FTPLibClient:    """FTPLibClient is an implementation of FTPClient using ftplib package    of Python."""    class DebugLogger:        """This class is used to write debug messages to log view. It has        a write function which can be used to write messages."""        charset = 'utf-8'                def __init__(self, client, updater):            self.client = client            self.updater = updater            self.line = ''        def write(self, s):            if not isinstance(s, unicode):                try:                    s = unicode(s, self.charset)                except UnicodeDecodeError:                    pass            gtk.idle_add(self.updater, s)        def flush(self):            gtk.idle_add(self.updater, self.line)        def set_charset(self, charset):            self.charset = charset    poll = None    monitor_thread = None    def __init__(self, ftp_engine):        self.ftp_engine = ftp_engine        self.config = ftp_engine.config        self.coralftp = ftp_engine.coralftp        self.sout = sys.stdout        self.logger = FTPLibClient.DebugLogger(self, ftp_engine.log_updater)        return    def __del__(self):        if self.input_hid:            self.stop_monitor()        return    def run(self):        "Start FTPClient."        self.ftp = AdvancedFTP()        self.ftp.set_logger(self.logger)        self.ftp.set_debuglevel(1)        self.ftp.timeout = config_value(            self.config, 'general', 'connect_timeout')        self.config.notify_add(config_key('general', 'connect_timeout'),                               self.ftp.on_timeout_change)        return    def interrupt(self):        "Send an abort messasge"                sys.stdout = self.logger        self.logger.write('*error* (soft abort)\n')        try:            self.ftp.abort()        except socket.timeout:            logging.debug('timeout')            pass        self.logger.write('*error* User Aborted\n')        sys.stdout = self.sout        return    def quit(self):        QuitCommand(self).execute()        self.monitor_thread.quit = True        return    def start_monitor(self):        """Monitor is used when nothing is being done. This is used to get        421 idle connection close inform."""        if self.poll == None:            self.poll = select.poll()            self.monitor_thread = MonitorThread(self)            self.monitor_thread.start()        self.poll.register(self.ftp.file.fileno(), select.POLLIN)        logging.debug('poll for ftp registered')        return    def stop_monitor(self):        if self.poll:            self.poll.unregister(self.ftp.file.fileno())            logging.debug('poll for ftp unregistered')        return        def new_command(self, cmd_type, *args):        if cmd_type == ftp_engine.CMD_QUIT:            return QuitCommand(self, *args)        elif cmd_type == ftp_engine.CMD_OPEN:            return OpenCommand(self, *args)        elif cmd_type == ftp_engine.CMD_CD:            return CdCommand(self, *args)        elif cmd_type == ftp_engine.CMD_LIST:            return ListCommand(self, *args)        elif cmd_type == ftp_engine.CMD_LISTD:            return ListdCommand(self, *args)        elif cmd_type == ftp_engine.CMD_PWD:            return PwdCommand(self, *args)        elif cmd_type == ftp_engine.CMD_PUT:            return PutCommand(self, *args)        elif cmd_type == ftp_engine.CMD_GET:            return GetCommand(self, *args)        elif cmd_type == ftp_engine.CMD_MKDIR:            return MkdirCommand(self, *args)        elif cmd_type == ftp_engine.CMD_DELETE:            return DeleteCommand(self, *args)        elif cmd_type == ftp_engine.CMD_MOVE:            return MoveCommand(self, *args)        elif cmd_type == ftp_engine.CMD_ABOR:            return AborCommand(self, *args)        elif cmd_type == ftp_engine.CMD_SIMPLE:            return SimpleCommand(self, *args)        else:            raise ValueError    def execute_command(self, command):        return command.execute()def safe_execute(logger, func, *args):    sout = sys.stdout    sys.stdout = logger    try:        try:            return func(*args)        finally:            sys.stdout = sout    except EOFError:        # EOFError is accured when abort transfer        logging.debug("EOFError")    except error_temp, resp:        logging.debug("TempError: %s" % resp.__str__())        raise FTPTempException(resp)    except error_perm, resp:        logging.debug("PermError: %s" % resp.__str__())        raise FTPPermException(resp)    except ftplib.Error, resp:        logging.debug(resp.__str__())        raise FTPException('000 ' + resp.__str__())    except socket.error, resp:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -