|
楼主 |
发表于 2024-5-15 09:40:04
|
显示全部楼层
安徽省马鞍山市
import os
import requests
import threading
import time
class Downloader:
def __init__(
self,
id,
completion_callback=None,
progress_callback=None,
message_output=None,
download_dir="cache",
):
self.id = id
self.file_urls = []
self.completion_callback = completion_callback
self.progress_callback = progress_callback
self.message_output = message_output
self.download_dir = download_dir
self.downloaded_files = []
self.stop_flag = False
self.session = requests.Session()
self._create_download_dir()
def _create_download_dir(self):
os.makedirs(self.download_dir, exist_ok=True)
def add_url(self, url, filename, dirname=None):
self.file_urls.append((url, filename, dirname))
def start(self, callback=None, params=None):
download_thread = threading.Thread(
target=self._download,
args=(
callback,
params,
),
)
download_thread.start()
def start_sync(self, callback=None, params=None):
return self._download(callback, params)
def stop(self):
self.stop_flag = True
def _download(self, callback=None, params=None):
for url, filename, dirname in self.file_urls:
if self.stop_flag:
break
try:
self._download_file(url, filename, dirname)
except Exception as e:
self._print_message(f"Failed to download {url}: {e}")
break
if self.completion_callback:
sync = self.completion_callback(
self.id, self.downloaded_files, self.download_dir
)
self.session.close()
if callback:
return callback(self.id, sync, params)
def _download_file(self, url, filename, dirname):
response = self.session.get(url, stream=True)
total_size = int(response.headers.get("content-length", 0))
bytes_so_far = 0
start_time = time.time()
file_path = os.path.join(self.download_dir, dirname or "", filename)
file_path = os.path.normpath(file_path)
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, "wb") as file:
for chunk in response.iter_content(chunk_size=1024):
if self.stop_flag:
break
if chunk:
file.write(chunk)
bytes_so_far += len(chunk)
if time.time() - start_time > 1:
if self.progress_callback:
self.progress_callback(
self.id, bytes_so_far, total_size, filename, dirname
)
start_time = time.time()
self._print_message(
f"{os.path.join(dirname or '', filename)} downloaded from {url}"
)
self.downloaded_files.append(file_path)
def _print_message(self, message):
if self.message_output:
self.message_output(message)
else:
print(message)
if __name__ == "__main__":
def handle_download_completion(id, downloaded_files, download_dir):
print_message(f"All files have been downloaded for download ID: {id}")
print_message(f"Downloaded files: {downloaded_files}")
return True
def handle_progress_update(id, bytes_so_far, total_size, filename, dirname):
print_message(
f"Download ID: {id}, downloaded {bytes_so_far} of {total_size} bytes for {dirname} {filename}"
)
def print_message(message):
print(message)
base = os.path.dirname(__file__)
cache = os.path.join(base, "static", "cache")
downloader1 = Downloader(
22, handle_download_completion, handle_progress_update, print_message, cache
)
downloader1.add_url(
"http://192.168.0.201:8998/html/data/download/schedule-88.zip",
"os\\schedule-1.zip",
)
# downloader1.add_url("https://dldir1.qq.com/qqfile/qq/QQNT/a8b6c3ae/QQ9.9.6.20201_x64.exe", "QQSetup.exe")
def callback(id, state, value):
print("#callback", id, state, value)
print(downloader1.start(callback, "is"))
|
|