You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1196 lines
46 KiB

11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
  1. #! /usr/bin/env python
  2. import wx
  3. from wx.lib.pubsub import setuparg1
  4. from wx.lib.pubsub import pub as Publisher
  5. from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
  6. from .version import __version__
  7. from .UpdateThread import UpdateThread
  8. from .DownloadThread import DownloadManager
  9. from .OptionsHandler import OptionsHandler
  10. from .YoutubeDLInterpreter import YoutubeDLInterpreter
  11. from .OutputHandler import DownloadHandler
  12. from .LogManager import LogManager, LogGUI
  13. from .Utils import (
  14. video_is_dash,
  15. have_dash_audio,
  16. get_os_type,
  17. file_exist,
  18. fix_path,
  19. abs_path,
  20. open_dir,
  21. remove_spaces
  22. )
  23. from .data import (
  24. __author__,
  25. __projecturl__,
  26. __appname__,
  27. __licensefull__,
  28. __descriptionfull__
  29. )
  30. if get_os_type() == 'nt':
  31. YOUTUBE_DL_FILENAME = 'youtube-dl.exe'
  32. else:
  33. YOUTUBE_DL_FILENAME = 'youtube-dl'
  34. AUDIOFORMATS = ["mp3", "wav", "aac", "m4a"]
  35. VIDEOFORMATS = ["default",
  36. "mp4 [1280x720]",
  37. "mp4 [640x360]",
  38. "webm [640x360]",
  39. "flv [400x240]",
  40. "3gp [320x240]",
  41. "mp4 1080p(DASH)",
  42. "mp4 720p(DASH)",
  43. "mp4 480p(DASH)",
  44. "mp4 360p(DASH)"]
  45. DASH_AUDIO_FORMATS = ["NO SOUND",
  46. "DASH m4a audio 128k",
  47. "DASH webm audio 48k"]
  48. LANGUAGES = ["English",
  49. "Greek",
  50. "Portuguese",
  51. "French",
  52. "Italian",
  53. "Russian",
  54. "Spanish",
  55. "German"]
  56. ICON = fix_path(abs_path(__file__))+'icons/youtube-dl-gui.png'
  57. class MainFrame(wx.Frame):
  58. def __init__(self, parent=None, id=-1):
  59. wx.Frame.__init__(self, parent, id, __appname__+' '+__version__, size=(600, 420))
  60. # init gui
  61. self.InitGUI()
  62. # bind events
  63. self.Bind(wx.EVT_BUTTON, self.OnDownload, self.downloadButton)
  64. self.Bind(wx.EVT_BUTTON, self.OnUpdate, self.updateButton)
  65. self.Bind(wx.EVT_BUTTON, self.OnOptions, self.optionsButton)
  66. self.Bind(wx.EVT_TEXT, self.OnTrackListChange, self.trackList)
  67. self.Bind(wx.EVT_CLOSE, self.OnClose)
  68. # set app icon
  69. icon = wx.Icon(ICON, wx.BITMAP_TYPE_ICO)
  70. self.SetIcon(icon)
  71. # set publisher for update thread
  72. Publisher.subscribe(self.update_handler, "update")
  73. # set publisher for download thread
  74. Publisher.subscribe(self.download_handler, "download")
  75. # init Options and DownloadHandler objects
  76. self.optionsList = OptionsHandler(self.status_bar_write)
  77. self.downloadHandler = None
  78. # init log manager
  79. self.logManager = None
  80. if self.optionsList.enableLog:
  81. self.logManager = LogManager(
  82. self.optionsList.get_config_path(),
  83. self.optionsList.writeTimeToLog
  84. )
  85. # init some thread variables
  86. self.downloadThread = None
  87. self.updateThread = None
  88. # init urlList for evt_text on self.trackList
  89. self.urlList = []
  90. def InitGUI(self):
  91. self.panel = wx.Panel(self)
  92. mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
  93. urlTextBox = wx.BoxSizer(wx.HORIZONTAL)
  94. urlTextBox.Add(wx.StaticText(self.panel, label='URLs'), flag = wx.TOP, border=10)
  95. mainBoxSizer.Add(urlTextBox, flag = wx.LEFT, border=20)
  96. trckListBox = wx.BoxSizer(wx.HORIZONTAL)
  97. self.trackList = wx.TextCtrl(self.panel, size=(-1, 120), style = wx.TE_MULTILINE | wx.TE_DONTWRAP)
  98. trckListBox.Add(self.trackList, 1)
  99. mainBoxSizer.Add(trckListBox, flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border=20)
  100. buttonsBox = wx.BoxSizer(wx.HORIZONTAL)
  101. self.downloadButton = wx.Button(self.panel, label='Download', size=(90, 30))
  102. buttonsBox.Add(self.downloadButton)
  103. self.updateButton = wx.Button(self.panel, label='Update', size=(90, 30))
  104. buttonsBox.Add(self.updateButton, flag = wx.LEFT | wx.RIGHT, border=80)
  105. self.optionsButton = wx.Button(self.panel, label='Options', size=(90, 30))
  106. buttonsBox.Add(self.optionsButton)
  107. mainBoxSizer.Add(buttonsBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.BOTTOM | wx.TOP, border=10)
  108. stListBox = wx.BoxSizer(wx.HORIZONTAL)
  109. self.statusList = ListCtrl(self.panel, style = wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES)
  110. stListBox.Add(self.statusList, 1, flag = wx.EXPAND)
  111. mainBoxSizer.Add(stListBox, 1, flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border=20)
  112. stBarBox = wx.BoxSizer(wx.HORIZONTAL)
  113. self.statusBar = wx.StaticText(self.panel, label='Author: '+__author__)
  114. stBarBox.Add(self.statusBar, flag = wx.TOP | wx.BOTTOM, border=5)
  115. mainBoxSizer.Add(stBarBox, flag = wx.LEFT, border=20)
  116. self.panel.SetSizer(mainBoxSizer)
  117. def check_if_youtube_dl_exist(self):
  118. path = fix_path(self.optionsList.updatePath)+YOUTUBE_DL_FILENAME
  119. if not file_exist(path):
  120. self.status_bar_write("Youtube-dl is missing, trying to download it...")
  121. self.update_youtube_dl()
  122. def update_youtube_dl(self):
  123. self.downloadButton.Disable()
  124. self.updateThread = UpdateThread(self.optionsList.updatePath, YOUTUBE_DL_FILENAME)
  125. def status_bar_write(self, msg):
  126. self.statusBar.SetLabel(msg)
  127. def fin_task(self, msg):
  128. self.status_bar_write(msg)
  129. self.downloadButton.SetLabel('Download')
  130. self.updateButton.Enable()
  131. self.downloadThread.join()
  132. self.downloadThread = None
  133. self.downloadHandler = None
  134. self.urlList = []
  135. self.finished_popup()
  136. self.open_destination_dir()
  137. def open_destination_dir(self):
  138. if self.optionsList.openDownloadDir:
  139. open_dir(self.optionsList.savePath)
  140. def download_handler(self, msg):
  141. self.downloadHandler.handle(msg)
  142. if self.downloadHandler._has_closed():
  143. self.status_bar_write('Stoping downloads')
  144. if self.downloadHandler._has_finished():
  145. if self.downloadHandler._has_error():
  146. if self.logManager != None:
  147. msg = 'An error occured while downloading. See Options>Log.'
  148. else:
  149. msg = 'An error occured while downloading'
  150. else:
  151. msg = 'Done'
  152. self.fin_task(msg)
  153. def update_handler(self, msg):
  154. if msg.data == 'finish':
  155. self.downloadButton.Enable()
  156. self.updateThread.join()
  157. self.updateThread = None
  158. else:
  159. self.status_bar_write(msg.data)
  160. def stop_download(self):
  161. self.downloadThread.close()
  162. def load_tracklist(self, trackList):
  163. for url in trackList:
  164. url = remove_spaces(url)
  165. if url != '':
  166. self.urlList.append(url)
  167. self.statusList._add_item(url)
  168. def start_download(self):
  169. self.statusList._clear_list()
  170. self.load_tracklist(self.trackList.GetValue().split('\n'))
  171. if not self.statusList._is_empty():
  172. self.check_if_youtube_dl_exist()
  173. if self.updateThread is not None:
  174. self.updateThread.join()
  175. options = YoutubeDLInterpreter(self.optionsList, YOUTUBE_DL_FILENAME).get_options()
  176. self.downloadThread = DownloadManager(
  177. options,
  178. self.statusList._get_items(),
  179. self.optionsList.clearDashFiles,
  180. self.logManager
  181. )
  182. self.downloadHandler = DownloadHandler(self.statusList)
  183. self.status_bar_write('Download started')
  184. self.downloadButton.SetLabel('Stop')
  185. self.updateButton.Disable()
  186. else:
  187. self.no_url_popup()
  188. def save_options(self):
  189. self.optionsList.save_to_file()
  190. def finished_popup(self):
  191. wx.MessageBox('Downloads completed.', 'Info', wx.OK | wx.ICON_INFORMATION)
  192. def no_url_popup(self):
  193. wx.MessageBox('You need to provide at least one url.', 'Error', wx.OK | wx.ICON_EXCLAMATION)
  194. def OnTrackListChange(self, event):
  195. if self.downloadThread != None:
  196. ''' Get current url list from trackList textCtrl '''
  197. curList = self.trackList.GetValue().split('\n')
  198. ''' For each url in current url list '''
  199. for url in curList:
  200. ''' Remove spaces from url '''
  201. url = remove_spaces(url)
  202. ''' If url is not in self.urlList (original downloads list) and url is not empty '''
  203. if url not in self.urlList and url != '':
  204. ''' Add url into original download list '''
  205. self.urlList.append(url)
  206. ''' Add handler for url '''
  207. self.downloadHandler._add_empty_handler()
  208. ''' Add url into statusList '''
  209. self.statusList._add_item(url)
  210. ''' Retrieve last item as {url:url, index:indexNo} '''
  211. item = self.statusList._get_last_item()
  212. ''' Pass that item into downloadThread '''
  213. self.downloadThread._add_download_item(item)
  214. def OnDownload(self, event):
  215. if self.downloadThread != None:
  216. self.stop_download()
  217. else:
  218. self.start_download()
  219. def OnUpdate(self, event):
  220. if (self.downloadThread == None and self.updateThread == None):
  221. self.update_youtube_dl()
  222. def OnOptions(self, event):
  223. optionsFrame = OptionsFrame(self.optionsList, parent=self, logger=self.logManager)
  224. optionsFrame.Show()
  225. def OnClose(self, event):
  226. if self.downloadThread != None:
  227. self.downloadThread.close(kill=True)
  228. self.downloadThread.join()
  229. self.save_options()
  230. self.Destroy()
  231. class ListCtrl(wx.ListCtrl, ListCtrlAutoWidthMixin):
  232. ''' Custom ListCtrl class '''
  233. def __init__(self, parent=None, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0):
  234. wx.ListCtrl.__init__(self, parent, id, pos, size, style)
  235. ListCtrlAutoWidthMixin.__init__(self)
  236. self.InsertColumn(0, 'Video', width=150)
  237. self.InsertColumn(1, 'Size', width=80)
  238. self.InsertColumn(2, 'Percent', width=65)
  239. self.InsertColumn(3, 'ETA', width=45)
  240. self.InsertColumn(4, 'Speed', width=90)
  241. self.InsertColumn(5, 'Status', width=160)
  242. self.setResizeColumn(0)
  243. self.ListIndex = 0
  244. ''' Add single item on list '''
  245. def _add_item(self, item):
  246. self.InsertStringItem(self.ListIndex, item)
  247. self.ListIndex += 1
  248. ''' Write data on index, column '''
  249. def _write_data(self, index, column, data):
  250. self.SetStringItem(index, column, data)
  251. ''' Clear list and set index to 0'''
  252. def _clear_list(self):
  253. self.DeleteAllItems()
  254. self.ListIndex = 0
  255. ''' Return True if list is empty '''
  256. def _is_empty(self):
  257. return self.ListIndex == 0
  258. ''' Get last item inserted, Returns dictionary '''
  259. def _get_last_item(self):
  260. data = {}
  261. last_item = self.GetItem(itemId=self.ListIndex-1, col=0)
  262. data['url'] = last_item.GetText()
  263. data['index'] = self.ListIndex-1
  264. return data
  265. ''' Retrieve all items [start, self.ListIndex), Returns list '''
  266. def _get_items(self, start=0):
  267. items = []
  268. for row in range(start, self.ListIndex):
  269. item = self.GetItem(itemId=row, col=0)
  270. data = {}
  271. data['url'] = item.GetText()
  272. data['index'] = row
  273. items.append(data)
  274. return items
  275. class LogPanel(wx.Panel):
  276. size = ''
  277. path = ''
  278. win_box_border = 0
  279. def __init__(self, parent, optList, log):
  280. wx.Panel.__init__(self, parent)
  281. self.SetBoxBorder()
  282. self.optList = optList
  283. self.log = log
  284. self.set_data()
  285. mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
  286. enLogBox = wx.BoxSizer(wx.HORIZONTAL)
  287. self.enableLogChk = wx.CheckBox(self, label='Enable Log')
  288. enLogBox.Add(self.enableLogChk)
  289. mainBoxSizer.Add(enLogBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=20+self.win_box_border)
  290. wrTimeBox = wx.BoxSizer(wx.HORIZONTAL)
  291. self.enableTimeChk = wx.CheckBox(self, label='Write Time')
  292. wrTimeBox.Add(self.enableTimeChk)
  293. mainBoxSizer.Add(wrTimeBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=5+self.win_box_border)
  294. butBox = wx.BoxSizer(wx.HORIZONTAL)
  295. self.clearLogButton = wx.Button(self, label='Clear Log')
  296. butBox.Add(self.clearLogButton)
  297. self.viewLogButton = wx.Button(self, label='View Log')
  298. butBox.Add(self.viewLogButton, flag = wx.LEFT, border=20)
  299. mainBoxSizer.Add(butBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=15)
  300. if self.optList.enableLog:
  301. self.SetDataSizers(mainBoxSizer)
  302. self.SetSizer(mainBoxSizer)
  303. self.Bind(wx.EVT_CHECKBOX, self.OnEnable, self.enableLogChk)
  304. self.Bind(wx.EVT_CHECKBOX, self.OnTime, self.enableTimeChk)
  305. self.Bind(wx.EVT_BUTTON, self.OnClear, self.clearLogButton)
  306. self.Bind(wx.EVT_BUTTON, self.OnView, self.viewLogButton)
  307. def SetBoxBorder(self):
  308. ''' Set border for windows '''
  309. if get_os_type() == 'nt':
  310. self.win_box_border = 10
  311. def SetDataSizers(self, box):
  312. logPathText = wx.BoxSizer(wx.HORIZONTAL)
  313. logPathText.Add(wx.StaticText(self, label='Path: ' + self.path))
  314. box.Add(logPathText, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=20)
  315. logSizeText = wx.BoxSizer(wx.HORIZONTAL)
  316. self.sizeText = wx.StaticText(self, label='Log Size: ' + self.size)
  317. logSizeText.Add(self.sizeText)
  318. box.Add(logSizeText, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=10)
  319. def set_data(self):
  320. if self.log != None:
  321. self.size = str(self.log.size()) + ' Bytes'
  322. self.path = self.log.path
  323. def OnTime(self, event):
  324. if self.log != None:
  325. self.log.add_time = self.enableTimeChk.GetValue()
  326. def OnEnable(self, event):
  327. if self.enableLogChk.GetValue():
  328. self.enableTimeChk.Enable()
  329. else:
  330. self.enableTimeChk.Disable()
  331. self.restart_popup()
  332. def OnClear(self, event):
  333. if self.log != None:
  334. self.log.clear()
  335. self.sizeText.SetLabel('Log Size: 0 Bytes')
  336. def OnView(self, event):
  337. if self.log != None:
  338. log_gui = LogGUI(self.path, parent=self)
  339. log_gui.Show()
  340. def load_options(self):
  341. self.enableLogChk.SetValue(self.optList.enableLog)
  342. self.enableTimeChk.SetValue(self.optList.writeTimeToLog)
  343. if self.optList.enableLog == False:
  344. self.enableTimeChk.Disable()
  345. if self.log == None:
  346. self.clearLogButton.Disable()
  347. self.viewLogButton.Disable()
  348. def save_options(self):
  349. self.optList.enableLog = self.enableLogChk.GetValue()
  350. self.optList.writeTimeToLog = self.enableTimeChk.GetValue()
  351. def restart_popup(self):
  352. wx.MessageBox('Please restart ' + __appname__, 'Restart', wx.OK | wx.ICON_INFORMATION)
  353. class PlaylistPanel(wx.Panel):
  354. def __init__(self, parent, optList):
  355. wx.Panel.__init__(self, parent)
  356. self.optList = optList
  357. mainBoxSizer = wx.StaticBoxSizer(wx.StaticBox(self, label='Playlist Options'), wx.VERTICAL)
  358. mainBoxSizer.Add((-1, 10))
  359. startBox = wx.BoxSizer(wx.HORIZONTAL)
  360. startBox.Add(wx.StaticText(self, label='Start'), flag = wx.RIGHT, border=32)
  361. self.startSpnr = wx.SpinCtrl(self, size=(60, -1))
  362. self.startSpnr.SetRange(1, 999)
  363. startBox.Add(self.startSpnr)
  364. mainBoxSizer.Add(startBox, flag = wx.TOP | wx.LEFT, border=20)
  365. stopBox = wx.BoxSizer(wx.HORIZONTAL)
  366. stopBox.Add(wx.StaticText(self, label='Stop'), flag = wx.RIGHT, border=34)
  367. self.stopSpnr = wx.SpinCtrl(self, size=(60, -1))
  368. self.stopSpnr.SetRange(0, 999)
  369. stopBox.Add(self.stopSpnr)
  370. mainBoxSizer.Add(stopBox, flag = wx.TOP | wx.LEFT, border=20)
  371. maxBox = wx.BoxSizer(wx.HORIZONTAL)
  372. maxBox.Add(wx.StaticText(self, label='Max DLs'), flag = wx.RIGHT, border=self.get_border())
  373. self.maxSpnr = wx.SpinCtrl(self, size=(60, -1))
  374. self.maxSpnr.SetRange(0, 999)
  375. maxBox.Add(self.maxSpnr)
  376. mainBoxSizer.Add(maxBox, flag = wx.TOP | wx.LEFT, border=20)
  377. self.SetSizer(mainBoxSizer)
  378. def get_border(self):
  379. if get_os_type() == 'nt':
  380. return 16
  381. return 10
  382. def load_options(self):
  383. self.startSpnr.SetValue(self.optList.startTrack)
  384. self.stopSpnr.SetValue(self.optList.endTrack)
  385. self.maxSpnr.SetValue(self.optList.maxDownloads)
  386. def save_options(self):
  387. self.optList.startTrack = self.startSpnr.GetValue()
  388. self.optList.endTrack = self.stopSpnr.GetValue()
  389. self.optList.maxDownloads = self.maxSpnr.GetValue()
  390. class ConnectionPanel(wx.Panel):
  391. def __init__(self, parent, optList):
  392. wx.Panel.__init__(self, parent)
  393. self.optList = optList
  394. mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
  395. retBox = wx.BoxSizer(wx.HORIZONTAL)
  396. retBox.Add(wx.StaticText(self, label='Retries'), flag = wx.RIGHT, border=8)
  397. self.retriesSpnr = wx.SpinCtrl(self, size=(50, -1))
  398. self.retriesSpnr.SetRange(1, 99)
  399. retBox.Add(self.retriesSpnr)
  400. mainBoxSizer.Add(retBox, flag = wx.LEFT | wx.TOP, border=10)
  401. uaText = wx.BoxSizer(wx.HORIZONTAL)
  402. uaText.Add(wx.StaticText(self, label='User Agent'), flag = wx.LEFT, border=15)
  403. mainBoxSizer.Add(uaText, flag = wx.TOP, border=10)
  404. mainBoxSizer.Add((-1, 5))
  405. uaBox = wx.BoxSizer(wx.HORIZONTAL)
  406. self.userAgentBox = wx.TextCtrl(self)
  407. uaBox.Add(self.userAgentBox, 1, flag = wx.LEFT, border=10)
  408. mainBoxSizer.Add(uaBox, flag = wx.EXPAND | wx.RIGHT, border=200)
  409. refText = wx.BoxSizer(wx.HORIZONTAL)
  410. refText.Add(wx.StaticText(self, label='Referer'), flag = wx.LEFT, border=15)
  411. mainBoxSizer.Add(refText, flag = wx.TOP, border=10)
  412. mainBoxSizer.Add((-1, 5))
  413. refBox = wx.BoxSizer(wx.HORIZONTAL)
  414. self.refererBox = wx.TextCtrl(self)
  415. refBox.Add(self.refererBox, 1, flag = wx.LEFT, border=10)
  416. mainBoxSizer.Add(refBox, flag = wx.EXPAND | wx.RIGHT, border=200)
  417. prxyText = wx.BoxSizer(wx.HORIZONTAL)
  418. prxyText.Add(wx.StaticText(self, label='Proxy'), flag = wx.LEFT, border=15)
  419. mainBoxSizer.Add(prxyText, flag = wx.TOP, border=10)
  420. mainBoxSizer.Add((-1, 5))
  421. prxyBox = wx.BoxSizer(wx.HORIZONTAL)
  422. self.proxyBox = wx.TextCtrl(self)
  423. prxyBox.Add(self.proxyBox, 1, flag = wx.LEFT, border=10)
  424. mainBoxSizer.Add(prxyBox, flag = wx.EXPAND | wx.RIGHT, border=100)
  425. self.SetSizer(mainBoxSizer)
  426. def load_options(self):
  427. self.userAgentBox.SetValue(self.optList.userAgent)
  428. self.refererBox.SetValue(self.optList.referer)
  429. self.proxyBox.SetValue(self.optList.proxy)
  430. self.retriesSpnr.SetValue(self.optList.retries)
  431. def save_options(self):
  432. self.optList.userAgent = self.userAgentBox.GetValue()
  433. self.optList.referer = self.refererBox.GetValue()
  434. self.optList.proxy = self.proxyBox.GetValue()
  435. self.optList.retries = self.retriesSpnr.GetValue()
  436. class AuthenticationPanel(wx.Panel):
  437. def __init__(self, parent, optList):
  438. wx.Panel.__init__(self,parent)
  439. self.optList = optList
  440. mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
  441. usrTextBox = wx.BoxSizer(wx.HORIZONTAL)
  442. usrTextBox.Add(wx.StaticText(self, label='Username'))
  443. mainBoxSizer.Add(usrTextBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=15)
  444. usrBox = wx.BoxSizer(wx.HORIZONTAL)
  445. self.usernameBox = wx.TextCtrl(self, size=(-1, 25))
  446. usrBox.Add(self.usernameBox, 1, flag = wx.TOP, border=5)
  447. mainBoxSizer.Add(usrBox, flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border=160)
  448. passTextBox = wx.BoxSizer(wx.HORIZONTAL)
  449. passTextBox.Add(wx.StaticText(self, label='Password'))
  450. mainBoxSizer.Add(passTextBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=15)
  451. passBox = wx.BoxSizer(wx.HORIZONTAL)
  452. self.passwordBox = wx.TextCtrl(self, size=(-1, 25), style = wx.TE_PASSWORD)
  453. passBox.Add(self.passwordBox, 1, flag = wx.TOP, border=5)
  454. mainBoxSizer.Add(passBox, flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border=160)
  455. vPassTextBox = wx.BoxSizer(wx.HORIZONTAL)
  456. vPassTextBox.Add(wx.StaticText(self, label='Video Password (vimeo, smotri)'))
  457. mainBoxSizer.Add(vPassTextBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=15)
  458. vPassBox = wx.BoxSizer(wx.HORIZONTAL)
  459. self.videopassBox = wx.TextCtrl(self, size=(-1, 25), style = wx.TE_PASSWORD)
  460. vPassBox.Add(self.videopassBox, 1, flag = wx.TOP, border=5)
  461. mainBoxSizer.Add(vPassBox, flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border=160)
  462. self.SetSizer(mainBoxSizer)
  463. def load_options(self):
  464. self.usernameBox.SetValue(self.optList.username)
  465. self.passwordBox.SetValue(self.optList.password)
  466. self.videopassBox.SetValue(self.optList.videoPass)
  467. def save_options(self):
  468. self.optList.username = self.usernameBox.GetValue()
  469. self.optList.password = self.passwordBox.GetValue()
  470. self.optList.videoPass = self.videopassBox.GetValue()
  471. class AudioPanel(wx.Panel):
  472. win_box_border = 0
  473. quality = ['high', 'mid', 'low']
  474. def __init__(self, parent, optList):
  475. wx.Panel.__init__(self, parent)
  476. self.SetBoxBorder()
  477. self.optList = optList
  478. mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
  479. toaBox = wx.BoxSizer(wx.HORIZONTAL)
  480. self.toAudioChk = wx.CheckBox(self, label='Convert to Audio')
  481. toaBox.Add(self.toAudioChk)
  482. mainBoxSizer.Add(toaBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=15+self.win_box_border)
  483. keepVBox = wx.BoxSizer(wx.HORIZONTAL)
  484. self.keepVideoChk = wx.CheckBox(self, label='Keep Video')
  485. keepVBox.Add(self.keepVideoChk)
  486. mainBoxSizer.Add(keepVBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=5+self.win_box_border)
  487. afTextBox = wx.BoxSizer(wx.HORIZONTAL)
  488. afTextBox.Add(wx.StaticText(self, label='Audio Format'))
  489. mainBoxSizer.Add(afTextBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=10)
  490. afComboBox = wx.BoxSizer(wx.HORIZONTAL)
  491. self.audioFormatCombo = wx.ComboBox(self, choices=AUDIOFORMATS, size=(160, 30))
  492. afComboBox.Add(self.audioFormatCombo)
  493. mainBoxSizer.Add(afComboBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=5)
  494. aqTextBox = wx.BoxSizer(wx.HORIZONTAL)
  495. aqTextBox.Add(wx.StaticText(self, label='Audio Quality'))
  496. mainBoxSizer.Add(aqTextBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=10)
  497. aqComboBox = wx.BoxSizer(wx.HORIZONTAL)
  498. self.audioQualityCombo = wx.ComboBox(self, choices=self.quality, size=(80, 25))
  499. aqComboBox.Add(self.audioQualityCombo)
  500. mainBoxSizer.Add(aqComboBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=5)
  501. self.SetSizer(mainBoxSizer)
  502. self.Bind(wx.EVT_CHECKBOX, self.OnAudioCheck, self.toAudioChk)
  503. def SetBoxBorder(self):
  504. ''' Set border for windows '''
  505. if get_os_type() == 'nt':
  506. self.win_box_border = 5
  507. def OnAudioCheck(self, event):
  508. if self.toAudioChk.GetValue():
  509. self.keepVideoChk.Enable()
  510. self.audioFormatCombo.Enable()
  511. self.audioQualityCombo.Enable()
  512. else:
  513. self.keepVideoChk.Disable()
  514. self.audioFormatCombo.Disable()
  515. self.audioQualityCombo.Disable()
  516. def load_options(self):
  517. self.toAudioChk.SetValue(self.optList.toAudio)
  518. self.keepVideoChk.SetValue(self.optList.keepVideo)
  519. self.audioFormatCombo.SetValue(self.optList.audioFormat)
  520. self.audioQualityCombo.SetValue(self.optList.audioQuality)
  521. if self.optList.toAudio == False:
  522. self.keepVideoChk.Disable()
  523. self.audioFormatCombo.Disable()
  524. self.audioQualityCombo.Disable()
  525. def save_options(self):
  526. self.optList.toAudio = self.toAudioChk.GetValue()
  527. self.optList.keepVideo = self.keepVideoChk.GetValue()
  528. self.optList.audioFormat = self.audioFormatCombo.GetValue()
  529. self.optList.audioQuality = self.audioQualityCombo.GetValue()
  530. class VideoPanel(wx.Panel):
  531. def __init__(self, parent, optList):
  532. wx.Panel.__init__(self, parent)
  533. self.optList = optList
  534. mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
  535. vfTextBox = wx.BoxSizer(wx.HORIZONTAL)
  536. vfTextBox.Add(wx.StaticText(self, label='Video Format'))
  537. mainBoxSizer.Add(vfTextBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=20)
  538. vfComboBox = wx.BoxSizer(wx.HORIZONTAL)
  539. self.videoFormatCombo = wx.ComboBox(self, choices=VIDEOFORMATS, size=(160, 30))
  540. vfComboBox.Add(self.videoFormatCombo)
  541. mainBoxSizer.Add(vfComboBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=5)
  542. daTextBox = wx.BoxSizer(wx.HORIZONTAL)
  543. daTextBox.Add(wx.StaticText(self, label='DASH Audio'))
  544. mainBoxSizer.Add(daTextBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=10)
  545. daComboBox = wx.BoxSizer(wx.HORIZONTAL)
  546. self.dashAudioFormatCombo = wx.ComboBox(self, choices=DASH_AUDIO_FORMATS, size=(160, 30))
  547. daComboBox.Add(self.dashAudioFormatCombo)
  548. mainBoxSizer.Add(daComboBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=5)
  549. clrDashBox = wx.BoxSizer(wx.HORIZONTAL)
  550. self.clearDashFilesChk = wx.CheckBox(self, label='Clear DASH audio/video files')
  551. clrDashBox.Add(self.clearDashFilesChk)
  552. mainBoxSizer.Add(clrDashBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=20)
  553. self.SetSizer(mainBoxSizer)
  554. self.Bind(wx.EVT_COMBOBOX, self.OnVideoFormatPick, self.videoFormatCombo)
  555. self.Bind(wx.EVT_COMBOBOX, self.OnAudioFormatPick, self.dashAudioFormatCombo)
  556. def OnAudioFormatPick(self, event):
  557. if have_dash_audio(self.dashAudioFormatCombo.GetValue()):
  558. self.clearDashFilesChk.Enable()
  559. else:
  560. self.clearDashFilesChk.SetValue(False)
  561. self.clearDashFilesChk.Disable()
  562. def OnVideoFormatPick(self, event):
  563. if video_is_dash(self.videoFormatCombo.GetValue()):
  564. self.dashAudioFormatCombo.Enable()
  565. if have_dash_audio(self.dashAudioFormatCombo.GetValue()):
  566. self.clearDashFilesChk.Enable()
  567. else:
  568. self.clearDashFilesChk.SetValue(False)
  569. self.clearDashFilesChk.Disable()
  570. self.dashAudioFormatCombo.Disable()
  571. def load_options(self):
  572. self.videoFormatCombo.SetValue(self.optList.videoFormat)
  573. self.dashAudioFormatCombo.SetValue(self.optList.dashAudioFormat)
  574. self.clearDashFilesChk.SetValue(self.optList.clearDashFiles)
  575. if not video_is_dash(self.optList.videoFormat):
  576. self.dashAudioFormatCombo.Disable()
  577. if not have_dash_audio(self.optList.dashAudioFormat):
  578. self.clearDashFilesChk.SetValue(False)
  579. self.clearDashFilesChk.Disable()
  580. def save_options(self):
  581. self.optList.videoFormat = self.videoFormatCombo.GetValue()
  582. self.optList.dashAudioFormat = self.dashAudioFormatCombo.GetValue()
  583. self.optList.clearDashFiles = self.clearDashFilesChk.GetValue()
  584. class OutputPanel(wx.Panel):
  585. win_box_border = 0
  586. def __init__(self, parent, optList):
  587. wx.Panel.__init__(self, parent)
  588. self.SetBoxBorder()
  589. self.optList = optList
  590. mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
  591. idBox = wx.BoxSizer(wx.HORIZONTAL)
  592. self.idAsNameChk = wx.CheckBox(self, label='ID as Name')
  593. idBox.Add(self.idAsNameChk, flag = wx.LEFT, border=5)
  594. mainBoxSizer.Add(idBox, flag = wx.TOP, border=15)
  595. titleBox = wx.BoxSizer(wx.HORIZONTAL)
  596. self.titleBoxChk = wx.CheckBox(self, label='Title as Name')
  597. titleBox.Add(self.titleBoxChk, flag = wx.LEFT, border=5)
  598. mainBoxSizer.Add(titleBox, flag = wx.TOP, border=5+self.win_box_border)
  599. customChkBox = wx.BoxSizer(wx.HORIZONTAL)
  600. self.customTitleChk = wx.CheckBox(self, label='Custom Template (youtube-dl)')
  601. customChkBox.Add(self.customTitleChk, flag = wx.LEFT, border=5)
  602. mainBoxSizer.Add(customChkBox, flag = wx.TOP, border=5+self.win_box_border)
  603. mainBoxSizer.Add((-1, 10))
  604. customBox = wx.BoxSizer(wx.HORIZONTAL)
  605. self.customTitleBox = wx.TextCtrl(self)
  606. customBox.Add(self.customTitleBox, 1, flag = wx.RIGHT, border=300)
  607. mainBoxSizer.Add(customBox, flag = wx.EXPAND | wx.LEFT, border=5)
  608. self.SetSizer(mainBoxSizer)
  609. self.Bind(wx.EVT_CHECKBOX, self.OnId, self.idAsNameChk)
  610. self.Bind(wx.EVT_CHECKBOX, self.OnTitle, self.titleBoxChk)
  611. self.Bind(wx.EVT_CHECKBOX, self.OnCustom, self.customTitleChk)
  612. def OnId(self, event):
  613. self.group_load('id')
  614. def OnTitle(self, event):
  615. self.group_load('title')
  616. def OnCustom(self, event):
  617. self.group_load('custom')
  618. def SetBoxBorder(self):
  619. ''' Set border for windows '''
  620. if get_os_type() == 'nt':
  621. self.win_box_border = 10
  622. def group_load(self, oformat):
  623. if oformat == 'id':
  624. self.idAsNameChk.SetValue(True)
  625. self.titleBoxChk.SetValue(False)
  626. self.customTitleChk.SetValue(False)
  627. self.customTitleBox.Disable()
  628. elif oformat == 'title':
  629. self.idAsNameChk.SetValue(False)
  630. self.titleBoxChk.SetValue(True)
  631. self.customTitleChk.SetValue(False)
  632. self.customTitleBox.Disable()
  633. elif oformat == 'custom':
  634. self.idAsNameChk.SetValue(False)
  635. self.titleBoxChk.SetValue(False)
  636. self.customTitleChk.SetValue(True)
  637. self.customTitleBox.Enable()
  638. def get_output_format(self):
  639. if self.idAsNameChk.GetValue():
  640. return 'id'
  641. elif self.titleBoxChk.GetValue():
  642. return 'title'
  643. elif self.customTitleChk.GetValue():
  644. return 'custom'
  645. def load_options(self):
  646. self.group_load(self.optList.outputFormat)
  647. self.customTitleBox.SetValue(self.optList.outputTemplate)
  648. def save_options(self):
  649. self.optList.outputTemplate = self.customTitleBox.GetValue()
  650. self.optList.outputFormat = self.get_output_format()
  651. class FilesystemPanel(wx.Panel):
  652. win_box_border = 0
  653. def __init__(self, parent, optList):
  654. wx.Panel.__init__(self, parent)
  655. self.SetBoxBorder()
  656. self.optList = optList
  657. mainBoxSizer = wx.BoxSizer(wx.HORIZONTAL)
  658. leftBoxSizer = wx.BoxSizer(wx.VERTICAL)
  659. rightBoxSizer = wx.StaticBoxSizer(wx.StaticBox(self, label='Filesize (e.g. 50k or 44.6m)'), wx.VERTICAL)
  660. self.SetLeftBox(leftBoxSizer)
  661. self.SetRightBox(rightBoxSizer)
  662. mainBoxSizer.Add(leftBoxSizer, 1, flag = wx.EXPAND | wx.ALL, border=10)
  663. mainBoxSizer.Add(rightBoxSizer, 1, flag = wx.EXPAND | wx.ALL, border=10)
  664. self.SetSizer(mainBoxSizer)
  665. def SetBoxBorder(self):
  666. ''' Set border for windows '''
  667. if get_os_type() == 'nt':
  668. self.win_box_border = 10
  669. def SetLeftBox(self, box):
  670. ignrBox = wx.BoxSizer(wx.HORIZONTAL)
  671. self.ignoreErrorsChk = wx.CheckBox(self, label='Ignore Errors')
  672. ignrBox.Add(self.ignoreErrorsChk, flag = wx.LEFT, border=5)
  673. box.Add(ignrBox, flag = wx.TOP, border=15)
  674. wrtDescBox = wx.BoxSizer(wx.HORIZONTAL)
  675. self.writeDescriptionChk = wx.CheckBox(self, label='Write description to file')
  676. wrtDescBox.Add(self.writeDescriptionChk, flag = wx.LEFT, border=5)
  677. box.Add(wrtDescBox, flag = wx.TOP, border=5+self.win_box_border)
  678. wrtInfoBox = wx.BoxSizer(wx.HORIZONTAL)
  679. self.writeInfoChk = wx.CheckBox(self, label='Write info to (.json) file')
  680. wrtInfoBox.Add(self.writeInfoChk, flag = wx.LEFT, border=5)
  681. box.Add(wrtInfoBox, flag = wx.TOP, border=5+self.win_box_border)
  682. wrtThumBox = wx.BoxSizer(wx.HORIZONTAL)
  683. self.writeThumbnailChk = wx.CheckBox(self, label='Write thumbnail to disk')
  684. wrtThumBox.Add(self.writeThumbnailChk, flag = wx.LEFT, border=5)
  685. box.Add(wrtThumBox, flag = wx.TOP, border=5+self.win_box_border)
  686. openDirBox = wx.BoxSizer(wx.HORIZONTAL)
  687. self.openDirChk = wx.CheckBox(self, label='Open destination folder when done')
  688. openDirBox.Add(self.openDirChk, flag = wx.LEFT, border=5)
  689. box.Add(openDirBox, flag = wx.TOP, border=5+self.win_box_border)
  690. def SetRightBox(self, box):
  691. minBox = wx.BoxSizer(wx.HORIZONTAL)
  692. minBox.Add(wx.StaticText(self, label='Min'), flag = wx.RIGHT, border=12)
  693. self.minFilesizeBox = wx.TextCtrl(self, size=(80, -1))
  694. minBox.Add(self.minFilesizeBox)
  695. box.Add(minBox, flag = wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, border=10)
  696. maxBox = wx.BoxSizer(wx.HORIZONTAL)
  697. maxBox.Add(wx.StaticText(self, label='Max'), flag = wx.RIGHT, border=8)
  698. self.maxFilesizeBox = wx.TextCtrl(self, size=(80, -1))
  699. maxBox.Add(self.maxFilesizeBox)
  700. box.Add(maxBox, flag = wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, border=10)
  701. def load_options(self):
  702. self.writeDescriptionChk.SetValue(self.optList.writeDescription)
  703. self.writeInfoChk.SetValue(self.optList.writeInfo)
  704. self.writeThumbnailChk.SetValue(self.optList.writeThumbnail)
  705. self.ignoreErrorsChk.SetValue(self.optList.ignoreErrors)
  706. self.openDirChk.SetValue(self.optList.openDownloadDir)
  707. self.minFilesizeBox.SetValue(self.optList.minFileSize)
  708. self.maxFilesizeBox.SetValue(self.optList.maxFileSize)
  709. def save_options(self):
  710. self.optList.writeDescription = self.writeDescriptionChk.GetValue()
  711. self.optList.writeInfo = self.writeInfoChk.GetValue()
  712. self.optList.writeThumbnail = self.writeThumbnailChk.GetValue()
  713. self.optList.ignoreErrors = self.ignoreErrorsChk.GetValue()
  714. self.optList.openDownloadDir = self.openDirChk.GetValue()
  715. self.optList.minFileSize = self.minFilesizeBox.GetValue()
  716. self.optList.maxFileSize = self.maxFilesizeBox.GetValue()
  717. self.check_input()
  718. def check_input(self):
  719. self.optList.minFileSize.replace('-', '')
  720. self.optList.maxFileSize.replace('-', '')
  721. if self.optList.minFileSize == '':
  722. self.optList.minFileSize = '0'
  723. if self.optList.maxFileSize == '':
  724. self.optList.maxFileSize = '0'
  725. class SubtitlesPanel(wx.Panel):
  726. win_box_border = 0
  727. def __init__(self, parent, optList):
  728. wx.Panel.__init__(self, parent)
  729. self.SetBoxBorder()
  730. self.optList = optList
  731. mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
  732. dlSubsBox = wx.BoxSizer(wx.HORIZONTAL)
  733. self.writeSubsChk = wx.CheckBox(self, label='Download subtitle file by language')
  734. dlSubsBox.Add(self.writeSubsChk, flag = wx.LEFT, border=10)
  735. mainBoxSizer.Add(dlSubsBox, flag = wx.TOP, border=15)
  736. dlAllSubBox = wx.BoxSizer(wx.HORIZONTAL)
  737. self.writeAllSubsChk = wx.CheckBox(self, label='Download all available subtitles')
  738. dlAllSubBox.Add(self.writeAllSubsChk, flag = wx.LEFT, border=10)
  739. mainBoxSizer.Add(dlAllSubBox, flag = wx.TOP, border=5+self.win_box_border)
  740. dlAutoSubBox = wx.BoxSizer(wx.HORIZONTAL)
  741. self.writeAutoSubsChk = wx.CheckBox(self, label='Download automatic subtitle file (YOUTUBE ONLY)')
  742. dlAutoSubBox.Add(self.writeAutoSubsChk, flag = wx.LEFT, border=10)
  743. mainBoxSizer.Add(dlAutoSubBox, flag = wx.TOP, border=5+self.win_box_border)
  744. embSubBox = wx.BoxSizer(wx.HORIZONTAL)
  745. self.embedSubsChk = wx.CheckBox(self, label='Embed subtitles in the video (only for mp4 videos)')
  746. self.embedSubsChk.Disable()
  747. embSubBox.Add(self.embedSubsChk, flag = wx.LEFT, border=10)
  748. mainBoxSizer.Add(embSubBox, flag = wx.TOP, border=5+self.win_box_border)
  749. slangTextBox = wx.BoxSizer(wx.HORIZONTAL)
  750. slangTextBox.Add(wx.StaticText(self, label='Subtitles Language'), flag = wx.LEFT, border=15)
  751. mainBoxSizer.Add(slangTextBox, flag = wx.TOP, border=10+self.win_box_border)
  752. slangBox = wx.BoxSizer(wx.HORIZONTAL)
  753. self.subsLangCombo = wx.ComboBox(self, choices=LANGUAGES, size=(140, 30))
  754. slangBox.Add(self.subsLangCombo, flag = wx.LEFT, border=10)
  755. mainBoxSizer.Add(slangBox, flag = wx.TOP, border=5)
  756. self.SetSizer(mainBoxSizer)
  757. self.Bind(wx.EVT_CHECKBOX, self.OnWriteSubsChk, self.writeSubsChk)
  758. self.Bind(wx.EVT_CHECKBOX, self.OnWriteAllSubsChk, self.writeAllSubsChk)
  759. self.Bind(wx.EVT_CHECKBOX, self.OnWriteAutoSubsChk, self.writeAutoSubsChk)
  760. def SetBoxBorder(self):
  761. ''' Set border for windows '''
  762. if get_os_type() == 'nt':
  763. self.win_box_border = 5
  764. def subs_are_on(self):
  765. return self.writeAutoSubsChk.GetValue() or self.writeSubsChk.GetValue()
  766. def OnWriteAutoSubsChk(self, event):
  767. if self.writeAutoSubsChk.GetValue():
  768. self.writeAllSubsChk.Disable()
  769. self.writeSubsChk.Disable()
  770. self.subsLangCombo.Disable()
  771. self.embedSubsChk.Enable()
  772. else:
  773. self.writeAllSubsChk.Enable()
  774. self.writeSubsChk.Enable()
  775. self.subsLangCombo.Enable()
  776. self.embedSubsChk.Disable()
  777. self.embedSubsChk.SetValue(False)
  778. def OnWriteSubsChk(self, event):
  779. if self.writeSubsChk.GetValue():
  780. self.writeAllSubsChk.Disable()
  781. self.writeAutoSubsChk.Disable()
  782. self.embedSubsChk.Enable()
  783. else:
  784. self.writeAllSubsChk.Enable()
  785. self.writeAutoSubsChk.Enable()
  786. self.embedSubsChk.Disable()
  787. self.embedSubsChk.SetValue(False)
  788. def OnWriteAllSubsChk(self, event):
  789. if self.writeAllSubsChk.GetValue():
  790. self.writeSubsChk.Disable()
  791. self.subsLangCombo.Disable()
  792. self.writeAutoSubsChk.Disable()
  793. else:
  794. self.writeSubsChk.Enable()
  795. self.subsLangCombo.Enable()
  796. self.writeAutoSubsChk.Enable()
  797. def load_options(self):
  798. self.writeSubsChk.Enable()
  799. self.subsLangCombo.Enable()
  800. self.writeAllSubsChk.Enable()
  801. self.writeAutoSubsChk.Enable()
  802. self.writeSubsChk.SetValue(self.optList.writeSubs)
  803. self.writeAllSubsChk.SetValue(self.optList.writeAllSubs)
  804. self.subsLangCombo.SetValue(self.optList.subsLang)
  805. self.writeAutoSubsChk.SetValue(self.optList.writeAutoSubs)
  806. self.embedSubsChk.SetValue(self.optList.embedSubs)
  807. if self.optList.writeSubs:
  808. self.writeAllSubsChk.Disable()
  809. self.writeAutoSubsChk.Disable()
  810. self.embedSubsChk.Enable()
  811. if self.optList.writeAllSubs:
  812. self.writeSubsChk.Disable()
  813. self.subsLangCombo.Disable()
  814. self.writeAutoSubsChk.Disable()
  815. if self.optList.writeAutoSubs:
  816. self.writeAllSubsChk.Disable()
  817. self.writeSubsChk.Disable()
  818. self.subsLangCombo.Disable()
  819. self.embedSubsChk.Enable()
  820. if not self.subs_are_on():
  821. self.embedSubsChk.Disable()
  822. def save_options(self):
  823. self.optList.writeSubs = self.writeSubsChk.GetValue()
  824. self.optList.writeAllSubs = self.writeAllSubsChk.GetValue()
  825. self.optList.subsLang = self.subsLangCombo.GetValue()
  826. self.optList.writeAutoSubs = self.writeAutoSubsChk.GetValue()
  827. self.optList.embedSubs = self.embedSubsChk.GetValue()
  828. class GeneralPanel(wx.Panel):
  829. def __init__(self, parent, optList, resetHandler):
  830. wx.Panel.__init__(self, parent)
  831. self.optList = optList
  832. self.resetHandler = resetHandler
  833. mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
  834. svTextBox = wx.BoxSizer(wx.HORIZONTAL)
  835. svTextBox.Add(wx.StaticText(self, label='Save Path'))
  836. mainBoxSizer.Add(svTextBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=20)
  837. svPathBox = wx.BoxSizer(wx.HORIZONTAL)
  838. self.savePathBox = wx.TextCtrl(self)
  839. svPathBox.Add(self.savePathBox, 1, flag = wx.TOP, border=10)
  840. mainBoxSizer.Add(svPathBox, flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border=40)
  841. buttonsBox = wx.BoxSizer(wx.HORIZONTAL)
  842. self.aboutButton = wx.Button(self, label='About', size=(110, 40))
  843. buttonsBox.Add(self.aboutButton)
  844. self.openButton = wx.Button(self, label='Open', size=(110, 40))
  845. buttonsBox.Add(self.openButton, flag = wx.LEFT | wx.RIGHT, border=50)
  846. self.resetButton = wx.Button(self, label='Reset Options', size=(110, 40))
  847. buttonsBox.Add(self.resetButton)
  848. mainBoxSizer.Add(buttonsBox, flag = wx.ALIGN_CENTER_HORIZONTAL | wx.TOP, border=20)
  849. setngsBox = wx.BoxSizer(wx.HORIZONTAL)
  850. text = 'Settings: ' + self.optList.settings_abs_path
  851. setngsBox.Add(wx.StaticText(self, label=text), flag = wx.TOP, border=30)
  852. mainBoxSizer.Add(setngsBox, flag = wx.ALIGN_CENTER_HORIZONTAL)
  853. self.SetSizer(mainBoxSizer)
  854. self.Bind(wx.EVT_BUTTON, self.OnAbout, self.aboutButton)
  855. self.Bind(wx.EVT_BUTTON, self.OnOpen, self.openButton)
  856. self.Bind(wx.EVT_BUTTON, self.OnReset, self.resetButton)
  857. def OnReset(self, event):
  858. self.resetHandler()
  859. def OnOpen(self, event):
  860. dlg = wx.DirDialog(None, "Choose directory")
  861. if dlg.ShowModal() == wx.ID_OK:
  862. self.savePathBox.SetValue(dlg.GetPath())
  863. dlg.Destroy()
  864. def OnAbout(self, event):
  865. info = wx.AboutDialogInfo()
  866. info.SetIcon(wx.Icon(ICON, wx.BITMAP_TYPE_ICO))
  867. info.SetName(__appname__)
  868. info.SetVersion(__version__)
  869. info.SetDescription(__descriptionfull__)
  870. info.SetWebSite(__projecturl__)
  871. info.SetLicense(__licensefull__)
  872. info.AddDeveloper(__author__)
  873. wx.AboutBox(info)
  874. def load_options(self):
  875. self.savePathBox.SetValue(self.optList.savePath)
  876. def save_options(self):
  877. self.optList.savePath = fix_path(self.savePathBox.GetValue())
  878. class OtherPanel(wx.Panel):
  879. def __init__(self, parent, optList):
  880. wx.Panel.__init__(self, parent)
  881. self.optList = optList
  882. mainBoxSizer = wx.BoxSizer(wx.VERTICAL)
  883. textBox = wx.BoxSizer(wx.HORIZONTAL)
  884. textBox.Add(wx.StaticText(self, label='Command line arguments (e.g. --help)'), flag = wx.TOP, border=30)
  885. mainBoxSizer.Add(textBox, flag = wx.LEFT, border=50)
  886. inputBox = wx.BoxSizer(wx.HORIZONTAL)
  887. self.cmdArgsBox = wx.TextCtrl(self)
  888. inputBox.Add(self.cmdArgsBox, 1, flag = wx.TOP, border=10)
  889. mainBoxSizer.Add(inputBox, flag = wx.EXPAND | wx.LEFT | wx.RIGHT, border=50)
  890. self.SetSizer(mainBoxSizer)
  891. def load_options(self):
  892. self.cmdArgsBox.SetValue(self.optList.cmdArgs)
  893. def save_options(self):
  894. self.optList.cmdArgs = self.cmdArgsBox.GetValue()
  895. class OptionsFrame(wx.Frame):
  896. def __init__(self, optionsList, parent=None, id=-1, logger=None):
  897. wx.Frame.__init__(self, parent, id, "Options", size=self.SetFrameSizer())
  898. self.optionsList = optionsList
  899. panel = wx.Panel(self)
  900. notebook = wx.Notebook(panel)
  901. self.generalTab = GeneralPanel(notebook, self.optionsList, self.reset)
  902. self.audioTab = AudioPanel(notebook, self.optionsList)
  903. self.connectionTab = ConnectionPanel(notebook, self.optionsList)
  904. self.videoTab = VideoPanel(notebook, self.optionsList)
  905. self.filesysTab = FilesystemPanel(notebook, self.optionsList)
  906. self.subtitlesTab = SubtitlesPanel(notebook, self.optionsList)
  907. self.otherTab = OtherPanel(notebook, self.optionsList)
  908. self.authTab = AuthenticationPanel(notebook, self.optionsList)
  909. self.videoselTab = PlaylistPanel(notebook, self.optionsList)
  910. self.logTab = LogPanel(notebook, self.optionsList, logger)
  911. self.outputTab = OutputPanel(notebook, self.optionsList)
  912. notebook.AddPage(self.generalTab, "General")
  913. notebook.AddPage(self.videoTab, "Video")
  914. notebook.AddPage(self.audioTab, "Audio")
  915. notebook.AddPage(self.outputTab, "Output")
  916. notebook.AddPage(self.videoselTab, "Playlist")
  917. notebook.AddPage(self.subtitlesTab, "Subtitles")
  918. notebook.AddPage(self.filesysTab, "Filesystem")
  919. notebook.AddPage(self.connectionTab, "Connection")
  920. notebook.AddPage(self.authTab, "Authentication")
  921. notebook.AddPage(self.logTab, "Log")
  922. notebook.AddPage(self.otherTab, "Commands")
  923. sizer = wx.BoxSizer()
  924. sizer.Add(notebook, 1, wx.EXPAND)
  925. panel.SetSizer(sizer)
  926. self.Bind(wx.EVT_CLOSE, self.OnClose)
  927. self.load_all_options()
  928. def SetFrameSizer(self):
  929. if get_os_type() == 'nt':
  930. return (580, 270)
  931. else:
  932. return (580, 250)
  933. def OnClose(self, event):
  934. self.save_all_options()
  935. self.Destroy()
  936. def reset(self):
  937. self.optionsList.load_default()
  938. self.load_all_options()
  939. def load_all_options(self):
  940. self.generalTab.load_options()
  941. self.audioTab.load_options()
  942. self.connectionTab.load_options()
  943. self.videoTab.load_options()
  944. self.filesysTab.load_options()
  945. self.subtitlesTab.load_options()
  946. self.otherTab.load_options()
  947. self.authTab.load_options()
  948. self.videoselTab.load_options()
  949. self.logTab.load_options()
  950. self.outputTab.load_options()
  951. def save_all_options(self):
  952. self.generalTab.save_options()
  953. self.audioTab.save_options()
  954. self.connectionTab.save_options()
  955. self.videoTab.save_options()
  956. self.filesysTab.save_options()
  957. self.subtitlesTab.save_options()
  958. self.otherTab.save_options()
  959. self.authTab.save_options()
  960. self.videoselTab.save_options()
  961. self.logTab.save_options()
  962. self.outputTab.save_options()