Python文件监听,SSH上传服务器

运行环境:

    本地:Window7 64位,Python 2.7.6,paramiko 1.12.1,watchdog 0.8.1

    远端:Ubuntu 14.04,Openssh-server


from auto_ssh_upload_paramiko import SSHFileUpload

auto_ssh_upload_paramiko 模块参看[这里]


dirs_handlers.py:

#!/usr/bin/python
# coding:utf8

import re
import logging
from watchdog.events import RegexMatchingEventHandler, PatternMatchingEventHandler
from pathtools.patterns import match_any_paths, match_path


class BaseRsyncEventHandler():
    """文件监听事件基础类
    """
    
    def __init__(self):
        logging.info("Rsync service started")

        
    def __del__(self):
        if self._ssh:
            self._ssh.close()
            logging.debug("ssh connection closed")

            
    def on_moved(self, event):
        """文件发生移动事件
        """
        remote_src_path = event.src_path.replace(self._local_path, self._remote_path).replace('\\', '/').replace('//', '/')
        remote_dest_path = event.dest_path.replace(self._local_path, self._remote_path).replace('\\', '/').replace('//', '/')

        self._ssh.exec_command("mv %s %s" % (remote_src_path, remote_dest_path))

        what = 'directory' if event.is_directory else 'file'
        logging.info("Moved %s: from %s to %s", what, event.src_path.replace('\\', '/').replace('//', '/'),
                     event.dest_path.replace('\\', '/').replace('//', '/'))

                     
    def on_created(self, event):
        """文件新建事件处理
        """
        local_path = event.src_path.replace('\\', '/').replace('//', '/')
        remote_path = event.src_path.replace(self._local_path, self._remote_path).replace('\\', '/').replace('//', '/')
        if event.is_directory: # 新建文件夹
            self._ssh.exec_command("mkdir -p %s" % remote_path)
        else: 
            self._ssh.copyFile(local_path, remote_path)

        what = 'directory' if event.is_directory else 'file'
        logging.info("Created %s: %s", what, event.src_path)

        
    def on_deleted(self, event):
        """文件删除事件处理
        """
        local_path = event.src_path.replace('\\', '/').replace('//', '/')
        remote_path = event.src_path.replace(self._local_path, self._remote_path).replace('\\', '/').replace('//', '/')
        
        self._ssh.exec_command("rm -f %s" % remote_path)    

        what = 'directory' if event.is_directory else 'file'
        logging.info("Deleted %s: %s", what, event.src_path.replace('\\', '/').replace('//', '/'))

        
    def on_modified(self, event):
        """文件修改事件处理
        """
        if not event.is_directory:
            local_path = event.src_path.replace('\\', '/').replace('//', '/')
            remote_path = event.src_path.replace(self._local_path, self._remote_path).replace('\\', '/').replace('//', '/')
            self._ssh.copyFile(local_path, remote_path)

        what = 'directory' if event.is_directory else 'file'
        logging.info("Modified %s: %s", what, event.src_path.replace('\\', '/').replace('//', '/'))


def ignoreRegexesFilter(ignore_regexes, case_sensitive=False):
    """正则表达式匹配, 忽略监听特定文件
    """
    
    _ignore_regexes = []
    if case_sensitive:
        _ignore_regexes = [re.compile(r) for r in ignore_regexes]
    else:
        _ignore_regexes = [re.compile(r, re.I) for r in ignore_regexes]

    def wapper(file_path):
        if any(r.match(file_path) for r in _ignore_regexes):
            return False
        return True
    return wapper

    
class RsyncRegexMatchingEventHandler(BaseRsyncEventHandler, RegexMatchingEventHandler):
    """正则表达式匹配, 文件同步处理类
    """
    
    def __init__(self, ssh, local_path, remote_path, regexes=[r".*"], ignore_regexes=[],
                 ignore_directories=False, case_sensitive=False):
        RegexMatchingEventHandler.__init__(self, regexes, ignore_regexes,
                 ignore_directories, case_sensitive)        
        if not ssh:
            raise ValueError('ssh argument should NOT be null')

        self._ssh = ssh
        self._ssh.connect()

        self._local_path = local_path
        self._remote_path = remote_path
        self._ssh.copyDir(local_path, remote_path, filters=[ignoreRegexesFilter(ignore_regexes)])

        BaseRsyncEventHandler.__init__(self)


