Browse Source

Update docstrings dlthread.py

doc-issue-template
MrS0m30n3 10 years ago
parent
commit
7a956c5ca5
1 changed files with 135 additions and 8 deletions
  1. 143
      youtube_dl_gui/dlthread.py

143
youtube_dl_gui/dlthread.py

@ -1,6 +1,15 @@
#!/usr/bin/env python2
''' Youtube-dlG module to download videos & handle each download. '''
"""Youtubedlg module for managing the download process.
This module is responsible for managing the download process
and update the GUI interface.
Note:
It's not the actual module that downloads the urls
thats the job of the 'downloaders' module.
"""
import time
import os.path
@ -19,7 +28,25 @@ from .utils import YOUTUBEDL_BIN
class DownloadManager(Thread):
""" DownloadManager """
"""Manages the download process.
Attributes:
PUBLISHER_TOPIC (string): Subscription topic for the wx Publisher.
WORKERS_NUMBER (int): Size of custom thread pool.
WAIT_TIME (float): Time in seconds to sleep.
Args:
urls_list (list): Python list that contains multiple dictionaries
with the url to download and the corresponding column(index) in
which the worker should send the download process information.
opt_manager (optionsmanager.OptionsManager): Object responsible for
managing the youtubedlg options.
log_manager (logmanager.LogManager): Object responsible for writing
erros to the log.
"""
PUBLISHER_TOPIC = 'dlmanager'
WORKERS_NUMBER = 3
@ -40,13 +67,19 @@ class DownloadManager(Thread):
@property
def successful(self):
"""Return number of successful downloads. """
return self._successful
@property
def time_it_took(self):
"""Return time in seconds it took for the
download process to finish.
"""
return self._time_it_took
def increase_succ(self):
"""Increase number of successful downloads. """
self._successful += 1
def run(self):
@ -76,6 +109,10 @@ class DownloadManager(Thread):
self._talk_to_gui('finished')
def active(self):
"""Return number of active items.
active_items = workers that work + items waiting in the url_list.
"""
counter = 0
for worker in self._workers:
if not worker.available():
@ -86,22 +123,56 @@ class DownloadManager(Thread):
return counter
def stop_downloads(self):
"""Stop the download process. Also send 'closing'
signal back to the GUI.
Note:
It does NOT kill the workers thats the job of the
clean up task in the run() method.
"""
self._talk_to_gui('closing')
self._running = False
for worker in self._workers:
worker.stop_download()
def add_url(self, url):
"""Add given url to the urls_list.
Args:
url (dictionary): Python dictionary that contains two keys,
the url and the index of the corresponding column
to send the download information back.
"""
self.urls_list.append(url)
def _talk_to_gui(self, data):
"""Send data back to the GUI using wx CallAfter and wx Publisher.
Args:
data (string): Unique signal string that informs the GUI for the
download process.
Note:
DownloadManager supports 3 signals for the moment.
1) closing: The download process is closing.
2) closed: The download process has closed.
3) finished: The download process terminated normally.
"""
CallAfter(Publisher.sendMessage, self.PUBLISHER_TOPIC, data)
def _check_youtubedl(self):
"""Check if youtube-dl binary exists. If not try to download it. """
if not os.path.exists(self._youtubedl_path()):
UpdateThread(self.opt_manager.options['youtubedl_path'], True).join()
def _jobs_done(self):
"""Return True if the workers have finished their jobs.
Else return False.
"""
for worker in self._workers:
if not worker.available():
return False
@ -109,17 +180,44 @@ class DownloadManager(Thread):
return True
def _youtubedl_path(self):
"""Return the path of the youtube-dl binary. """
path = self.opt_manager.options['youtubedl_path']
path = os.path.join(path, YOUTUBEDL_BIN)
return path
def _init_workers(self):
"""Initialise the custom thread pool.
Returns:
Python list that contains the workers.
"""
youtubedl = self._youtubedl_path()
return [Worker(self.opt_manager, youtubedl, self.increase_succ, self.log_manager) for i in xrange(self.WORKERS_NUMBER)]
class Worker(Thread):
"""Simple worker that downloads the given url using a downloader.
Attributes:
PUBLISHER_TOPIC (string): Subscription topic for the wx Publisher.
WAIT_TIME (float): Time in seconds to sleep.
Args:
opt_manager (optionsmanager.OptionsManager): Check DownloadManager
description.
youtubedl (string): Absolute path to youtube-dl binary.
increase_succ (DownloadManager.increase_succ() method): Callback to
increase the number of successful downloads.
log_manager (logmanager.LogManager): Check DownloadManager
description.
"""
PUBLISHER_TOPIC = 'dlworker'
WAIT_TIME = 0.1
@ -139,7 +237,7 @@ class Worker(Thread):
def run(self):
while self._running:
if self._url is not None:
options = self._options_parser.parse(self.opt_manager.options)
options = self._options_parser.parse(self.opt_manager.options)
ret_code = self._downloader.download(self._url, options)
if (ret_code == YoutubeDLDownloader.OK or
@ -152,20 +250,42 @@ class Worker(Thread):
time.sleep(self.WAIT_TIME)
def download(self, item):
"""Download given item.
Args:
item (dictionary): Python dictionary that contains two keys,
the url and the index of the corresponding column
to send the download information back.
"""
self._url = item['url']
self._index = item['index']
def stop_download(self):
"""Stop the download process of the worker. """
self._downloader.stop()
def close(self):
"""Kill the worker after stopping the download process. """
self._running = False
self._downloader.stop()
def available(self):
"""Return True if the worker has no job. Else False. """
return self._url is None
def _data_hook(self, data):
"""Callback method.
This method takes the data from the downloader, merges the
playlist_info with the current status (if any) and sends the
data back to the GUI.
Args:
data (dictionary): Python dictionary that contains information
about the download process. (See YoutubeDLDownloader class).
"""
if data['status'] is not None and data['playlist_index'] is not None:
playlist_info = ' '
playlist_info += data['playlist_index']
@ -177,15 +297,22 @@ class Worker(Thread):
self._talk_to_gui(data)
def _talk_to_gui(self, data):
"""Send the data back to the GUI after inserting the index. """
data['index'] = self._index
CallAfter(Publisher.sendMessage, self.PUBLISHER_TOPIC, data)
if __name__ == '__main__':
''' Direct call of module for testing. Before
you run the tests change relative imports or you will
get [ValueError: Attempted relative import in non-package].
You need to change relative imports on all the modules
you are gonna use.'''
"""Direct call of module for testing.
Raises:
ValueError: Attempted relative import in non-package
Note:
Before you run the tests change relative imports else an exceptions
will be raised. You need to change relative imports on all the modules
you are gonna use.
"""
print "No tests available"
Loading…
Cancel
Save