Development background:
Sometimes need to transfer files in the LAN, always use a USB drive, if more people need the same file, the U disk is a bit troublesome, the file sharing configuration on Windows is very small, but often because of various reasons for failure, but also check to check. So consider the FTP protocol to transfer files, but the famous FTP server software similar to serv-u this, the function is very powerful, but a lot of configuration, I just temporarily transfer the next file, I hope you can free installation, a key to start FTP, a button to close the FTP. So you want to use Python to implement the FTP server, and then packaged into EXE files.
Development environment:
Win 7 64-bit, Python 3.6.2,pyftpdlib,wxpython,pyinstaller 3.3.1
Specific ideas:
FTP via Pyftpdlib Library function ftpserver.py, use Wxpython to implement GUI interface wxgui.py, generate configuration file config.ini,ftpserver.py on wxgui.py and get information from Config.ini start FTP, finally use Pyinstaller to package EXE executable file.
Software:
However, just developed good software, there should be a lot of bugs, and then gradually improve the use of the process.
To open the software:
Select the FTP directory:
To start ftp:
Specific source code:
Implement the FTP function code ftpserver.py:
# coding:utf-8from pyftpdlib.authorizers Import dummyauthorizerfrom pyftpdlib.handlers import Ftphandlerfrom Pyftpdlib.servers import ftpserverimport loggingimport configparserimport osdef ftpd (): Authorizer = DummyAuthorizer () If GetConfig (' anonymous ') = = ' True ': #添加匿名用户 authorizer.add_anonymous (GetConfig (' dir '), perm= ' ELRADFMWM ') else: #添加用户, require account and password login authorizer.add_user (getconfig (' user '), getconfig (' password '), GetConfig (' dir '), p erm= ' ELRADFMWM ') handler = ftphandler# Initializes the class that handles the client command Handler.authorizer = authorizer# Select the Login method (whether anonymous) logging.basicconf IG (filename= ' Ftpd.log ', level=logging.info) #日志信息写入ftpd. Log address = (' 0.0.0.0 ', GetConfig (' Port ')) #设置服务器的监听地址和端口 s Erver = Ftpserver (address, handler) Server.max_cons = #给链接设置限制 Server.max_cons_per_ IP = 5 server.serve_forever () # start Ftpdef getconfig (v): #获取config. ini configuration file Information config = Configparser. Configparser () config. Read (' Config.ini ') return Config.get (' ftpd ', v) if __name__ = = ' __main__ ': ftpd ()
Implementing GUI Interface code wxgui.py:
#-*-Coding:utf-8-*-import wximport osimport sysimport configparserimport ftpserverimport timeimport threadingimport so Cketdef onclick (event): #选择FTP目录 dlg=wx. Dirdialog (window, ' Select shared directory ') if dlg. ShowModal () = = Wx.ID_OK:dirtext. SetValue (dlg. GetPath ()) def onclose (event): #退出事件 if Startbutton. Getlabel () = = ' Close ftp ': Dlg1 = wx. Messagedialog (None, "FTP is running, confirm exiting?") "," Exit ", WX. Yes_no | Wx. icon_exclamation) if Dlg1. ShowModal () ==wx.id_yes:sys.exit () else:sys.exit () def startftp (event): #点击 Start FTP button event global t If Startbutton. Getlabel () = = ' Start ftp ': Startbutton. SetLabel (' Close ftp ') #把FTP启动信息写入config the. ini configuration file in Config=configparser. Configparser () config.add_section (' ftpd ') config.set (' ftpd ', ' Anonymous ', str (not check. GetValue ())) Config.set (' ftpd ', ' user ', Usertext. GetValue ()) config.set (' ftpd ', ' Password ', Passtext. GetValue ()) config.set (' ftpd ', ' Port ', Porttext. GetValue ()) config.set (' ftpd ', ' diR ', Dirtext. GetValue ()) with open (' Config.ini ', ' W ') as Conf:config.write (conf) time.sleep (1) #创建线程启动F TP t=threading. Thread (TARGET=FTPSERVER.FTPD) T.setdaemon (True) T.start () iplist=socket.gethostbyname_ex (sock Et.gethostname ()) [2] ftpurl= "If iplist:for IP in iplist:ftpurl+= ' FTP address: ftp:// ' +ip+ ': ' +porttext. GetValue () + ' \ n ' URLLabel. SetLabel (ftpurl) Else:dlg1 = wx. Messagedialog (None, "FTP is running, confirm exiting?") "," Exit ", WX. Yes_no | Wx. icon_exclamation) if Dlg1. ShowModal () ==wx.id_yes:sys.exit () def onchecked (event): #复选框事件 Usertext. Seteditable (event. IsChecked ()) Passtext. Seteditable (event. IsChecked ()) app = Wx. APP () #实例化wx. app# creates a top-level window, and the window cannot be changed to size Windows = WX. Frame (none,title = "ftp Server", size = (390, 260), pos= (400,300), style=wx. Default_frame_style ^ Wx. Resize_border ^ Wx. Maximize_box) #绑定退出事件window. Bind (WX. Evt_close,onclose) #创建panelpanel = wx. Panel (window) font = wx. Font (one, WX. SWISS, WX. NORMAL, WX. NORMAL) #创建复选框 and bind the event check=wx. CheckBox (panel,-1, ' Login with account password ', pos= (20,20), size= (200,-1)) check. SetFont (font) window. Bind (WX. evt_checkbox,onchecked) #创建静态文本和文本输入框userlabel = wx. Statictext (panel, label = "User name:", pos= (35,45)) Userlabel. SetFont (font) Usertext = wx. Textctrl (Panel,-1, ", size= (95,20), pos= (90,42), style = wx.te_readonly) Passlabel = wx. Statictext (panel, label = "Password:", pos= (195,45)) Passlabel. SetFont (font) Passtext = wx. Textctrl (Panel,-1, ", size= (95,20), pos= (235,42), style = Wx.te_password) passtext. Seteditable (False) Dirlabel = wx. Statictext (panel, label = "FTP directory:", pos= (23,72)) Dirlabel. SetFont (font) Dirtext = wx. Textctrl (PANEL,-1,OS.GETCWD (), size= (215,20), pos= (88,70), style = Wx.te_readonly) #创建按钮, and Bind button event button=wx. button (panel,-1, ' Change ', pos= (310,70), size= (40,20)) button. SetFont (WX. Font (9, WX. SWISS, WX. NORMAL, WX. NORMAL)) window. Bind (WX. Evt_button,onclick,button) Portlabel = wx. Statictext (panel, label = "FTP port:", pos= (23,104)) Portlabel. SetFont (font) Porttext = wx.Textctrl (panel,-1, ' + ', size= (51,20), pos= (88,102)) startbutton=wx. Button (panel,-1, ' Start ftp ', pos= (160,130), size= (70,30)) Startbutton. SetFont (WX. Font (WX. SWISS, WX. NORMAL, WX. NORMAL)) window. Bind (WX. Evt_button,startftp,startbutton) #加载配置文件, which restores the program to the interface before exiting if Os.path.isfile (' Config.ini '): If Ftpserver.getconfig (' Anonymous ') = = ' False ': check. SetValue (1) usertext. Seteditable (1) passtext. Seteditable (1) usertext. SetValue (ftpserver.getconfig (' user ')) passtext. SetValue (ftpserver.getconfig (' password ')) Porttext. SetValue (Ftpserver.getconfig (' Port ')) Dirtext. SetValue (Ftpserver.getconfig (' dir ')) URLLabel = WX. Statictext (panel, label = "", pos= ()) URLLabel. SetFont (font) window. Show (True) #窗口可见app. Mainloop () #主循环, handling events
Packaging with Pyinstaller
If it goes well, the two orders can be packed successfully, but I'm not going to be so smooth.
PIP Installation Pyinstaller
Pip Install Pyinstaller
Start Packing:
Pyinstaller-f wxgui.py-w
-F parameter: is to generate a single executable file
-W parameter: Because I am a GUI program, I use this parameter to remove the command line window
Generated files:
Summary of issues:
The development of this small project encountered a problem, Baidu Google can not find a solution.
The program creates a thread to start the FTP service, and when I want to stop the FTP service, how do I stop the FTP service without exiting the program?
Python implementation of FTP server (using Wxpython to implement GUI interface)