def ignorePatternsFilter(ignore_patterns, case_sensitive=False):
    def wapper(file_path):
        return match_any_paths(file_path,included_patterns=None,
                           excluded_patterns=set(ignore_patterns),
                           case_sensitive=case_sensitive)
    return wapper


class RsyncPatternMatchingEventHandler(BaseRsyncEventHandler, PatternMatchingEventHandler):

    def __init__(self, ssh, local_path, remote_path, patterns=None, ignore_patterns=None,
                 ignore_directories=False, case_sensitive=False):
        if not ssh:
            raise ValueError('ssh argument should NOT be null')

        self._ssh = ssh
        self._ssh.connect()

        self._local_path = local_path
        self._remote_path = remote_path
        # self._ssh.copyDir(local_path, remote_path, filters=[ignorePatternsFilter(ignore_patterns)])

        PatternMatchingEventHandler.__init__(self, patterns, ignore_patterns,
                 ignore_directories, case_sensitive)        
        BaseRsyncEventHandler.__init__(self)



#!/usr/bin/python
# coding:utf8

import os
import os.path
import re
import sys
import time
import logging
from logging.handlers import TimedRotatingFileHandler
from ConfigParser import SafeConfigParser
from pathtools.patterns import match_any_paths
from watchdog.observers import Observer

from auto_ssh_upload_paramiko import SSHFileUpload
from dirs_handlers import RsyncRegexMatchingEventHandler, RsyncPatternMatchingEventHandler


def getSSHConfig(section_name='env', conf_file='ssh-config.ini'):
    config = SafeConfigParser()
    config.readfp(open(conf_file))
    return dict(config.items(section_name))

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

_logLevelNames = {
    CRITICAL : 'CRITICAL',
    ERROR : 'ERROR',
    WARNING : 'WARNING',
    INFO : 'INFO',
    DEBUG : 'DEBUG',
    NOTSET : 'NOTSET',
    'CRITICAL' : CRITICAL,
    'ERROR' : ERROR,
    'WARN' : WARNING,
    'WARNING' : WARNING,
    'INFO' : INFO,
    'DEBUG' : DEBUG,
    'NOTSET' : NOTSET,
}

if __name__ == "__main__":
    config = getSSHConfig("env")
    log_path = config.get('log_path').replace('\\', '/').replace('//', '/')
    log_level = config.get('log_level')

    if not log_level: 
        log_level = _logLevelNames['INFO']

    formatter='%(asctime)s - %(message)s'
    datefmt='%Y-%m-%d %H:%M:%S'
    logging.basicConfig(
                        level=_logLevelNames[log_level]
                        ,format=formatter
                        ,datefmt=datefmt
                        # ,filename=log_path
                        # ,filemode='a'
                        )

    fmt = logging.Formatter(formatter)
    log_handler = TimedRotatingFileHandler(log_path, when='D', interval=1, backupCount=40)
    log_handler.setLevel(logging.INFO)
    log_handler.suffix = r"%Y%m%d-%H%M.log"
    log_handler.setFormatter(fmt)
    logging.getLogger().addHandler(log_handler)

    host = config.get('host')
    port = int(config.get('port'))
    username = config.get('username')
    password = config.get('password')
    
    local_path =  config.get('local_path')
    remote_path = config.get('remote_path')
    
    ssh = SSHFileUpload(host, port, username, password)

 
    with open("./ignoreregexes") as f:
        ignoreregexes = [unicode(line.strip('\n'), 'cp936').encode('utf8') for line in f.readlines() if line.strip('\n')]

    event_handler = RsyncRegexMatchingEventHandler(ssh, local_path, remote_path, 
        ignore_regexes=ignoreregexes #[r".*\.tmp$", r".*\.git.*", r".*\.settings.*", r".*\.project.*", r".*\.buildpath.*", r".*\.idea.*", r".*___jb_.*"]
        )
    observer = Observer()
    observer.schedule(event_handler, local_path, recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()


配置文件(ssh-config.ini):

[env]
host=192.168.88.128
port=22
username=root
password=your_passwd
local_path=E:/app
remote_path=/home/app
log_path=./dirs-rsync.log


ignoreregexes文件文本内容:

.*\.tmp$
.*\.git.*
.*\.settings.*
.*\.project.*
.*\.buildpath.*

.*\.idea.*

.*___jb_.*





转载于:https://my.oschina.net/dexterman/blog/310571

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值