Browse Source

Update docstrings mainframe.py

doc-issue-template
MrS0m30n3 10 years ago
parent
commit
d8038364a8
1 changed files with 212 additions and 71 deletions
  1. 283
      youtube_dl_gui/mainframe.py

283
youtube_dl_gui/mainframe.py

@ -1,6 +1,6 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
''' Contains code for main app frame & custom ListCtrl. '''
"""Youtubedlg module responsible for the main app window. """
import os.path import os.path
@ -29,16 +29,46 @@ from .info import (
class MainFrame(wx.Frame): class MainFrame(wx.Frame):
''' Youtube-dlG main frame. '''
"""Main window class.
This class is responsible for creating the main app window
and binding the events.
Attributes:
FRAME_SIZE (tuple): Frame size (width, height).
BUTTONS_SIZE (tuple): Buttons size (width, height).
BUTTONS_SPACE (int): Horizontal space between the buttons.
SIZE_20 (int): Constant size number.
SIZE_10 (int): Constant size number.
SIZE_5 (int): Constant size number.
Labels area (strings): Strings for the widgets labels.
STATUSLIST_COLUMNS (tuple): Tuple of tuples that contains informations
about the ListCtrl columns. First item is the column name. Second
item is the column position. Third item is the constant column
label. Fourth item is the column width. Last item is a boolean
flag if True the current column is resizable.
Args:
opt_manager (optionsmanager.OptionsManager): Object responsible for
handling the settings.
log_manager (logmanager.LogManager): Object responsible for handling
the log stuff.
parent (wx.Window): Frame parent.
"""
FRAME_SIZE = (700, 490) FRAME_SIZE = (700, 490)
TEXTCTRL_SIZE = (-1, -1)
BUTTONS_SIZE = (90, 30) BUTTONS_SIZE = (90, 30)
BUTTONS_SPACE = 80 BUTTONS_SPACE = 80
SIZE_20 = 20 SIZE_20 = 20
SIZE_10 = 10 SIZE_10 = 10
SIZE_5 = 5 SIZE_5 = 5
# Labels area
URLS_LABEL = "URLs" URLS_LABEL = "URLs"
DOWNLOAD_LABEL = "Download" DOWNLOAD_LABEL = "Download"
UPDATE_LABEL = "Update" UPDATE_LABEL = "Update"
@ -62,6 +92,7 @@ class MainFrame(wx.Frame):
ETA_LABEL = "ETA" ETA_LABEL = "ETA"
SPEED_LABEL = "Speed" SPEED_LABEL = "Speed"
STATUS_LABEL = "Status" STATUS_LABEL = "Status"
#################################
STATUSLIST_COLUMNS = ( STATUSLIST_COLUMNS = (
('filename', 0, VIDEO_LABEL, 150, True), ('filename', 0, VIDEO_LABEL, 150, True),
@ -114,6 +145,17 @@ class MainFrame(wx.Frame):
self._set_publisher(self._download_manager_handler, 'dlmanager') self._set_publisher(self._download_manager_handler, 'dlmanager')
def _set_publisher(self, handler, topic): def _set_publisher(self, handler, topic):
"""Sets a handler for the given topic.
Args:
handler (function): Can be any function with one parameter
the message that the caller sends.
topic (string): Can be any string that identifies the caller.
You can bind multiple handlers on the same topic or
multiple topics on the same handler.
"""
Publisher.subscribe(handler, topic) Publisher.subscribe(handler, topic)
def _create_statictext(self, label): def _create_statictext(self, label):
@ -122,9 +164,9 @@ class MainFrame(wx.Frame):
def _create_textctrl(self, style=None, event_handler=None): def _create_textctrl(self, style=None, event_handler=None):
if style is None: if style is None:
textctrl = wx.TextCtrl(self._panel, size=self.TEXTCTRL_SIZE)
textctrl = wx.TextCtrl(self._panel)
else: else:
textctrl = wx.TextCtrl(self._panel, size=self.TEXTCTRL_SIZE, style=style)
textctrl = wx.TextCtrl(self._panel, style=style)
if event_handler is not None: if event_handler is not None:
textctrl.Bind(wx.EVT_TEXT, event_handler) textctrl.Bind(wx.EVT_TEXT, event_handler)
@ -140,10 +182,10 @@ class MainFrame(wx.Frame):
return btn return btn
def _create_popup(self, text, title, style): def _create_popup(self, text, title, style):
''' Create popup message. '''
wx.MessageBox(text, title, style) wx.MessageBox(text, title, style)
def _set_sizers(self): def _set_sizers(self):
"""Sets the sizers of the main window. """
hor_sizer = wx.BoxSizer(wx.HORIZONTAL) hor_sizer = wx.BoxSizer(wx.HORIZONTAL)
vertical_sizer = wx.BoxSizer(wx.VERTICAL) vertical_sizer = wx.BoxSizer(wx.VERTICAL)
@ -161,13 +203,10 @@ class MainFrame(wx.Frame):
vertical_sizer.Add(buttons_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL) vertical_sizer.Add(buttons_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)
vertical_sizer.AddSpacer(self.SIZE_10) vertical_sizer.AddSpacer(self.SIZE_10)
vertical_sizer.Add(self._status_list, 2, wx.EXPAND) vertical_sizer.Add(self._status_list, 2, wx.EXPAND)
vertical_sizer.AddSpacer(self.SIZE_5) vertical_sizer.AddSpacer(self.SIZE_5)
vertical_sizer.Add(self._status_bar) vertical_sizer.Add(self._status_bar)
vertical_sizer.AddSpacer(self.SIZE_5) vertical_sizer.AddSpacer(self.SIZE_5)
hor_sizer.Add(vertical_sizer, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, border=self.SIZE_20) hor_sizer.Add(vertical_sizer, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, border=self.SIZE_20)
@ -175,23 +214,23 @@ class MainFrame(wx.Frame):
self._panel.SetSizer(hor_sizer) self._panel.SetSizer(hor_sizer)
def _update_youtubedl(self): def _update_youtubedl(self):
''' Update youtube-dl executable. '''
"""Update youtube-dl binary to the latest version. """
self._update_btn.Disable() self._update_btn.Disable()
self._download_btn.Disable() self._download_btn.Disable()
self.update_thread = UpdateThread(self.opt_manager.options['youtubedl_path']) self.update_thread = UpdateThread(self.opt_manager.options['youtubedl_path'])
def _status_bar_write(self, msg): def _status_bar_write(self, msg):
''' Write msg to self._status_bar. '''
"""Display msg in the status bar. """
self._status_bar.SetLabel(msg) self._status_bar.SetLabel(msg)
def _reset_buttons(self): def _reset_buttons(self):
''' Reset GUI and variables after download process. '''
"""Resets GUI widgets after update or download process. """
self._download_btn.SetLabel(self.DOWNLOAD_LABEL) self._download_btn.SetLabel(self.DOWNLOAD_LABEL)
self._download_btn.Enable() self._download_btn.Enable()
self._update_btn.Enable() self._update_btn.Enable()
def _print_stats(self): def _print_stats(self):
''' Print stats to self._status_bar after downloading. '''
"""Display download stats in the status bar. """
suc_downloads = self.download_manager.successful suc_downloads = self.download_manager.successful
dtime = get_time(self.download_manager.time_it_took) dtime = get_time(self.download_manager.time_it_took)
@ -204,7 +243,13 @@ class MainFrame(wx.Frame):
self._status_bar_write(msg) self._status_bar_write(msg)
def _after_download(self): def _after_download(self):
''' Run tasks after download process has finished. '''
"""Run tasks after download process has been completed.
Note:
Here you can add any tasks you want to run after the
download process has been completed.
"""
if self.opt_manager.options['shutdown']: if self.opt_manager.options['shutdown']:
self.opt_manager.save_to_file() self.opt_manager.save_to_file()
shutdown_sys(self.opt_manager.options['sudo_password']) shutdown_sys(self.opt_manager.options['sudo_password'])
@ -214,16 +259,31 @@ class MainFrame(wx.Frame):
open_dir(self.opt_manager.options['save_path']) open_dir(self.opt_manager.options['save_path'])
def _status_list_handler(self, msg): def _status_list_handler(self, msg):
"""dlthread.Worker thread handler.
Handles messages from the Worker thread.
Args:
See dlthread.Worker _talk_to_gui() method.
"""
data = msg.data data = msg.data
self._status_list.write(data) self._status_list.write(data)
# Report urls been downloaded
# Report number of urls been downloaded
msg = self.URL_REPORT_MSG.format(self.download_manager.active()) msg = self.URL_REPORT_MSG.format(self.download_manager.active())
self._status_bar_write(msg) self._status_bar_write(msg)
def _download_manager_handler(self, msg): def _download_manager_handler(self, msg):
''' Handle messages from DownloadManager. '''
"""dlthread.DownloadManager thread handler.
Handles messages from the DownloadManager thread.
Args:
See dlthread.DownloadManager _talk_to_gui() method.
"""
data = msg.data data = msg.data
if data == 'finished': if data == 'finished':
@ -239,7 +299,14 @@ class MainFrame(wx.Frame):
self._status_bar_write(self.CLOSING_MSG) self._status_bar_write(self.CLOSING_MSG)
def _update_handler(self, msg): def _update_handler(self, msg):
''' Handle messages from UpdateThread. '''
"""dlthread.UpdateThread thread handler.
Handles messages from the UpdateThread thread.
Args:
See updthread.UpdateThread _talk_to_gui() method.
"""
data = msg.data data = msg.data
if data == 'finish': if data == 'finish':
@ -249,10 +316,11 @@ class MainFrame(wx.Frame):
self._status_bar_write(data) self._status_bar_write(data)
def _get_urls(self): def _get_urls(self):
"""Returns urls list. """
return self._url_list.GetValue().split('\n') return self._url_list.GetValue().split('\n')
def _start_download(self): def _start_download(self):
''' Handle pre-download tasks & start download process. '''
"""Handles pre-download tasks & starts the download process. """
self._status_list.clear() self._status_list.clear()
self._status_list.load_urls(self._get_urls()) self._status_list.load_urls(self._get_urls())
@ -270,28 +338,72 @@ class MainFrame(wx.Frame):
self._update_btn.Disable() self._update_btn.Disable()
def _on_urllist_edit(self, event): def _on_urllist_edit(self, event):
''' Dynamically add url for download.'''
"""Event handler of the self._status_list widget.
This method is used to dynamically add urls on the download_manager
after the download process has started.
Args:
event (wx.Event): Event item.
"""
if self.download_manager is not None: if self.download_manager is not None:
self._status_list.load_urls(self._get_urls(), self.download_manager.add_url) self._status_list.load_urls(self._get_urls(), self.download_manager.add_url)
def _on_download(self, event): def _on_download(self, event):
''' Event handler method for self._download_btn. '''
"""Event handler of the self._download_btn widget.
This method is used when download-stop button is pressed to
start or stop the download process.
Args:
event (wx.Event): Event item.
"""
if self.download_manager is None: if self.download_manager is None:
self._start_download() self._start_download()
else: else:
self.download_manager.stop_downloads() self.download_manager.stop_downloads()
def _on_update(self, event): def _on_update(self, event):
''' Event handler method for self._update_btn. '''
"""Event handler of the self._update_btn widget.
This method is used when update button is pressed to start
the update process.
Note:
Currently the is not way to stop the update process.
Args:
event (wx.Event): Event item.
"""
self._update_youtubedl() self._update_youtubedl()
def _on_options(self, event): def _on_options(self, event):
''' Event handler method for self._options_btn. '''
"""Event handler of the self._options_btn widget.
This method is used when options button is pressed to show
the optios window.
Args:
event (wx.Event): Event item.
"""
self._options_frame.load_all_options() self._options_frame.load_all_options()
self._options_frame.Show() self._options_frame.Show()
def _on_close(self, event): def _on_close(self, event):
''' Event handler method (wx.EVT_CLOSE). '''
"""Event handler method for the wx.EVT_CLOSE event.
This method is used when the user tries to close the program.
It's used to run some tasks on the shutdown like save the options
and make sure the download & update process are not running.
Args:
event (wx.Event): Event item.
"""
if self.download_manager is not None: if self.download_manager is not None:
self.download_manager.stop_downloads() self.download_manager.stop_downloads()
self.download_manager.join() self.download_manager.join()
@ -305,45 +417,12 @@ class MainFrame(wx.Frame):
class ListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin): class ListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
'''
Custom ListCtrl class.
Accessible Methods
write()
Params: Python dictionary that contains data to write
Return: None
has_url()
Params: Url to search
Return: True if url in ListCtrl, else False
add_url()
Params: Url to add
Return: None
clear()
Params: None
Return: None
is_empty()
Params: None
Return: True if ListCtrl is empty, else False
get_items()
Params: None
Return: Python list that contains all ListCtrl items
get_last_item()
Params: None
Return: Last item inserted in ListCtrl
'''
"""Custom ListCtrl widget.
Args:
columns (tuple): See MainFrame class STATUSLIST_COLUMNS attribute.
"""
def __init__(self, columns, *args, **kwargs): def __init__(self, columns, *args, **kwargs):
wx.ListCtrl.__init__(self, *args, **kwargs) wx.ListCtrl.__init__(self, *args, **kwargs)
@ -354,12 +433,41 @@ class ListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
self._set_columns() self._set_columns()
def write(self, data): def write(self, data):
''' Write data on ListCtrl row-column. '''
"""Write data on ListCtrl row-column.
Args:
data (dictionary): Dictionary that contains data to be
written on the ListCtrl. In order for this method to
write the given data there must be an 'index' key that
identifies the current row and a corresponding key to the
self.columns first item (column name) that identifies
the column.
Example:
Example of data to be written.
data = {'index': 1, 'filename': 'test'}
The write method will search the self.columns tuple in order to
see if any of the columns names is in the income data. Here the
only key is the 'filename' so it's gonna retrieve the columns
number for the filename column (second item in self.columns) and
then it will read the data['index'] to identify the row.
"""
for column in self.columns: for column in self.columns:
column_key = column[0] column_key = column[0]
self._write_data(data[column_key], data['index'], column[1]) self._write_data(data[column_key], data['index'], column[1])
def load_urls(self, url_list, func=None): def load_urls(self, url_list, func=None):
"""Load URLs from the url_list on the ListCtrl widget.
Args:
url_list (list): Python list that contains the URLs to add.
func (function): Callback function. Here it's used to add
the URLs on the download_manager.
"""
for url in url_list: for url in url_list:
url = url.replace(' ', '') url = url.replace(' ', '')
@ -368,32 +476,51 @@ class ListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
if func is not None: if func is not None:
# Custom hack to add url into download_manager # Custom hack to add url into download_manager
# i am gonna change this
item = self._get_item(self._list_index - 1) item = self._get_item(self._list_index - 1)
func(item) func(item)
def has_url(self, url): def has_url(self, url):
''' Return True if url in ListCtrl, else return False. '''
"""Returns True if url is aleady in the ListCtrl
else returns False.
Args:
url (string): URL string.
"""
return url in self._url_list return url in self._url_list
def add_url(self, url): def add_url(self, url):
''' Add url on ListCtrl. '''
"""Adds the given url in the ListCtrl.
Args:
url (string): URL string.
"""
self.InsertStringItem(self._list_index, url) self.InsertStringItem(self._list_index, url)
self._url_list.add(url) self._url_list.add(url)
self._list_index += 1 self._list_index += 1
def clear(self): def clear(self):
''' Clear ListCtrl & reset self._list_index. '''
"""Clear ListCtrl widget & reset self._list_index and
self._url_list.
"""
self.DeleteAllItems() self.DeleteAllItems()
self._list_index = 0 self._list_index = 0
self._url_list = set() self._url_list = set()
def is_empty(self): def is_empty(self):
''' Return True if list is empty. '''
"""Returns True if the list is empty else False. """
return self._list_index == 0 return self._list_index == 0
def get_items(self): def get_items(self):
''' Return list of items in ListCtrl. '''
"""Returns a list of items in ListCtrl.
Returns:
List of dictionaries that contains the 'url' and the
'index' (row) for each item of the ListCtrl.
"""
items = [] items = []
for row in xrange(self._list_index): for row in xrange(self._list_index):
@ -403,17 +530,31 @@ class ListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
return items return items
def _write_data(self, data, row, column): def _write_data(self, data, row, column):
''' Write data on row, column. '''
"""Write data on row-column. """
if isinstance(data, basestring): if isinstance(data, basestring):
self.SetStringItem(row, column, data) self.SetStringItem(row, column, data)
def _get_item(self, index): def _get_item(self, index):
''' Return single item base on index. '''
"""Returns corresponding ListCtrl item for the given index.
Args:
index (int): Index that identifies the row of the item.
Index must be smaller than the current self._list_index.
Returns:
Dictionary that contains the URL string of the row and the
row number (index).
"""
item = self.GetItem(itemId=index, col=0) item = self.GetItem(itemId=index, col=0)
data = dict(url=item.GetText(), index=index) data = dict(url=item.GetText(), index=index)
return data return data
def _set_columns(self): def _set_columns(self):
"""Initializes ListCtrl columns.
See MainFrame STATUSLIST_COLUMNS attribute for more info.
"""
for column in self.columns: for column in self.columns:
self.InsertColumn(column[1], column[2], width=column[3]) self.InsertColumn(column[1], column[2], width=column[3])
if column[4]: if column[4]:

Loading…
Cancel
Save