Browse Source

fixed playlist output

doc-issue-template
MrS0m30n3 10 years ago
parent
commit
d1d4f68e71
7 changed files with 191 additions and 89 deletions
  1. 20
      SIGNALS.txt
  2. 3
      setup.py
  3. 80
      youtube_dl_gui/DownloadThread.py
  4. 95
      youtube_dl_gui/SignalHandler.py
  5. 22
      youtube_dl_gui/Utils.py
  6. 58
      youtube_dl_gui/YoutubeDLGUI.py
  7. 2
      youtube_dl_gui/version.py

20
SIGNALS.txt

@ -4,9 +4,13 @@ Signals list, that DownloadManager thread sends (DownloadThread.py)
HANDLER
=======
YoutubeDLGUI.py
def download_handler(self, msg):
...
SignalHandler.py
class DownloadHandler()
def handle(self, msg):
.
.
.
SIGNALS
=======
@ -21,13 +25,15 @@ SIGNALS
['error', index]: Error occured url, index
['[youtube]', ..., index]: Pre-Processing for url, index
['playlist', data, index]: Playlist data for url, index
['[youtube]', index]: Pre-Processing for url, index
['[download]', ..., index]: Downloading url, index
['[download]', data, index]: Downloading url, index
['[ffmpeg]', ..., index]: Post-Processing for url, index
['[ffmpeg]', index]: Post-Processing for url, index
['ignore'] Do nothing
['ignore', index] Do nothing
EXAMPLES
========

3
setup.py

