基于Python搭建局域網(wǎng)大文件分享傳輸工具
1.簡介
由于單位不讓用優(yōu)盤、禁止用飛秋、也不準(zhǔn)使共享,禁用FTP,也禁止搭建網(wǎng)站,且目前局域網(wǎng)內(nèi)用的IM不支持1G以上文件傳輸,于是在找適合內(nèi)網(wǎng)的大文件傳輸方法。開始搭建網(wǎng)盤,但上傳一次、下載一次,效率還是有點低。后來用Everything的HTTP服務(wù)器,結(jié)果把整個硬盤都分享了,太不安全。于是就自己做了這個簡單的文件分享工具。資源已打包可自行下載。
HTTP分享,利用Flask搭建了一個Web服務(wù)器,選擇要分享的文件啟動后,將生成的鏈接發(fā)給對方,對方就可以通過瀏覽器下載。
FTP分享用pyftpdlib搭建了一個FTP服務(wù)器,同樣生成鏈接后,對方可以通過一些瀏覽器或FTP客戶端下載,也可以通過程序提供的工具下載文件。
2.運行效果
3.相關(guān)源碼
from PyQt5.QtWidgets import QApplication, QRadioButton, QMainWindow, QLabel, QComboBox, QLineEdit, QPushButton, QMessageBox, QToolButton, QFileDialog, QDialog from PyQt5.QtCore import QDir, Qt, QThread, pyqtSignal from PyQt5 import QtGui, QtCore, QtWidgets from PyQt5.QtGui import QIcon,QFont import sys import os import random import netifaces from flask import Flask, send_file from concurrent.futures import ThreadPoolExecutor from pyftpdlib.authorizers import DummyAuthorizer from pyftpdlib.handlers import FTPHandler from pyftpdlib.servers import ThreadedFTPServer from ftplib import FTP from urllib.parse import urlparse class HelpWindow(QDialog): def __init__(self): super().__init__() self.setWindowTitle("幫助") self.setFixedSize(300, 280) self.center() self.setWindowFlags(Qt.WindowCloseButtonHint | Qt.WindowTitleHint) self.label = QLabel(self) self.label.setText("1、選擇文件傳輸協(xié)議;2、輸入端口號(建議10000~60000,一般默認(rèn)即可); \ 3、選擇文件所在目錄;4、選擇要分享的文件;5、點擊啟動按鈕,\ 若防火墻彈出警示點擊允許訪問即可;6、將生成的鏈接復(fù)制發(fā)送給接收方, \ 接收方通過瀏覽器訪問即可下載。若通過FTP協(xié)議分享還可通過FTP客戶端軟件 \ 或本程序的“接收FTP文件”按鈕下載。注意:傳輸完成后請及時關(guān)閉程序, \ 以免造成數(shù)據(jù)泄露和網(wǎng)絡(luò)安全隱患。") self.label.setGeometry(10, 10, 280, 260) self.label.setWordWrap(True) font = QFont() font.setPointSize(10) font.setBold(True) self.label.setFont(font) def center(self): screen = QApplication.desktop().screenGeometry() window = self.geometry() x = (screen.width() - window.width()) // 2 y = (screen.height() - window.height()) // 2 self.move(x, y) class DownloadThread(QThread): finished = pyqtSignal(bool) ftp = FTP() def __init__(self, ftp_url): super().__init__() self.ftp_url = ftp_url def run(self): parsed_url = urlparse(self.ftp_url) username = parsed_url.username password = parsed_url.password host = parsed_url.hostname port = parsed_url.port filename = parsed_url.path.rsplit('/', 1)[-1] if len(filename)==0: downloadfile = False else: downloadfile = True try: self.ftp.connect(host, port) self.ftp.encoding = 'utf-8' self.ftp.login(user=username, passwd=password) current_dir = os.getcwd() current_dir = current_dir.replace("\\", "/") random_int = random.randint(100, 999) mulu = "接收文件_" + str(random_int) LocalDir = current_dir + "/" + mulu if not os.path.exists(LocalDir): os.makedirs(LocalDir) if downloadfile:#下載一個文件 Local = os.path.join(LocalDir, filename) self.DownLoadFile(Local,filename) else:#下載整個目錄 self.DownLoadFileTree(LocalDir,"/") self.ftp.quit() self.finished.emit(True) except Exception as e: self.finished.emit(False) def DownLoadFile(self, LocalFile, RemoteFile): # 下載單個文件 with open(LocalFile, 'wb') as file_handler: self.ftp.retrbinary('RETR ' + RemoteFile, file_handler.write) file_handler.close() return True def DownLoadFileTree(self, LocalDir, RemoteDir): # 下載整個目錄下的文件 print("遠程文件夾remoteDir:", RemoteDir) if not os.path.exists(LocalDir): os.makedirs(LocalDir) self.ftp.cwd(RemoteDir) RemoteNames = self.ftp.nlst() print("遠程文件目錄:", RemoteNames) for file in RemoteNames: Local = os.path.join(LocalDir, file) #print("正在下載", self.ftp.nlst(file)) try: self.ftp.cwd(file) self.ftp.cwd("..") if not os.path.exists(Local): os.makedirs(Local) self.DownLoadFileTree(Local, file) except: self.DownLoadFile(Local, file) self.ftp.cwd("..") return class FTPWindow(QDialog): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("下載FTP文件") self.setFixedSize(400, 150) self.label_ftp_url = QLabel("FTP鏈接:", self) self.label_ftp_url.setGeometry(20, 20, 80, 30) self.textbox_ftp_url = QLineEdit(self) self.textbox_ftp_url.setGeometry(100, 20, 280, 30) self.button_download = QPushButton("下載", self) self.button_download.setGeometry(160, 65, 80, 30) self.button_download.clicked.connect(self.download_ftp_file) self.label_ftp_info = QLabel("輸入包含文件名的鏈接下載指定文件;\n輸入不包含文件名只到端口號的鏈接下載整個目錄。", self) self.label_ftp_info.setGeometry(20, 110, 380, 40) def download_ftp_file(self): ftp_url = self.textbox_ftp_url.text() if ftp_url == "": return self.button_download.setEnabled(False) self.thread = DownloadThread(ftp_url) self.thread.finished.connect(self.show_message_box) self.thread.start() def show_message_box(self, success): if success: QMessageBox.information(self, "提示", "文件下載成功!", QMessageBox.Ok) else: QMessageBox.critical(self, "錯誤", "文件下載失?。?, QMessageBox.Ok) self.button_download.setEnabled(True) class MyWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("文件分享") self.setWindowIcon(QIcon('icon.ico')) self.setMaximumSize(self.size()) self.setFixedSize(400, 300) self.tcp_label = QLabel('選擇傳輸方式:', self) self.tcp_label.move(20, 10) self.http_button = QRadioButton('HTTP', self) self.http_button.setChecked(True) self.http_button.move(150, 10) self.http_button.toggled.connect(self.onProtocolChanged) self.ftp_button = QRadioButton('FTP', self) self.ftp_button.move(250, 10) self.ftp_button.toggled.connect(self.onProtocolChanged) self.ip_label = QLabel('當(dāng)前IP地址:', self) self.ip_label.move(20, 40) self.ip_text = QLabel(self.get_wired_ip(), self) self.ip_text.setGeometry(120, 43, 250, 25) self.port_label = QLabel('端 口 :', self) self.port_label.move(20, 75) self.textbox = QLineEdit(self) self.textbox.setGeometry(80, 75, 300, 30) self.textbox.setValidator(QtGui.QIntValidator(10000, 65500)) self.textbox.setText(str(random.randint(10000, 65500))) self.folder_label = QLabel('文件夾:', self) self.folder_label.setGeometry(20, 115, 50, 30) self.textfol = QLineEdit(self) self.textfol.setGeometry(80, 115, 220, 30) self.textfol.setText(QDir.currentPath()) self.textfol.setReadOnly(True) self.folder_button = QPushButton('選擇文件夾', self) self.folder_button.setGeometry(300, 115, 80, 30) self.folder_button.clicked.connect(self.onFolderClicked) self.file_label = QLabel('文 件 :', self) self.file_label.setGeometry(20, 155, 50, 30) self.combobox = QComboBox(self) self.combobox.setGeometry(80, 155, 300, 30) self.updateFileList() self.updateFileList() self.button = QPushButton(self) self.button.setText("啟 動") self.button.setGeometry(20, 195, 360, 30) self.button.clicked.connect(self.show_selection) self.textboxa = QLineEdit(self) self.textboxa.setGeometry(20, 235, 360, 30) self.textboxa.mousePressEvent = self.select_text self.hidden_button = QPushButton("接收\nFTP\n文件", self) self.hidden_button.setVisible(False) self.hidden_button.setGeometry(320, 10, 60, 55) self.hidden_button.clicked.connect(self.show_ftp_window) self.labela = QLabel(self) self.labela.setText("@hvinsion") self.labela.setGeometry(320, 280, 360, 20) self.labelb = QPushButton(self) self.labelb.setText("說明") self.labelb.setToolTip("幫助") self.labelb.setGeometry(10, self.height() - 30, 30, 30) self.labelb.clicked.connect(self.open_help_window) self.help_window = HelpWindow() self.thread_pool = ThreadPoolExecutor(max_workers=5) def open_help_window(self): self.help_window.show() def select_text(self, event): self.textboxa.selectAll() self.textboxa.setFocus() def show_ftp_window(self): ftp_window = FTPWindow(self) ftp_window.exec_() def onProtocolChanged(self): if self.ftp_button.isChecked(): self.hidden_button.setVisible(True) else: self.hidden_button.setVisible(False) def onFolderClicked(self): m = QFileDialog.getExistingDirectory(self, "選取文件夾", QDir.currentPath()) self.textfol.setText(m) self.updateFileList() def updateFileList(self): folder_path = self.textfol.text() file_list = QDir(folder_path).entryList(QDir.Files) self.combobox.clear() self.combobox.addItems(file_list) def get_wired_ip(self): try: default_gateway = netifaces.gateways()['default'] if default_gateway and netifaces.AF_INET in default_gateway: routingNicName = default_gateway[netifaces.AF_INET][1] for interface in netifaces.interfaces(): if interface == routingNicName: routingIPAddr = netifaces.ifaddresses(interface).get(netifaces.AF_INET) if routingIPAddr: return routingIPAddr[0]['addr'] except (KeyError, IndexError): pass return "未找到物理網(wǎng)卡IP" def start_flask_server(self): app = Flask(__name__) @app.route('/download/<filename>', methods=['GET']) def download_file(filename): file_path = os.path.join(self.textfol.text(), filename) return send_file(file_path, as_attachment=True) port = int(self.textbox.text()) self.textbox.setText(str(random.randint(10000, 65500))) app.run(host='0.0.0.0', port=port, threaded=True) def start_ftp_server(self): authorizer = DummyAuthorizer() authorizer.add_user('a', 'a', self.textfol.text(), perm='elradfmwM') class CustomFTPHandler(FTPHandler): def on_file_received(self, file): pass def on_file_deleted(self, file): pass def on_rename(self, old_file, new_file): pass handler = CustomFTPHandler handler.authorizer = authorizer address = ('0.0.0.0', int(self.textbox.text())) server = ThreadedFTPServer(address, handler) self.thread_pool.submit(server.serve_forever) self.textbox.setText(str(random.randint(10000, 65500))) def show_selection(self): ip_address = self.get_wired_ip() port_text = self.textbox.text() if int(port_text)<10000: QMessageBox.critical(self, "警告", "請勿使用10000以下端口號!", QMessageBox.Ok) self.textbox.setText(str(random.randint(10000, 65500))) return selected_file = self.combobox.currentText() if self.http_button.isChecked(): self.thread_pool.submit(self.start_flask_server) self.textboxa.setText("http://" + ip_address + ":" + port_text + "/download/" + selected_file) elif self.ftp_button.isChecked(): self.thread_pool.submit(self.start_ftp_server) self.textboxa.setText("ftp://a:a@" + ip_address + ":" + port_text + "/" + selected_file) else: QMessageBox.warning(self, "警告", "請選擇傳輸方式!", QMessageBox.Ok) if __name__ == "__main__": app = QApplication(sys.argv) win = MyWindow() win.show() sys.exit(app.exec_())
到此這篇關(guān)于基于Python搭建局域網(wǎng)大文件分享傳輸工具的文章就介紹到這了,更多相關(guān)Python大文件傳輸內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python發(fā)qq消息轟炸虐狗好友思路詳解(完整代碼)
因為我的某個好友在情人節(jié)的時候秀恩愛,所以我靈光一閃制作了qq消息轟炸并記錄了下來。本文給大家分享python發(fā)qq消息轟炸虐狗好友思路詳解,感興趣的朋友一起看看吧2020-02-02使用python matploblib庫繪制準(zhǔn)確率,損失率折線圖
這篇文章主要介紹了使用python matploblib庫繪制準(zhǔn)確率,損失率折線圖,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06python+excel接口自動化獲取token并作為請求參數(shù)進行傳參操作
這篇文章主要介紹了python+excel接口自動化獲取token并作為請求參數(shù)進行傳參操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11Python多進程池 multiprocessing Pool用法示例
這篇文章主要介紹了Python多進程池 multiprocessing Pool用法,結(jié)合實例形式分析了多進程池 multiprocessing Pool相關(guān)概念、原理及簡單使用技巧,需要的朋友可以參考下2018-09-09