Django 项目中 pyftpdlib 快速搭建 FTP 服务器,动态增量添加 ftp 用户



django 中启动 ftp 服务


#ftpServer.py
import os
from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer, MultiprocessFTPServer, ThreadedFTPServer
from django.core.management import BaseCommand

class Command(BaseCommand):
    def handle(self, *args, **options):
        """
        实现主要逻辑,启动ftp服务
        :param args:
        :param options:
        :return:
        """
        authorizer = DummyAuthorizer()
        handler = MyHandler
        handler.authorizer = authorizer
        ftp_server(authorizer)
        # server = FTPServer(("0.0.0.0", 2121), handler)
        # server = MultiprocessFTPServer(("0.0.0.0", 2121), handler)
        server = ThreadedFTPServer((FTP_IP, FTP_POST), handler)
        server.serve_forever()


1. 文件存放路径:apps/<app>/management/commands/ftpServer.py

2. 启动 ftp 服务命令:python manage.py ftpServer


接下来实现动态添加 ftp 用户的功能


user_cfg_path = os.path.join(BASE_DIR + '/apps/ftpUser.cfg')
class MyHandler(FTPHandler):
    """
    回调方法
    """
    def on_connect(self):  # 链接时调用
        ftp_server(self.authorizer)
        print("%s:%s connected" % (self.remote_ip, self.remote_port))


def get_user(userfile):
    # 定义一个用户列表
    user_list = []
    with open(userfile) as f:
        for line in f:
            if not line.startswith('#') and line:
                if len(line.split()) == 6:
                    # print(line.split())
                    user_list.append(line.split())
                else:
                    print("user.conf配置错误")
    return user_list


def ftp_server(authorizer):
    # 添加用户权限和路径,括号内的参数是(用户名, 密码, 用户目录, 权限)
    # authorizer.add_user('user', '12345', '/home/', perm='elradfmw')
    user_list = get_user(user_cfg_path)
    for user in user_list:
        name, passwd, permit, homedir, date, time = user
        try:
            authorizer.add_user(name, passwd, homedir, perm=permit)
        except Exception as e:
            print(e)

class Command(BaseCommand):
    def handle(self, *args, **options):
        """
        实现主要逻辑,启动ftp服务
        :param args:
        :param options:
        :return:
        """
        authorizer = DummyAuthorizer()
        handler = MyHandler
        handler.authorizer = authorizer
        ftp_server(authorizer)
        # server = FTPServer(("0.0.0.0", 2121), handler)
        # server = MultiprocessFTPServer(("0.0.0.0", 2121), handler)
        server = ThreadedFTPServer((FTP_IP, FTP_POST), handler)
        server.serve_forever()


实现原理:每当用户连接ftp服务端的时候,就会调用回调方法,重新读取存储用户的配置文件,实现动态

至于动态添加用户,就需要,操作这个存储用户信息的配置文件了


操作这个存储用户信息的配置文件


1. 贴一下我的配置文件 :用户名     密码     操作权限(只有下载)    访问文件的路径      添加用户的时间

#ftpUser.cfg
7@7.com  SNFSTP  elr  /Users/cagey/gitlib_projects/test/PTM_backend/upload/files/7@7.com  2019-08-01 17:49:03.727385
1@1.com  P4X4R1  elr  /Users/cagey/gitlib_projects/test/PTM_backend/upload/files/1@1.com  2019-08-01 17:48:40
2@2.com  PYUVTN  elr  /Users/cagey/gitlib_projects/test/PTM_backend/upload/files/  2019-07-26 16:52:45
cagey7@163.com  BB1IVP  elr  /Users/cagey/gitlib_projects/test/PTM_backend/upload/files/  2019-07-26 16:05:48
admin  123  elradfmwMT  /Users/cagey/gitlib_projects/test/PTM_backend/upload/files/  2019-07-26 15:54:00


2. 具体的方法

def get_ftp_user(username):
    """
    获取用户ftp配置信息
    :param username: cagey7@163.com
    :return: ['cagey7@163.com', 'JG14CD', 'elr', '/Users/cagey/gitlib_projects/tool/new/PTM_backend/upload/files/']
    """
    name = username
    with open(user_cfg_path) as f:
        for line in f:
            if line.startswith(name):
                if len(line.split()) == 6:
                    return line.split()
                else:
                    return "user.conf配置错误!"
        return None

def del_ftp_user(username):
    """
    删除ftp用户
    :param username:
    :return:
    """
    with open(user_cfg_path, 'r') as r:
        lines = r.readlines()
    with open(user_cfg_path, 'w') as w:
        for l in lines:
            if not l.startswith(username):
                w.write(l)

def add_ftp_user(user_info):
    """
    添加,更新ftp用户
    :param user_info:
    :return:
    """
    with open(user_cfg_path, 'r') as fp:
        lines = []
        for line in fp:
            lines.append(line)
    with open(user_cfg_path, 'w') as fp:
        lines.insert(0, str(user_info) + '\n')  # 在第一行插入
        s = ''.join(lines)
        fp.write(s)

def random_code():
    # 生成随机6位随机数含字母
    code = []
    for i in range(6):
        if i == random.randint(1, 5):
            code.append(str(random.randint(1, 5)))
        else:
            code.append(chr(random.randint(65, 90)))
    return ''.join(code)

其他的功能可以根据自己的具体业务需求实现,详细的 pyftpdlib 配置我就不介绍了,网上很多


References

https://blog.csdn.net/Cagey77/article/details/98176175