diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index d4dd05d8c..a88df9cd0 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -55,6 +55,7 @@ from .utils import ( write_string, YoutubeDLHandler, prepend_extension, + StopDownloads ) from .extractor import get_info_extractor, gen_extractors from .downloader import get_suitable_downloader @@ -186,6 +187,8 @@ class YoutubeDL(object): self._ies = [] self._ies_instances = {} self._pps = [] + self._stop = False + self._pause = False self._progress_hooks = [] self._download_retcode = 0 self._num_downloads = 0 @@ -980,6 +983,9 @@ class YoutubeDL(object): fd = get_suitable_downloader(info)(self, self.params) for ph in self._progress_hooks: fd.add_progress_hook(ph) + # Add stop, pause handlers + fd.add_stop_handler(self._stop_handler) + fd.add_pause_handler(self._pause_handler) return fd.download(name, info) if info_dict.get('requested_formats') is not None: downloaded = [] @@ -1013,6 +1019,8 @@ class YoutubeDL(object): except (ContentTooShortError, ) as err: self.report_error('content too short (expected %s bytes and served %s)' % (err.expected, err.downloaded)) return + except StopDownloads: + return if success: try: @@ -1023,6 +1031,28 @@ class YoutubeDL(object): self.record_download_archive(info_dict) + def _stop_handler(self): + """ Return self._stop status """ + return self._stop + + def _pause_handler(self): + """ Return self._pause status """ + return self._pause + + def stop(self): + """ Stop downloads """ + if self._stop: + self._stop = False + else: + self._stop = True + + def pause(self): + """ Pause/Resume downloads """ + if self._pause: + self._pause = False + else: + self._pause = True + def download(self, url_list): """Download a given list of URLs.""" if (len(url_list) > 1 and diff --git a/youtube_dl/downloader/common.py b/youtube_dl/downloader/common.py index 917f3450e..b8ce20af0 100644 --- a/youtube_dl/downloader/common.py +++ b/youtube_dl/downloader/common.py @@ -8,6 +8,7 @@ from ..utils import ( encodeFilename, format_bytes, timeconvert, + StopDownloads ) @@ -49,6 +50,8 @@ class FileDownloader(object): self.ydl = ydl self._progress_hooks = [] self.params = params + self._stop_handler = None + self._pause_handler = None @staticmethod def format_seconds(seconds): @@ -155,7 +158,7 @@ class FileDownloader(object): speed = float(byte_counter) / elapsed if speed > rate_limit: time.sleep((byte_counter - rate_limit * (now - start_time)) / rate_limit) - + def temp_name(self, filename): """Returns a temporary filename for the given filename.""" if self.params.get('nopart', False) or filename == u'-' or \ @@ -298,6 +301,28 @@ class FileDownloader(object): for ph in self._progress_hooks: ph(status) + def _stop(self): + """ Check stop handler """ + if self._stop_handler is not None: + if self._stop_handler(): + raise StopDownloads() + + def _pause(self): + """ Check pause/resume handler """ + if self._pause_handler is not None: + while self._pause_handler(): + # Break if stop handler enable + if self._stop_handler(): break + time.sleep(1) + + def add_stop_handler(self, shand): + """ shand gets checked. If True raise StopDownloads """ + self._stop_handler = shand + + def add_pause_handler(self, phand): + """ phand gets checked. If True pause downloads """ + self._pause_handler = phand + def add_progress_hook(self, ph): """ ph gets called on download progress, with a dictionary with the entries * filename: The final filename diff --git a/youtube_dl/downloader/http.py b/youtube_dl/downloader/http.py index cc8b9c9a7..4f18c9e26 100644 --- a/youtube_dl/downloader/http.py +++ b/youtube_dl/downloader/http.py @@ -162,6 +162,12 @@ class HttpFD(FileDownloader): 'speed': speed, }) + # Check stop handler + self._stop() + + # Check pause handler + self._pause() + # Apply rate limit self.slow_down(start, byte_counter - resume_len) diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index 9c9320934..3daf42d99 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -655,6 +655,9 @@ class MaxDownloadsReached(Exception): """ --max-downloads limit has been reached. """ pass +class StopDownloads(Exception): + """ Stop Downloads """ + pass class UnavailableVideoError(Exception): """Unavailable Format exception.