改进下载逻辑,待测试

This commit is contained in:
g1879 2023-10-17 17:45:36 +08:00
parent 8dd184e848
commit 345c051aa1
2 changed files with 36 additions and 34 deletions

View File

@ -1,7 +1,6 @@
# -*- coding:utf-8 -*- # -*- coding:utf-8 -*-
from pathlib import Path from pathlib import Path
from shutil import move from shutil import move
from threading import Lock
from time import sleep, perf_counter from time import sleep, perf_counter
from .commons.tools import get_usable_path from .commons.tools import get_usable_path
@ -27,7 +26,6 @@ class BrowserDownloadManager(object):
self._created = True self._created = True
self._page = page self._page = page
self._lock = Lock()
self._when_download_file_exists = 'rename' self._when_download_file_exists = 'rename'
t = TabDownloadSettings(page.tab_id) t = TabDownloadSettings(page.tab_id)
@ -36,7 +34,7 @@ class BrowserDownloadManager(object):
self._missions = {} # {guid: DownloadMission} self._missions = {} # {guid: DownloadMission}
self._tab_missions = {} # {tab_id: DownloadMission} self._tab_missions = {} # {tab_id: DownloadMission}
self._guid_and_tab = {} # 记录guid在哪个tab self._guid_and_tab = {} # 记录guid在哪个tab
self._flags = {} # {tab_id: bool, DownloadMission} self._flags = {} # {tab_id: [bool, DownloadMission]}
self._page.browser_driver.set_listener('Browser.downloadProgress', self._onDownloadProgress) self._page.browser_driver.set_listener('Browser.downloadProgress', self._onDownloadProgress)
self._page.browser_driver.set_listener('Browser.downloadWillBegin', self._onDownloadWillBegin) self._page.browser_driver.set_listener('Browser.downloadWillBegin', self._onDownloadWillBegin)
@ -109,28 +107,35 @@ class BrowserDownloadManager(object):
""" """
self._guid_and_tab[guid] = tab_id self._guid_and_tab[guid] = tab_id
def set_done(self, mission, state, cancel=False, final_path=None): def set_done(self, mission, state, final_path=None):
"""设置任务结束 """设置任务结束
:param mission: 任务对象 :param mission: 任务对象
:param state: 任务状态 :param state: 任务状态
:param cancel: 是否取消
:param final_path: 最终路径 :param final_path: 最终路径
:return: None :return: None
""" """
mission.state = state if mission.state not in ('canceled', 'skipped'):
mission.state = state
mission.final_path = final_path mission.final_path = final_path
if cancel:
self._page.browser_driver.call_method('Browser.cancelDownload', guid=mission.id)
if mission.final_path:
Path(mission.final_path).unlink(True)
if mission.tab_id in self._tab_missions: if mission.tab_id in self._tab_missions:
self._tab_missions[mission.tab_id].remove(mission.id) self._tab_missions[mission.tab_id].remove(mission.id)
self._missions.pop(mission.id) self._missions.pop(mission.id)
def cancel(self, mission, state):
"""取消任务
:param mission: 任务对象
:param state: 任务状态
:return: None
"""
mission.state = state
self._page.browser_driver.call_method('Browser.cancelDownload', guid=mission.id)
if mission.final_path:
Path(mission.final_path).unlink(True)
def _onDownloadWillBegin(self, **kwargs): def _onDownloadWillBegin(self, **kwargs):
"""用于获取弹出新标签页触发的下载任务""" """用于获取弹出新标签页触发的下载任务"""
guid = kwargs['guid'] guid = kwargs['guid']
end = perf_counter() + .5 end = perf_counter() + .3
while perf_counter() < end: while perf_counter() < end:
tab_id = self._guid_and_tab.get(guid, None) tab_id = self._guid_and_tab.get(guid, None)
if tab_id: if tab_id:
@ -163,9 +168,9 @@ class BrowserDownloadManager(object):
self._missions[guid] = m self._missions[guid] = m
if self.get_flag(tab_id) is False: # 取消该任务 if self.get_flag(tab_id) is False: # 取消该任务
self.set_done(m, 'canceled', True) self.cancel(m, 'canceled')
elif skip: elif skip:
self.set_done(m, 'skipped', True) self.cancel(m, 'skipped')
else: else:
self._tab_missions.setdefault(tab_id, []).append(guid) self._tab_missions.setdefault(tab_id, []).append(guid)
@ -174,24 +179,22 @@ class BrowserDownloadManager(object):
def _onDownloadProgress(self, **kwargs): def _onDownloadProgress(self, **kwargs):
"""下载状态变化时执行""" """下载状态变化时执行"""
if kwargs['guid'] in self._missions: if kwargs['guid'] in self._missions:
with self._lock: mission = self._missions[kwargs['guid']]
if kwargs['guid'] in self._missions: if kwargs['state'] == 'inProgress':
mission = self._missions[kwargs['guid']] mission.state = 'running'
if kwargs['state'] == 'inProgress': mission.received_bytes = kwargs['receivedBytes']
mission.state = 'running' mission.total_bytes = kwargs['totalBytes']
mission.received_bytes = kwargs['receivedBytes']
mission.total_bytes = kwargs['totalBytes']
elif kwargs['state'] == 'completed': elif kwargs['state'] == 'completed':
mission.received_bytes = kwargs['receivedBytes'] mission.received_bytes = kwargs['receivedBytes']
mission.total_bytes = kwargs['totalBytes'] mission.total_bytes = kwargs['totalBytes']
form_path = f'{self._page.download_path}\\{mission.id}' form_path = f'{self._page.download_path}\\{mission.id}'
to_path = str(get_usable_path(f'{mission.path}\\{mission.name}')) to_path = str(get_usable_path(f'{mission.path}\\{mission.name}'))
move(form_path, to_path) move(form_path, to_path)
self.set_done(mission, 'completed', final_path=to_path) self.set_done(mission, 'completed', final_path=to_path)
else: # canceled else: # 'canceled'
self.set_done(mission, 'canceled') self.set_done(mission, 'canceled')
class TabDownloadSettings(object): class TabDownloadSettings(object):
@ -248,7 +251,7 @@ class DownloadMission(object):
def cancel(self): def cancel(self):
"""取消该任务,如任务已完成,删除已下载的文件""" """取消该任务,如任务已完成,删除已下载的文件"""
self._mgr.set_done(self, state='canceled', cancel=True) self._mgr.cancel(self, state='canceled')
def wait(self, show=True, timeout=None, cancel_if_timeout=True): def wait(self, show=True, timeout=None, cancel_if_timeout=True):
"""等待任务结束 """等待任务结束