@ -1,9 +1,10 @@
#! /usr/bin/env python
from distutils.core import setup
from youtube_dl_gui import version
setup(name='Youtube-DLG',
version='0.2',
version=version.__version__,
description='Youtube-dl GUI',
author='Sotiris Papadopoulos',
author_email='ytubedlg@gmail.com',

80
youtube_dl_gui/DownloadThread.py

@ -9,6 +9,13 @@ from threading import Thread
from wx.lib.pubsub import setuparg1
from wx.lib.pubsub import pub as Publisher
from .Utils import (
remove_spaces,
string_to_array,
get_encoding,
encode_list
)
OS_TYPE = name
MAX_DOWNLOAD_THREADS = 3
PUBLISHER_TOPIC = 'download'
@ -73,17 +80,16 @@ class DownloadManager(Thread):
def check_queue(self, t=1):
for proc in self.procList:
if not self.running:
break
if not self.running: break
if not proc.isAlive():
return proc
sleep(t)
return None
def close(self):
CallAfter(Publisher.sendMessage, PUBLISHER_TOPIC, ['close', -1])
self.running = False
self.procNo = 0
self.running = False
CallAfter(Publisher.sendMessage, PUBLISHER_TOPIC, ['close', -1])
class ProcessWrapper(Thread):
@ -93,21 +99,22 @@ class ProcessWrapper(Thread):
self.index = index
self.url = url
self.proc = None
self.info = None
self.err = False
self.stopped = False
self.set_process_info()
self.err = False
self.start()
def run(self):
self.proc = subprocess.Popen(self.get_cmd(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=self.info)
self.proc = subprocess.Popen(self.get_cmd(),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
startupinfo=self.set_process_info())
# while subprocess is alive and NOT the current thread
while self.proc_is_alive():
# read output
output = self.read()
if output != '':
# process output
data = self.proc_output(output)
data = self.check_data(data)
if self.err:
CallAfter(Publisher.sendMessage, PUBLISHER_TOPIC, ['error', self.index])
else:
@ -117,8 +124,8 @@ class ProcessWrapper(Thread):
def close(self):
self.proc.kill()
CallAfter(Publisher.sendMessage, PUBLISHER_TOPIC, ['close', self.index])
self.stopped = True
CallAfter(Publisher.sendMessage, PUBLISHER_TOPIC, ['close', self.index])
def proc_is_alive(self):
return self.proc.poll() == None
@ -132,41 +139,40 @@ class ProcessWrapper(Thread):
return output.rstrip()
def proc_output(self, output):
data = self.remove_spaces(self.string_to_array(output))
data = remove_spaces(string_to_array(output))
data.append(self.index)
data = self.filter_data(data)
return data
def check_data(self, data):
''' check data for exceptions '''
def filter_data(self, data):
''' Filters data for output exceptions '''
filter_list = ['Destination:', '100%', 'Resuming']
if len(data) > 3:
if data[1] == "UnicodeWarning:":
self.err = False
return ['ignore']
if data[0] == "[download]" and data[1] == "Destination:":
return ['ignore']
if data[0] == "[download]" and data[1] == "100%":
return ['ignore']
if data[0] == "[download]" and len(data[1]) > 10:
return ['ignore']
if data[0] == "[download]" and data[1] == "Resuming":
return ['ignore']
if data[0] == '[download]':
if data[1] in filter_list or len(data[1]) > 11:
return ['ignore', self.index]
if data[1] == 'Downloading':
if data[2] == 'video':
return ['playlist', data[3], data[5], self.index]
else:
return ['ignore', self.index]
else:
if data[1] == 'UnicodeWarning:':
self.err = False
return ['ignore', self.index]
return data
def get_cmd(self):
data = self.options + [self.url]
if OS_TYPE == 'nt':
enc = sys.getfilesystemencoding()
data = [x.encode(enc, 'ignore') for x in data]
return data
enc = get_encoding()
if enc != None:
data = encode_list(self.options + [self.url], enc)
return self.options + [self.url]
def string_to_array(self, string):
return string.split(' ')
def remove_spaces(self, array):
return [x for x in array if x != '']
def set_process_info(self):
if OS_TYPE == 'nt':
self.info = subprocess.STARTUPINFO()
self.info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
info = subprocess.STARTUPINFO()
info.dwFlags |= subprocess.STARTF_USESHOWWINDOW
return info
else:
return None

95
youtube_dl_gui/SignalHandler.py

@ -0,0 +1,95 @@
#! /usr/bin/env python
class DownloadHandler():
def __init__(self, ListCtrl):
self.ListCtrl = ListCtrl
self.finished = False
self.close = False
self.handlers = []
def _has_closed(self):
return self.close
def _has_finished(self):
return self.finished
def handle(self, msg):
''' Handles msg base to Signals.txt '''
data = msg.data
index = self.get_index(data)
if index == -1:
if data[0] == 'finish':
self.finished = True
elif data[0] == 'close':
self.close = True
else:
''' Manage handlers for its index '''
if index == len(self.handlers):
''' Create new IndexDownloadHandler and add it to handlers '''
self.handlers.append(IndexDownloadHandler(self.ListCtrl, index))
''' Let IndexDownloadHandler handle message data for current index '''
self.handlers[index].handle(data)
def get_index(self, data):
return data.pop()
class IndexDownloadHandler():
def __init__(self, ListCtrl, index):
self.ListCtrl = ListCtrl
self.index = index
self.info = ''
def handle(self, data):
''' Handle its data message for current index '''
if data[0] == 'finish':
self.finish()
elif data[0] == 'close':
self.close()
elif data[0] == 'error':
self.error()
elif data[0] == 'playlist':
self.playlist(data)
elif data[0] == '[youtube]':
self.pre_proc()
elif data[0] == '[download]':
self.download(data)
elif data[0] == '[ffmpeg]':
self.post_proc()
def finish(self):
self.ListCtrl._write_data(self.index, 4, '')
self.ListCtrl._write_data(self.index, 5, 'Finished')
def close(self):
self.ListCtrl._write_data(self.index, 3, '')
self.ListCtrl._write_data(self.index, 4, '')
self.ListCtrl._write_data(self.index, 5, 'Stopped')
def error(self):
self.ListCtrl._write_data(self.index, 3, '')
self.ListCtrl._write_data(self.index, 4, '')
self.ListCtrl._write_data(self.index, 5, 'Error')
def pre_proc(self):
self.ListCtrl._write_data(self.index, 5, 'Pre-Processing %s' % self.info)
def post_proc(self):
self.ListCtrl._write_data(self.index, 4, '')
self.ListCtrl._write_data(self.index, 5, 'Converting to Audio %s' % self.info)
def download(self, data):
self.ListCtrl._write_data(self.index, 1, data[3])
self.ListCtrl._write_data(self.index, 2, data[1])
self.ListCtrl._write_data(self.index, 3, data[7])
self.ListCtrl._write_data(self.index, 4, data[5])
self.ListCtrl._write_data(self.index, 5, 'Downloading %s' % self.info)
def playlist(self, data):
self.ListCtrl._write_data(self.index, 1, '')
self.ListCtrl._write_data(self.index, 2, '')
self.ListCtrl._write_data(self.index, 3, '')
self.ListCtrl._write_data(self.index, 4, '')
self.info = '%s/%s' % (data[1], data[2])

22
youtube_dl_gui/Utils.py

@ -0,0 +1,22 @@
#! /usr/bin/env python
import sys
def remove_spaces(array):
return [x for x in array if x != '']
def string_to_array(string, char=' '):
return string.split(char)
def get_encoding():
if sys.version_info >= (3, 0):
return None
if sys.platform == 'win32':
return sys.getfilesystemencoding()
else:
return None
def encode_list(data_list, encoding):
return [x.encode(encoding, 'ignore') for x in data_list]

58
youtube_dl_gui/YoutubeDLGUI.py

@ -24,6 +24,7 @@ from .UpdateThread import UpdateThread
from .DownloadThread import DownloadManager
from .OptionsHandler import OptionsHandler
from .YoutubeDLInterpreter import YoutubeDLInterpreter
from .SignalHandler import DownloadHandler
if os.name == 'nt':
YOUTUBE_DL_FILENAME = 'youtube-dl.exe'
@ -93,8 +94,9 @@ class MainFrame(wx.Frame):
# set publisher for download thread
Publisher.subscribe(self.download_handler, "download")
# init options object
# init Options and DownloadHandler objects
self.optionsList = OptionsHandler()
self.downloadHandler = None
# init some thread variables
self.downloadThread = None
@ -122,47 +124,16 @@ class MainFrame(wx.Frame):
self.statusBar.SetLabel(msg)
def download_handler(self, msg):
''' Handles msg base into signals see SIGNALS.txt for more info'''
if msg.data[0] == 'finish':
index = msg.data.pop()
if index == -1:
self.status_bar_write('Done')
self.downloadButton.SetLabel('Download')
self.updateButton.Enable()
self.downloadThread = None
self.urlList = []
else:
self.statusList._write_data(index, 4, '')
self.statusList._write_data(index, 5, 'Finished')
elif msg.data[0] == 'close':
index = msg.data.pop()
if index == -1:
self.status_bar_write('Stoping downloads')
else:
self.statusList._write_data(index, 3, '')
self.statusList._write_data(index, 4, '')
self.statusList._write_data(index, 5, 'Stopped')
elif msg.data[0] == 'error':
index = msg.data.pop()
self.statusList._write_data(index, 3, '')
self.statusList._write_data(index, 4, '')
self.statusList._write_data(index, 5, 'Error')
elif msg.data[0] == '[youtube]':
index = msg.data.pop()
self.statusList._write_data(index, 5, 'Pre-Processing')
elif msg.data[0] == '[download]':
index = msg.data.pop()
self.statusList._write_data(index, 1, msg.data[3])
self.statusList._write_data(index, 2, msg.data[1])
self.statusList._write_data(index, 3, msg.data[7])
self.statusList._write_data(index, 4, msg.data[5])
self.statusList._write_data(index, 5, 'Downloading')
elif msg.data[0] == '[ffmpeg]':
index = msg.data.pop()
self.statusList._write_data(index, 4, '')
self.statusList._write_data(index, 5, 'Converting to Audio')
else: # ['ignore'] or anything else
pass # do nothing
self.downloadHandler.handle(msg)
if self.downloadHandler._has_closed():
self.status_bar_write('Stoping downloads')
if self.downloadHandler._has_finished():
self.status_bar_write('Done')
self.downloadButton.SetLabel('Download')
self.updateButton.Enable()
self.downloadThread = None
self.urlList = []
self.downloadHandler = None
def update_handler(self, msg):
if msg.data == 'finish':
@ -187,6 +158,7 @@ class MainFrame(wx.Frame):
options = YoutubeDLInterpreter(self.optionsList, YOUTUBE_DL_FILENAME).get_options()
self.status_bar_write('Download started')
self.downloadThread = DownloadManager(options, self.statusList._get_items())
self.downloadHandler = DownloadHandler(self.statusList)
self.downloadButton.SetLabel('Stop')
self.updateButton.Disable()
@ -238,7 +210,7 @@ class ListCtrl(wx.ListCtrl):
self.InsertColumn(2, 'Percent', width=80)
self.InsertColumn(3, 'ETA', width=50)
self.InsertColumn(4, 'Speed', width=90)
self.InsertColumn(5, 'Status', width=120)
self.InsertColumn(5, 'Status', width=150)
self.ListIndex = 0
''' Add single item on list '''

2
youtube_dl_gui/version.py

@ -1 +1 @@
__version__ = '0.2'
__version__ = '0.2.1'
Loading…
Cancel
Save