browser_driver和BrowserManager改成每个浏览器只一个对象;改进下浏览器载功能,未完成

This commit is contained in:
g1879 2023-09-11 07:10:26 +08:00
parent a6233aa923
commit ed2883e2b9
6 changed files with 80 additions and 39 deletions

View File

@ -233,3 +233,21 @@ class ChromiumDriver(object):
return f"<ChromiumDriver {self.id}>" return f"<ChromiumDriver {self.id}>"
__repr__ = __str__ __repr__ = __str__
class BrowserDriver(ChromiumDriver):
BROWSERS = {}
def __new__(cls, tab_id, tab_type, address):
if tab_id in cls.BROWSERS:
return cls.BROWSERS[tab_id]
return object.__new__(cls)
def __init__(self, tab_id, tab_type, address):
if tab_id in BrowserDriver.BROWSERS:
return
super().__init__(tab_id, tab_type, address)
BrowserDriver.BROWSERS[tab_id] = self
def __repr__(self):
return f"<BrowserDriver {self.id}>"

View File

@ -5,7 +5,7 @@
""" """
from queue import Queue from queue import Queue
from threading import Thread, Event from threading import Thread, Event
from typing import Union, Callable from typing import Union, Callable, Dict
class GenericAttr(object): class GenericAttr(object):
@ -58,3 +58,7 @@ class ChromiumDriver(object):
def get_listener(self, event: str) -> Union[Callable, None]: ... def get_listener(self, event: str) -> Union[Callable, None]: ...
def __str__(self) -> str: ... def __str__(self) -> str: ...
class BrowserDriver(ChromiumDriver):
BROWSERS: Dict[str, ChromiumDriver] = ...

View File

@ -3,12 +3,14 @@
@Author : g1879 @Author : g1879
@Contact : g1879@qq.com @Contact : g1879@qq.com
""" """
from pathlib import Path
from shutil import move from shutil import move
from threading import Lock
from time import perf_counter, sleep from time import perf_counter, sleep
from .chromium_base import ChromiumBase, Timeout from .chromium_base import ChromiumBase, Timeout
from .chromium_base import handle_download from .chromium_base import handle_download
from .chromium_driver import ChromiumDriver from .chromium_driver import ChromiumDriver, BrowserDriver
from .chromium_tab import ChromiumTab from .chromium_tab import ChromiumTab
from .commons.browser import connect_browser from .commons.browser import connect_browser
from .commons.tools import get_usable_path from .commons.tools import get_usable_path
@ -98,7 +100,7 @@ class ChromiumPage(ChromiumBase):
u = f'http://{self.address}/json/version' u = f'http://{self.address}/json/version'
ws = self._control_session.get(u).json()['webSocketDebuggerUrl'] ws = self._control_session.get(u).json()['webSocketDebuggerUrl']
self._control_session.get(u, headers={'Connection': 'close'}) self._control_session.get(u, headers={'Connection': 'close'})
self._browser_driver = ChromiumDriver(ws.split('/')[-1], 'browser', self.address) self._browser_driver = BrowserDriver(ws.split('/')[-1], 'browser', self.address)
self._browser_driver.start() self._browser_driver.start()
self._alert = Alert() self._alert = Alert()
@ -446,13 +448,32 @@ class ChromiumTabRect(object):
class BrowserDownloadManager(object): class BrowserDownloadManager(object):
BROWSERS = {}
def __new__(cls, page):
"""
:param page: ChromiumPage对象
"""
if page.browser_driver.id in cls.BROWSERS:
return cls.BROWSERS[page.browser_driver.id]
return object.__new__(cls)
def __init__(self, page): def __init__(self, page):
"""
:param page: ChromiumPage对象
"""
if page.browser_driver.id in BrowserDownloadManager.BROWSERS:
return
self._page = page self._page = page
self._lock = Lock()
page.set.download_path(page.download_path) page.set.download_path(page.download_path)
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)
self._missions = {} self._missions = {}
BrowserDownloadManager.BROWSERS[page.browser_driver.id] = self
@property @property
def missions(self): def missions(self):
return self._missions return self._missions
@ -464,12 +485,20 @@ class BrowserDownloadManager(object):
""" """
self._missions[mission.id] = mission self._missions[mission.id] = mission
def cancel(self, mission): def set_done(self, mission, state, cancel=False, final_path=None):
"""取消一个下载任务 """设置任务结束
:param mission: 任务对象 :param mission: 任务对象
:param state: 任务状态
:param cancel: 是否取消
:param final_path: 最终路径
:return: None :return: None
""" """
self._page.browser_driver.call_method('Browser.cancelDownload', guid=mission.id) mission.state = state
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)
self._missions.pop(mission.id) self._missions.pop(mission.id)
def _onDownloadWillBegin(self, **kwargs): def _onDownloadWillBegin(self, **kwargs):
@ -481,22 +510,24 @@ class BrowserDownloadManager(object):
def _onDownloadProgress(self, **kwargs): def _onDownloadProgress(self, **kwargs):
"""下载状态变化时执行""" """下载状态变化时执行"""
if kwargs['guid'] in self._missions: if kwargs['guid'] in self._missions:
mission = self._missions[kwargs['guid']] with self._lock:
if kwargs['state'] == 'inProgress': if kwargs['guid'] in self._missions:
mission.state = 'running' mission = self._missions[kwargs['guid']]
mission.received_bytes = kwargs['receivedBytes'] if kwargs['state'] == 'inProgress':
mission.total_bytes = kwargs['totalBytes'] mission.state = 'running'
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)
mission._set_done('completed', final_path=to_path) self.set_done(mission, 'completed', final_path=to_path)
else: else:
mission._set_done('canceled') self.set_done(mission, 'canceled')
class Alert(object): class Alert(object):

