You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从internetarchive.upload函数获取已上传字节数?

在PyQt5中实现Archive.org文件上传进度条

我需要将本地文件上传到archive.org,已经用internetarchive模块实现了控制台上传,现在要做PyQt5图形界面简化流程,但缺少进度条体验不好。加verbose=True后控制台会显示tqdm进度条,但无法在GUI中展示,核心需求是获取已上传字节数/文件进度来实现GUI进度条。

尝试的代码

from internetarchive import configure, get_item, upload, get_files
from string import ascii_letters, digits
from random import choices
from time import sleep

def get_indentifier(l=20):
    while 1:
        identifier = ''.join(choices(ascii_letters + digits, k=l))
        if not get_item(identifier).exists:
            return identifier

def upload_callback(*args, **kwargs):
    print(args, kwargs)

configure('email', 'password')
print('Logged in')

identifier = get_indentifier()

print('Uploading...')
upload(identifier, ['file-sm.zip'], verbose=True)
print('Uploaded')

print('Proccessing...')

found = False
while not found:
    sleep(5)
    files = [i for i in get_files(identifier, ['file-sm.zip'])]
    found = bool(files)

print('Done!')
print('URL:', files[0].url)

问题

运行后控制台能看到tqdm进度条,但无法将进度数据同步到PyQt5界面。


解决方案

internetarchive的upload函数支持callback参数,可以自定义回调函数获取实时上传进度,结合PyQt5的信号槽机制更新进度条,同时要把上传操作放到子线程避免阻塞GUI。

完整实现代码

from internetarchive import configure, get_item, upload, get_files
from string import ascii_letters, digits
from random import choices
from PyQt5.QtWidgets import (QApplication, QMainWindow, QProgressBar, 
                             QPushButton, QVBoxLayout, QWidget)
from PyQt5.QtCore import QThread, pyqtSignal
import sys
from time import sleep

def get_identifier(l=20):
    while True:
        identifier = ''.join(choices(ascii_letters + digits, k=l))
        if not get_item(identifier).exists:
            return identifier

class UploadThread(QThread):
    # 定义信号:更新进度、上传完成
    progress_updated = pyqtSignal(int)
    upload_finished = pyqtSignal(str)

    def __init__(self, file_path):
        super().__init__()
        self.file_path = file_path
        self.identifier = get_identifier()

    def upload_callback(self, chunk_bytes, total_bytes, **kwargs):
        # 计算进度百分比并发送信号
        progress = int((chunk_bytes / total_bytes) * 100)
        self.progress_updated.emit(progress)

    def run(self):
        # 配置登录信息
        configure('your_email@example.com', 'your_password')
        # 上传文件,传入自定义回调
        upload(self.identifier, [self.file_path], callback=self.upload_callback)
        # 等待文件处理完成并获取URL
        found = False
        while not found:
            sleep(5)
            files = list(get_files(self.identifier, [self.file_path]))
            found = bool(files)
        self.upload_finished.emit(files[0].url)

class UploadWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle("Archive.org 文件上传工具")
        self.setGeometry(100, 100, 450, 200)

        # 布局设置
        central_widget = QWidget()
        layout = QVBoxLayout(central_widget)

        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        layout.addWidget(self.progress_bar)

        # 上传按钮
        self.upload_btn = QPushButton("开始上传")
        self.upload_btn.clicked.connect(self.start_upload)
        layout.addWidget(self.upload_btn)

        self.setCentralWidget(central_widget)
        self.upload_thread = None

    def start_upload(self):
        self.upload_btn.setEnabled(False)
        self.progress_bar.setValue(0)
        # 创建并启动上传线程
        self.upload_thread = UploadThread('file-sm.zip')
        self.upload_thread.progress_updated.connect(self.update_progress)
        self.upload_thread.upload_finished.connect(self.on_upload_done)
        self.upload_thread.start()

    def update_progress(self, progress):
        self.progress_bar.setValue(progress)

    def on_upload_done(self, url):
        self.upload_btn.setEnabled(True)
        print(f"上传完成!文件URL: {url}")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = UploadWindow()
    window.show()
    sys.exit(app.exec_())

关键说明

  1. 回调函数获取进度:upload_callback会在上传每个数据块后被调用,参数chunk_bytes是已上传总字节,total_bytes是文件总字节,通过这两个值计算进度百分比。
  2. 子线程处理上传:将上传操作放到QThread中,避免长时间操作阻塞GUI主线程,保证界面响应。
  3. 信号槽同步进度:子线程通过progress_updated信号将进度传递给主线程,主线程更新进度条;上传完成后通过upload_finished信号返回文件URL。

内容的提问来源于stack exchange,提问作者Shahriar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:13:22