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

📄 ftp_engine.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 gobjectfrom gtk import idle_addimport logging, os, os.path, string, sys, thread, timefrom threading import Thread, Event, Timerfrom Queue import Queue, Emptyfrom ftplib_client import *#from lftp_client import *from ftp_exception import *from utils import *CMD_QUIT = 0CMD_OPEN = 1CMD_CD = 2CMD_LIST = 3CMD_LISTD = 4CMD_PWD = 5CMD_PUT = 6CMD_GET = 7CMD_MKDIR = 8CMD_CHOWN = 9CMD_CHMOD = 10CMD_DELETE = 11CMD_MOVE = 12CMD_ABOR = 13CMD_SIMPLE = 14STATUS_NONE = 0STATUS_CONNECTING = 1STATUS_IDLE = 2STATUS_RUNNING = 3STATUS_ABORT = 4ERRNO_ABORT = -1ERRNO_TIMEDOUT = -2class FTPEngine(gobject.GObject, Thread):    """    This is a control object for FTP task. All the FTP request from remote    view is sent to this object, this object will process them using real    ftp program wrapper one by one.        Every FTPEngine object has a is_idle Event object, when a request is    processed, the object is clear, all the following command should wait    until the previous command finished.    FTPEngine use a real ftp program(such as lftp) wrapper to process FTP    command, in all the cases it will wait until the FTP command return.    So FTPEngine has a thread to process FTP commands.    FTPEngine is also a sub-class of GObject class. When process of FTP    command finished, signals are emitted via gtk_idle.    """    __gsignals__ = {        'interrupted' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,)),        'idle' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,)),        'delay' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_INT,)),        'log-message':        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        'quit' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'idle-connection-closed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'open-succeeded' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'open-failed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        'welcome-message' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_STRING,)),        'list-succeeded' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'list-failed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        'listd-succeeded' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'listd-failed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        'pwd-succeeded' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'pwd-failed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        'cd-succeeded' :       (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'cd-failed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        'move-succeeded' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'move-failed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        'delete-succeeded' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'delete-failed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        'mkdir-succeeded' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'mkdir-failed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        'put-succeeded' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'put-failed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        'get-succeeded' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),        'get-failed' :        (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,         (gobject.TYPE_INT, gobject.TYPE_STRING)),        }    # the status of the ftp engine    status = None        # total_idle is idle time since last useful command    total_idle = 0        # Timer object for idle    idle_timer = None        # Timer object for delay    delay_timer = None    # If true, start/stop idle will change idle time and start/stop send of    # idle event, otherwise, only __is_idle event will be changed.    __change_idle = TRUE    # __queue_lock is used to make command_queue be visited on in one thread.    __queue_lock = None    # __command_queue is a place which is used to store ftp commands need    # processed. FTPEngine object will add command to the queue and FTPClient    # object fetch command from the queue.    # __command_queue can be visited in only one thread, and the access to    # it is restricted by __queue_lock    __command_queue = None    __welcome_message = None    def __init__(self, rview):        self.__gobject_init__()        Thread.__init__(self)        self.__remote_view = rview        self.__coralftp = rview.main_window.coralftp        self.__is_idle = Event()        self.__queue_lock = Event()        self.__quit_event = Event()        self.__ftp_client = FTPLibClient(self)        self.__command_queue = Queue(8)        self.__read_config()        self.status = STATUS_NONE    def __read_config(self):        config = self.config        self.connect_retry_delay = config_value(            config, 'general', 'connect_retry_delay')        self.connect_retry_count = config_value(            config, 'general', 'connect_retry_count')        self.send_keep_alive_command = config_value(            config, 'general', 'send_keep_alive_command')        self.keep_alive_command = config_value(            config, 'general', 'keep_alive_command')        self.send_keep_alive_interval = config_value(            config, 'general', 'send_keep_alive_interval')        self.stop_send_keep_alive = config_value(            config, 'general', 'stop_send_keep_alive')        self.stop_keep_alive_after = 60 * config_value(            config, 'general', 'stop_keep_alive_after')            def run(self):        self.__pid = thread.get_ident()        logging.debug('ftp thread start, pid is %d' % self.__pid)        self.__coralftp.register_thread('ftp')        self.__ftp_client.run()        self.__queue_lock.set()        self.__is_idle.set()        while not self.quit_event.isSet():            try:                func = args = change_idle = None                self.__queue_lock.wait()                func, args, change_idle = self.__command_queue.get(TRUE, 1)                logging.debug("ftp thread get new command %s, %s, %s" \                              % (func, args, change_idle))                if self.__is_idle.isSet():                    self.stop_idle(change_idle)                self.__result = func(*args)                if self.__command_queue.empty():                    self.start_idle(change_idle)            except Empty, e:                pass                    logging.debug('before emit quit')        idle_add(self.emit, 'quit')        logging.debug('ftp thread quit')        return    def __execute_in_thread(self, func, *args):        """This function make put the method into command queue, and make it        run in ftp thread."""        if not self.__queue_lock.isSet():            raise RuntimeError        self.__command_queue.put((func, args, self.__change_idle), TRUE)    def __getattr__(self, name):        if name == 'remote_view':            return self.__remote_view        elif name == 'is_idle_event':            return self.__is_idle        elif name == 'is_idle':            return self.status == STATUS_IDLE        elif name == 'quit_event':            return self.__quit_event        elif name == 'config':            return self.__remote_view.config        elif name == 'log_updater':            return self.__remote_view.main_window.log_view.updater        elif name == 'site_info':            return self.__site_info        elif name == 'welcome_message':            return self.__welcome_message        elif name == 'coralftp':            return self.__coralftp        else:            raise AttributeError, name    def do_idle_connection_closed(self):        self.status = STATUS_NONE        idle_add(self.quit)    def abort(self):        logging.debug("ftp_engine.abort runs in %s" \                      % self.__coralftp.get_thread_name())        if self.delay_timer:            self.delay_timer.cancel()            self.delay_timer = None            self.delayed = None        self.__queue_lock.clear()        while not self.__command_queue.empty():            self.__command_queue.get_nowait()        if self.status == STATUS_RUNNING:            self.status = STATUS_ABORT            try:                self.__ftp_client.interrupt()            except EOFError:                self.__queue_lock.set()                self.quit()        self.__queue_lock.set()     def quit(self):        logging.debug('quit command execute in %s' % \                      self.__coralftp.get_thread_name())        if not self.__is_idle.isSet():            self.abort()            self.__is_idle.wait()        self.__quit_event.set()        self.__change_idle = FALSE        # send ftp quit commnad        if self.status > STATUS_CONNECTING:            try:                self.__ftp_client.quit()            except FTPTempException, (errno, errmsg):                if errno == 421:                    pass                else:                    raise ValueError        self.status = STATUS_NONE        self.stop_idle(FALSE)        logging.debug('quit command finished')        return    def start_idle(self, change_idle, finished_event = None):        def idle():            if self.status == STATUS_IDLE:                self.total_idle = self.total_idle + 1                idle_add(self.emit, 'idle', self.total_idle)                self.idle_timer = Timer(1, idle)                self.idle_timer.start()            return        self.__is_idle.set()        if self.status > STATUS_CONNECTING:            self.__ftp_client.start_monitor()                if change_idle and self.status > STATUS_CONNECTING:            self.status = STATUS_IDLE            self.total_idle = 0            logging.debug('start idle')            self.idle_timer = Timer(1, idle)            self.idle_timer.start()        if finished_event != None:            finished_event.set()

⌨️ 快捷键说明

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