View File

@ -3,6 +3,7 @@
@Author : g1879 @Author : g1879
@Contact : g1879@qq.com @Contact : g1879@qq.com
""" """
from threading import Lock
from typing import Union, Tuple, List, Dict from typing import Union, Tuple, List, Dict
from .chromium_base import ChromiumBase from .chromium_base import ChromiumBase
@ -128,6 +129,10 @@ class ChromiumTabRect(object):
class BrowserDownloadManager(object): class BrowserDownloadManager(object):
_page: ChromiumPage = ... _page: ChromiumPage = ...
_missions: Dict[str, DownloadMission] = ... _missions: Dict[str, DownloadMission] = ...
_lock: Lock = ...
BROWSERS: Dict[str, BrowserDownloadManager] = ...
def __new__(cls, page: ChromiumPage): ...
def __init__(self, page: ChromiumPage): ... def __init__(self, page: ChromiumPage): ...
@ -136,7 +141,7 @@ class BrowserDownloadManager(object):
def add_mission(self, mission: DownloadMission) -> None: ... def add_mission(self, mission: DownloadMission) -> None: ...
def cancel(self, mission: DownloadMission) -> None: ... def set_done(self, mission: DownloadMission, state: str, cancel: bool = False, final_path: str = None) -> None: ...
def _onDownloadWillBegin(self, **kwargs) -> None: ... def _onDownloadWillBegin(self, **kwargs) -> None: ...

View File

@ -401,9 +401,7 @@ class DownloadMission(object):
def cancel(self): def cancel(self):
"""取消该任务,如任务已完成,删除已下载的文件""" """取消该任务,如任务已完成,删除已下载的文件"""
self._set_done('canceled', True) self.tab._page._dl_mgr.set_done(self, state='canceled', cancel=True)
if self.final_path:
Path(self.final_path).unlink(True)
def wait(self, show=True, timeout=None, cancel_if_timeout=True): def wait(self, show=True, timeout=None, cancel_if_timeout=True):
"""等待任务结束 """等待任务结束
@ -450,16 +448,3 @@ class DownloadMission(object):
print() print()
return self.final_path if self.final_path else False return self.final_path if self.final_path else False
def _set_done(self, state, cancel=False, final_path=None):
"""设置任务结束
:param state: 任务状态
:param cancel: 是否取消
:param final_path: 最终路径
:return: None
"""
self.state = state
self.final_path = final_path
if cancel:
self.tab._page._dl_mgr.cancel(self)
self.tab._download_missions.remove(self)

View File

@ -108,5 +108,3 @@ class DownloadMission(object):
def cancel(self) -> None: ... def cancel(self) -> None: ...
def wait(self, show: bool = True, timeout=None, cancel_if_timeout=True) -> Union[bool, str]: ... def wait(self, show: bool = True, timeout=None, cancel_if_timeout=True) -> Union[bool, str]: ...
def _set_done(self, state: str, cancel: bool = False, final_path: str = None) -> None: ...