View File

@ -1,15 +1,12 @@
from pathlib import Path from pathlib import Path
from threading import Lock
from typing import Dict, Optional, Union from typing import Dict, Optional, Union
from chromium_base import ChromiumBase
from chromium_page import ChromiumPage from chromium_page import ChromiumPage
class BrowserDownloadManager(object): class BrowserDownloadManager(object):
BROWSERS: Dict[str, BrowserDownloadManager] = ... BROWSERS: Dict[str, BrowserDownloadManager] = ...
_page: ChromiumPage = ... _page: ChromiumPage = ...
_lock: Lock = ...
_missions: Dict[str, DownloadMission] = ... _missions: Dict[str, DownloadMission] = ...
_tab_missions: dict = ... _tab_missions: dict = ...
_tabs_settings: Dict[str, TabDownloadSettings] = ... _tabs_settings: Dict[str, TabDownloadSettings] = ...
@ -37,7 +34,9 @@ class BrowserDownloadManager(object):
def set_mission(self, tab_id: str, guid: str) -> None: ... def set_mission(self, tab_id: str, guid: str) -> None: ...
def set_done(self, mission: DownloadMission, state: str, cancel: bool = False, final_path: str = None) -> None: ... def set_done(self, mission: DownloadMission, state: str, final_path: str = None) -> None: ...
def cancel(self, mission: DownloadMission, state: str) -> None: ...
def _onDownloadWillBegin(self, **kwargs) -> None: ... def _onDownloadWillBegin(self, **kwargs) -> None: ...