diff --git a/youtube_dl_gui/OptionsHandler.py b/youtube_dl_gui/OptionsHandler.py index fd52c8e..57e3add 100644 --- a/youtube_dl_gui/OptionsHandler.py +++ b/youtube_dl_gui/OptionsHandler.py @@ -38,6 +38,8 @@ class OptionsHandler(): self.keepVideo = False self.audioFormat = "mp3" self.audioQuality = 5 + self.outputFormat = 'title' + self.outputTemplate = '%(uploader)s/%(title)s.%(ext)s' self.startTrack = 1 self.endTrack = 0 self.maxDownloads = 0 @@ -48,7 +50,7 @@ class OptionsHandler(): self.writeAutoSubs = False self.embedSubs = False self.subsLang = "English" - self.idAsName = False + self.openDownloadDir = False self.ignoreErrors = True self.writeDescription = False self.writeInfo = False @@ -112,31 +114,33 @@ class OptionsHandler(): self.keepVideo = opts[5] in ['True'] self.audioFormat = opts[6] self.audioQuality = int(opts[7]) - self.startTrack = int(opts[8]) - self.endTrack = int(opts[9]) - self.maxDownloads = int(opts[10]) - self.minFileSize = opts[11] - self.maxFileSize = opts[12] - self.writeSubs = opts[13] in ['True'] - self.writeAllSubs = opts[14] in ['True'] - self.writeAutoSubs = opts[15] in ['True'] - self.embedSubs = opts[16] in ['True'] - self.subsLang = opts[17] - self.idAsName = opts[18] in ['True'] - self.ignoreErrors = opts[19] in ['True'] - self.writeDescription = opts[20] in ['True'] - self.writeInfo = opts[21] in ['True'] - self.writeThumbnail = opts[22] in ['True'] - self.retries = int(opts[23]) - self.userAgent = opts[24] - self.referer = opts[25] - self.proxy = opts[26] - self.username = opts[27] - self.updatePath = opts[28].decode('utf8') - self.autoUpdate = opts[29] in ['True'] - self.cmdArgs = opts[30] - self.enableLog = opts[31] in ['True'] - self.writeTimeToLog = opts[32] in ['True'] + self.outputFormat = opts[8] + self.outputTemplate = opts[9] + self.startTrack = int(opts[10]) + self.endTrack = int(opts[11]) + self.maxDownloads = int(opts[12]) + self.minFileSize = opts[13] + self.maxFileSize = opts[14] + self.writeSubs = opts[15] in ['True'] + self.writeAllSubs = opts[16] in ['True'] + self.writeAutoSubs = opts[17] in ['True'] + self.embedSubs = opts[18] in ['True'] + self.subsLang = opts[19] + self.openDownloadDir = opts[20] in ['True'] + self.ignoreErrors = opts[21] in ['True'] + self.writeDescription = opts[22] in ['True'] + self.writeInfo = opts[23] in ['True'] + self.writeThumbnail = opts[24] in ['True'] + self.retries = int(opts[25]) + self.userAgent = opts[26] + self.referer = opts[27] + self.proxy = opts[28] + self.username = opts[29] + self.updatePath = opts[30].decode('utf8') + self.autoUpdate = opts[31] in ['True'] + self.cmdArgs = opts[32] + self.enableLog = opts[33] in ['True'] + self.writeTimeToLog = opts[34] in ['True'] except: self.statusBarWrite('Error while loading settings file. Loading default settings.') self.load_default() @@ -155,6 +159,8 @@ class OptionsHandler(): f.write('KeepVideo='+str(self.keepVideo)+'\n') f.write('AudioFormat='+str(self.audioFormat)+'\n') f.write('AudioQuality='+str(self.audioQuality)+'\n') + f.write('OutputFormat='+str(self.outputFormat)+'\n') + f.write('OutputTemplate='+str(self.outputTemplate)+'\n') f.write('StartTrack='+str(self.startTrack)+'\n') f.write('EndTrack='+str(self.endTrack)+'\n') f.write('MaxDownloads='+str(self.maxDownloads)+'\n') @@ -165,7 +171,7 @@ class OptionsHandler(): f.write('WriteAutoSubtitles='+str(self.writeAutoSubs)+'\n') f.write('EmbedSubs='+str(self.embedSubs)+'\n') f.write('SubtitlesLanguage='+str(self.subsLang)+'\n') - f.write('IdAsName='+str(self.idAsName)+'\n') + f.write('OpenDownloadDirectory='+str(self.openDownloadDir)+'\n') f.write('IgnoreErrors='+str(self.ignoreErrors)+'\n') f.write('WriteDescription='+str(self.writeDescription)+'\n') f.write('WriteInfo='+str(self.writeInfo)+'\n') diff --git a/youtube_dl_gui/Utils.py b/youtube_dl_gui/Utils.py index 8b5eedc..65c2fc4 100644 --- a/youtube_dl_gui/Utils.py +++ b/youtube_dl_gui/Utils.py @@ -3,6 +3,7 @@ import os import sys import locale +import subprocess def remove_empty_items(array): return [x for x in array if x != ''] @@ -84,3 +85,9 @@ def icon_path(icon_path, file_path): def get_filename(path): return path.split(get_path_seperator())[-1] +def open_dir(path): + if os.name == 'nt': + os.startfile(path) + else: + subprocess.call(('xdg-open', path)) + diff --git a/youtube_dl_gui/YoutubeDLGUI.py b/youtube_dl_gui/YoutubeDLGUI.py index 167df0f..4bd00e2 100644 --- a/youtube_dl_gui/YoutubeDLGUI.py +++ b/youtube_dl_gui/YoutubeDLGUI.py @@ -38,6 +38,7 @@ from .Utils import ( fix_path, abs_path, icon_path, + open_dir, remove_spaces ) @@ -182,6 +183,11 @@ class MainFrame(wx.Frame): self.downloadHandler = None self.urlList = [] self.finished_popup() + self.open_destination_dir() + + def open_destination_dir(self): + if self.optionsList.openDownloadDir: + open_dir(self.optionsList.savePath) def download_handler(self, msg): self.downloadHandler.handle(msg) @@ -768,6 +774,92 @@ class VideoPanel(wx.Panel): self.optList.videoFormat = self.videoFormatCombo.GetValue() self.optList.dashAudioFormat = self.dashAudioFormatCombo.GetValue() self.optList.clearDashFiles = self.clearDashFilesChk.GetValue() + +class OutputPanel(wx.Panel): + + win_box_border = 0 + + def __init__(self, parent, optList): + wx.Panel.__init__(self, parent) + + self.SetBoxBorder() + self.optList = optList + mainBoxSizer = wx.BoxSizer(wx.VERTICAL) + + idBox = wx.BoxSizer(wx.HORIZONTAL) + self.idAsNameChk = wx.CheckBox(self, label='ID as Name') + idBox.Add(self.idAsNameChk, flag = wx.LEFT, border=5) + mainBoxSizer.Add(idBox, flag = wx.TOP, border=15) + + titleBox = wx.BoxSizer(wx.HORIZONTAL) + self.titleBoxChk = wx.CheckBox(self, label='Title as Name') + titleBox.Add(self.titleBoxChk, flag = wx.LEFT, border=5) + mainBoxSizer.Add(titleBox, flag = wx.TOP, border=5+self.win_box_border) + + customChkBox = wx.BoxSizer(wx.HORIZONTAL) + self.customTitleChk = wx.CheckBox(self, label='Custom Template (youtube-dl)') + customChkBox.Add(self.customTitleChk, flag = wx.LEFT, border=5) + mainBoxSizer.Add(customChkBox, flag = wx.TOP, border=5+self.win_box_border) + + mainBoxSizer.Add((-1, 10)) + + customBox = wx.BoxSizer(wx.HORIZONTAL) + self.customTitleBox = wx.TextCtrl(self) + customBox.Add(self.customTitleBox, 1, flag = wx.RIGHT, border=300) + mainBoxSizer.Add(customBox, flag = wx.EXPAND | wx.LEFT, border=5) + + self.SetSizer(mainBoxSizer) + + self.Bind(wx.EVT_CHECKBOX, self.OnId, self.idAsNameChk) + self.Bind(wx.EVT_CHECKBOX, self.OnTitle, self.titleBoxChk) + self.Bind(wx.EVT_CHECKBOX, self.OnCustom, self.customTitleChk) + + def OnId(self, event): + self.group_load('id') + + def OnTitle(self, event): + self.group_load('title') + + def OnCustom(self, event): + self.group_load('custom') + + def SetBoxBorder(self): + ''' Set border for windows ''' + if get_os_type() == 'nt': + self.win_box_border = 10 + + def group_load(self, oformat): + if oformat == 'id': + self.idAsNameChk.SetValue(True) + self.titleBoxChk.SetValue(False) + self.customTitleChk.SetValue(False) + self.customTitleBox.Disable() + elif oformat == 'title': + self.idAsNameChk.SetValue(False) + self.titleBoxChk.SetValue(True) + self.customTitleChk.SetValue(False) + self.customTitleBox.Disable() + elif oformat == 'custom': + self.idAsNameChk.SetValue(False) + self.titleBoxChk.SetValue(False) + self.customTitleChk.SetValue(True) + self.customTitleBox.Enable() + + def get_output_format(self): + if self.idAsNameChk.GetValue(): + return 'id' + elif self.titleBoxChk.GetValue(): + return 'title' + elif self.customTitleChk.GetValue(): + return 'custom' + + def load_options(self): + self.group_load(self.optList.outputFormat) + self.customTitleBox.SetValue(self.optList.outputTemplate) + + def save_options(self): + self.optList.outputTemplate = self.customTitleBox.GetValue() + self.optList.outputFormat = self.get_output_format() class FilesystemPanel(wx.Panel): @@ -796,15 +888,10 @@ class FilesystemPanel(wx.Panel): self.win_box_border = 15 def SetLeftBox(self, box): - idBox = wx.BoxSizer(wx.HORIZONTAL) - self.idAsNameChk = wx.CheckBox(self, label='ID as Name') - idBox.Add(self.idAsNameChk, flag = wx.LEFT, border=5) - box.Add(idBox, flag = wx.TOP, border=20) - ignrBox = wx.BoxSizer(wx.HORIZONTAL) self.ignoreErrorsChk = wx.CheckBox(self, label='Ignore Errors') ignrBox.Add(self.ignoreErrorsChk, flag = wx.LEFT, border=5) - box.Add(ignrBox, flag = wx.TOP, border=5+self.win_box_border) + box.Add(ignrBox, flag = wx.TOP, border=20) wrtDescBox = wx.BoxSizer(wx.HORIZONTAL) self.writeDescriptionChk = wx.CheckBox(self, label='Write description to file') @@ -821,6 +908,11 @@ class FilesystemPanel(wx.Panel): wrtThumBox.Add(self.writeThumbnailChk, flag = wx.LEFT, border=5) box.Add(wrtThumBox, flag = wx.TOP, border=5+self.win_box_border) + openDirBox = wx.BoxSizer(wx.HORIZONTAL) + self.openDirChk = wx.CheckBox(self, label='Open destination folder when done') + openDirBox.Add(self.openDirChk, flag = wx.LEFT, border=5) + box.Add(openDirBox, flag = wx.TOP, border=5+self.win_box_border) + def SetRightBox(self, box): minBox = wx.BoxSizer(wx.HORIZONTAL) minBox.Add(wx.StaticText(self, label='Min'), flag = wx.RIGHT, border=12) @@ -839,7 +931,7 @@ class FilesystemPanel(wx.Panel): self.writeInfoChk.SetValue(self.optList.writeInfo) self.writeThumbnailChk.SetValue(self.optList.writeThumbnail) self.ignoreErrorsChk.SetValue(self.optList.ignoreErrors) - self.idAsNameChk.SetValue(self.optList.idAsName) + self.openDirChk.SetValue(self.optList.openDownloadDir) self.minFilesizeBox.SetValue(self.optList.minFileSize) self.maxFilesizeBox.SetValue(self.optList.maxFileSize) @@ -848,7 +940,7 @@ class FilesystemPanel(wx.Panel): self.optList.writeInfo = self.writeInfoChk.GetValue() self.optList.writeThumbnail = self.writeThumbnailChk.GetValue() self.optList.ignoreErrors = self.ignoreErrorsChk.GetValue() - self.optList.idAsName = self.idAsNameChk.GetValue() + self.optList.openDownloadDir = self.openDirChk.GetValue() self.optList.minFileSize = self.minFilesizeBox.GetValue() self.optList.maxFileSize = self.maxFilesizeBox.GetValue() self.check_input() @@ -1122,10 +1214,12 @@ class OptionsFrame(wx.Frame): self.authTab = AuthenticationPanel(notebook, self.optionsList) self.videoselTab = PlaylistPanel(notebook, self.optionsList) self.logTab = LogPanel(notebook, self.optionsList, logger) + self.outputTab = OutputPanel(notebook, self.optionsList) notebook.AddPage(self.generalTab, "General") notebook.AddPage(self.videoTab, "Video") notebook.AddPage(self.audioTab, "Audio") + notebook.AddPage(self.outputTab, "Output") notebook.AddPage(self.videoselTab, "Playlist") notebook.AddPage(self.subtitlesTab, "Subtitles") notebook.AddPage(self.filesysTab, "Filesystem") @@ -1173,6 +1267,7 @@ please do one of the following: self.authTab.load_options() self.videoselTab.load_options() self.logTab.load_options() + self.outputTab.load_options() def save_all_options(self): self.generalTab.save_options() @@ -1186,4 +1281,5 @@ please do one of the following: self.authTab.save_options() self.videoselTab.save_options() self.logTab.save_options() + self.outputTab.save_options() diff --git a/youtube_dl_gui/YoutubeDLInterpreter.py b/youtube_dl_gui/YoutubeDLInterpreter.py index 481ce01..05af4b0 100644 --- a/youtube_dl_gui/YoutubeDLInterpreter.py +++ b/youtube_dl_gui/YoutubeDLInterpreter.py @@ -153,10 +153,12 @@ class YoutubeDLInterpreter(): def set_output_opts(self): path = fix_path(self.optionsList.savePath) self.opts.append('-o') - if self.optionsList.idAsName: + if self.optionsList.outputFormat == 'id': self.opts.append(path + '%(id)s.%(ext)s') - else: + elif self.optionsList.outputFormat == 'title': self.opts.append(path + '%(title)s.%(ext)s') + elif self.optionsList.outputFormat == 'custom': + self.opts.append(path + self.optionsList.outputTemplate) def set_audio_opts(self): if self.optionsList.toAudio: