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.

634 lines
23 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. #! /usr/bin/env python
  2. '''
  3. This file contains all gui classes
  4. MainFrame
  5. Custom wx.ListCtrl class
  6. OptionsFrame
  7. ConnectionPanel
  8. AudioPanel
  9. videoPanel
  10. DownloadPanel
  11. SubtitlesPanel
  12. GeneralPanel
  13. OtherPanel
  14. '''
  15. import os
  16. import wx
  17. from wx.lib.pubsub import setuparg1
  18. from wx.lib.pubsub import pub as Publisher
  19. from .version import __version__
  20. from .UpdateThread import UpdateThread
  21. from .DownloadThread import DownloadManager
  22. from .OptionsHandler import OptionsHandler
  23. from .YoutubeDLInterpreter import YoutubeDLInterpreter
  24. from .SignalHandler import DownloadHandler
  25. if os.name == 'nt':
  26. YOUTUBE_DL_FILENAME = 'youtube-dl.exe'
  27. else:
  28. YOUTUBE_DL_FILENAME = 'youtube-dl'
  29. TITLE = 'Youtube-dlG'
  30. AUDIOFORMATS = ["mp3", "wav", "aac", "m4a"]
  31. VIDEOFORMATS = ["highest available",
  32. "mp4 [1280x720]",
  33. "mp4 [640x360]",
  34. "webm [640x360]",
  35. "flv [400x240]",
  36. "3gp [320x240]",
  37. "mp4 1080p(DASH)",
  38. "mp4 720p(DASH)",
  39. "mp4 480p(DASH)",
  40. "mp4 360p(DASH)"]
  41. LANGUAGES = ["English",
  42. "Greek",
  43. "Portuguese",
  44. "French",
  45. "Italian",
  46. "Russian",
  47. "Spanish",
  48. "German"]
  49. class MainFrame(wx.Frame):
  50. def __init__(self, parent=None, id=-1):
  51. wx.Frame.__init__(self, parent, id, TITLE+' '+__version__, size=(600, 410), style = wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER)
  52. # set sizers for status box (Windows & Linux)
  53. if os.name == 'nt':
  54. statusListSizer = (580, 165)
  55. statusBarSizer = (15, 365)
  56. else:
  57. statusListSizer = (580, 195)
  58. statusBarSizer = (15, 390)
  59. # create panel, trackList, statusBox using global statusBoxSizer
  60. self.panel = wx.Panel(self)
  61. wx.StaticText(self.panel, -1, "URLs", (15, 10))
  62. self.trackList = wx.TextCtrl(self.panel, -1, pos=(10, 25), size=(580, 110), style = wx.TE_MULTILINE | wx.TE_DONTWRAP)
  63. self.statusList = ListCtrl(self.panel, -1, pos=(10, 190), size=statusListSizer, style = wx.LC_REPORT | wx.LC_HRULES | wx.LC_VRULES)
  64. self.statusBar = wx.StaticText(self.panel, -1, 'Author: Sotiris Papadopoulos', pos=statusBarSizer)
  65. # create buttons
  66. self.downloadButton = wx.Button(self.panel, label="Download", pos=(100, 145), size=(-1, 30))
  67. self.updateButton = wx.Button(self.panel, label="Update", pos=(250, 145), size=(-1, 30))
  68. self.optionsButton = wx.Button(self.panel, label="Options", pos=(390, 145), size=(-1, 30))
  69. # bind events
  70. self.Bind(wx.EVT_BUTTON, self.OnDownload, self.downloadButton)
  71. self.Bind(wx.EVT_BUTTON, self.OnUpdate, self.updateButton)
  72. self.Bind(wx.EVT_BUTTON, self.OnOptions, self.optionsButton)
  73. self.Bind(wx.EVT_TEXT, self.OnTrackListChange, self.trackList)
  74. self.Bind(wx.EVT_CLOSE, self.OnClose)
  75. # set app icon
  76. icon = wx.Icon('../icons/ytube.png', wx.BITMAP_TYPE_ICO)
  77. self.SetIcon(icon)
  78. # set publisher for update thread
  79. Publisher.subscribe(self.update_handler, "update")
  80. # set publisher for download thread
  81. Publisher.subscribe(self.download_handler, "download")
  82. # init Options and DownloadHandler objects
  83. self.optionsList = OptionsHandler()
  84. self.downloadHandler = None
  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. # check & update libraries (youtube-dl)
  91. self.check_if_youtube_dl_exist()
  92. if (self.optionsList.autoUpdate):
  93. self.status_bar_write("Auto update enable")
  94. self.update_youtube_dl()
  95. def check_if_youtube_dl_exist(self):
  96. if not os.path.exists(YOUTUBE_DL_FILENAME):
  97. self.status_bar_write("Youtube-dl is missing, trying to download it...")
  98. self.update_youtube_dl()
  99. def update_youtube_dl(self):
  100. self.downloadButton.Disable()
  101. self.updateThread = UpdateThread(YOUTUBE_DL_FILENAME)
  102. def status_bar_write(self, msg):
  103. self.statusBar.SetLabel(msg)
  104. def download_handler(self, msg):
  105. self.downloadHandler.handle(msg)
  106. if self.downloadHandler._has_closed():
  107. self.status_bar_write('Stoping downloads')
  108. if self.downloadHandler._has_finished():
  109. self.finished_popup()
  110. self.status_bar_write('Done')
  111. self.downloadButton.SetLabel('Download')
  112. self.updateButton.Enable()
  113. self.downloadThread = None
  114. self.urlList = []
  115. self.downloadHandler = None
  116. def update_handler(self, msg):
  117. if msg.data == 'finish':
  118. self.downloadButton.Enable()
  119. self.updateThread = None
  120. else:
  121. self.status_bar_write(msg.data)
  122. def stop_download(self):
  123. self.downloadThread.close()
  124. self.downloadThread.join()
  125. self.downloadThread = None
  126. self.urlList = []
  127. def start_download(self, trackList):
  128. self.statusList._clear_list()
  129. for url in trackList:
  130. if url != '':
  131. self.urlList.append(url)
  132. self.statusList._add_item(url)
  133. if not self.statusList._is_empty():
  134. options = YoutubeDLInterpreter(self.optionsList, YOUTUBE_DL_FILENAME).get_options()
  135. self.status_bar_write('Download started')
  136. self.downloadThread = DownloadManager(options, self.statusList._get_items())
  137. self.downloadHandler = DownloadHandler(self.statusList)
  138. self.downloadButton.SetLabel('Stop')
  139. self.updateButton.Disable()
  140. else:
  141. self.no_url_popup()
  142. def save_options(self):
  143. self.optionsList.save_to_file()
  144. def finished_popup(self):
  145. wx.MessageBox('Downloads completed.', 'Info', wx.OK | wx.ICON_INFORMATION)
  146. def no_url_popup(self):
  147. wx.MessageBox('You need to provide at least one url.', 'Error', wx.OK | wx.ICON_EXCLAMATION)
  148. def OnTrackListChange(self, event):
  149. if self.downloadThread != None:
  150. ''' Get current url list from trackList textCtrl '''
  151. curList = self.trackList.GetValue().split('\n')
  152. ''' For each url in current url list '''
  153. for url in curList:
  154. ''' If url is not in self.urlList (original downloads list) and url is not empty '''
  155. if url not in self.urlList and url != '':
  156. ''' Add url into original download list '''
  157. self.urlList.append(url)
  158. ''' Add url into statusList '''
  159. index = self.statusList._add_item(url)
  160. ''' Retrieve last item as {url:url, index:indexNo} '''
  161. item = self.statusList._get_last_item()
  162. ''' Pass that item into downloadThread '''
  163. self.downloadThread.add_download_item(item)
  164. def OnDownload(self, event):
  165. if self.downloadThread != None:
  166. self.stop_download()
  167. else:
  168. self.start_download(self.trackList.GetValue().split('\n'))
  169. def OnUpdate(self, event):
  170. if (self.downloadThread == None and self.updateThread == None):
  171. self.status_bar_write("Updating youtube-dl...")
  172. self.update_youtube_dl()
  173. def OnOptions(self, event):
  174. optionsFrame = OptionsFrame(self.optionsList, self)
  175. optionsFrame.Show()
  176. def OnClose(self, event):
  177. self.save_options()
  178. self.Destroy()
  179. class ListCtrl(wx.ListCtrl):
  180. ''' Custom ListCtrl class '''
  181. def __init__(self, parent, id, pos, size, style):
  182. wx.ListCtrl.__init__(self, parent, id, pos, size, style)
  183. self.InsertColumn(0, 'URL', width=150)
  184. self.InsertColumn(1, 'Size', width=90)
  185. self.InsertColumn(2, 'Percent', width=80)
  186. self.InsertColumn(3, 'ETA', width=50)
  187. self.InsertColumn(4, 'Speed', width=90)
  188. self.InsertColumn(5, 'Status', width=150)
  189. self.ListIndex = 0
  190. ''' Add single item on list '''
  191. def _add_item(self, item):
  192. self.InsertStringItem(self.ListIndex, item)
  193. self.ListIndex += 1
  194. return self.ListIndex
  195. ''' Write data on index, column '''
  196. def _write_data(self, index, column, data):
  197. self.SetStringItem(index, column, data)
  198. ''' Clear list and set index to 0'''
  199. def _clear_list(self):
  200. self.DeleteAllItems()
  201. self.ListIndex = 0
  202. ''' Return True if list is empty '''
  203. def _is_empty(self):
  204. if self.ListIndex == 0:
  205. return True
  206. else:
  207. return False
  208. ''' Get last item inserted, Returns dictionary '''
  209. def _get_last_item(self):
  210. data = {}
  211. last_item = self.GetItem(itemId=self.ListIndex-1, col=0)
  212. data['url'] = last_item.GetText()
  213. data['index'] = self.ListIndex-1
  214. return data
  215. ''' Retrieve all items [start, self.ListIndex), Returns list '''
  216. def _get_items(self, start=0):
  217. items = []
  218. for row in range(start, self.ListIndex):
  219. item = self.GetItem(itemId=row, col=0)
  220. data = {}
  221. data['url'] = item.GetText()
  222. data['index'] = row
  223. items.append(data)
  224. return items
  225. class ConnectionPanel(wx.Panel):
  226. def __init__(self, parent, optList):
  227. self.optList = optList
  228. wx.Panel.__init__(self, parent)
  229. wx.StaticText(self, -1, 'User Agent', (15, 10))
  230. self.userAgentBox = wx.TextCtrl(self, -1, pos=(10, 30), size=(230, -1))
  231. wx.StaticText(self, -1, 'Referer', (270, 10))
  232. self.refererBox = wx.TextCtrl(self, -1, pos=(265, 30), size=(230, -1))
  233. wx.StaticText(self, -1, 'Username', (15, 60))
  234. self.usernameBox = wx.TextCtrl(self, -1, pos=(10, 80), size=(230, -1))
  235. wx.StaticText(self, -1, 'Password', (270, 60))
  236. self.passwordBox = wx.TextCtrl(self, -1, pos=(265, 80), size=(230, -1), style = wx.TE_PASSWORD)
  237. wx.StaticText(self, -1, 'Proxy', (15, 110))
  238. self.proxyBox = wx.TextCtrl(self, -1, pos=(10, 130), size=(350, -1))
  239. def load_options(self):
  240. self.userAgentBox.SetValue(self.optList.userAgent)
  241. self.refererBox.SetValue(self.optList.referer)
  242. self.usernameBox.SetValue(self.optList.username)
  243. self.proxyBox.SetValue(self.optList.proxy)
  244. def save_options(self):
  245. self.optList.userAgent = self.userAgentBox.GetValue()
  246. self.optList.referer = self.refererBox.GetValue()
  247. self.optList.username = self.usernameBox.GetValue()
  248. self.optList.proxy = self.proxyBox.GetValue()
  249. class AudioPanel(wx.Panel):
  250. def __init__(self, parent, optList):
  251. self.optList = optList
  252. wx.Panel.__init__(self, parent)
  253. self.toAudioChk = wx.CheckBox(self, -1, 'Convert to Audio', (10, 10))
  254. self.keepVideoChk = wx.CheckBox(self, -1, 'Keep Video', (30, 40))
  255. wx.StaticText(self, -1, 'Audio Format', (35, 80))
  256. self.audioFormatCombo = wx.ComboBox(self, choices=AUDIOFORMATS, pos=(30, 100), size=(95, -1))
  257. wx.StaticText(self, -1, "Audio Quality 0 (best) 9 (worst)", (35, 130))
  258. self.audioQualitySpnr = wx.SpinCtrl(self, -1, "", (30, 150))
  259. self.audioQualitySpnr.SetRange(0, 9)
  260. self.Bind(wx.EVT_CHECKBOX, self.OnAudioCheck, self.toAudioChk)
  261. def OnAudioCheck(self, event):
  262. if (self.toAudioChk.GetValue()):
  263. self.keepVideoChk.Enable()
  264. self.audioFormatCombo.Enable()
  265. self.audioQualitySpnr.Enable()
  266. else:
  267. self.keepVideoChk.Disable()
  268. self.audioFormatCombo.Disable()
  269. self.audioQualitySpnr.Disable()
  270. def load_options(self):
  271. self.toAudioChk.SetValue(self.optList.toAudio)
  272. self.keepVideoChk.SetValue(self.optList.keepVideo)
  273. self.audioFormatCombo.SetValue(self.optList.audioFormat)
  274. self.audioQualitySpnr.SetValue(self.optList.audioQuality)
  275. if (self.optList.toAudio == False):
  276. self.keepVideoChk.Disable()
  277. self.audioFormatCombo.Disable()
  278. self.audioQualitySpnr.Disable()
  279. def save_options(self):
  280. self.optList.toAudio = self.toAudioChk.GetValue()
  281. self.optList.keepVideo = self.keepVideoChk.GetValue()
  282. self.optList.audioFormat = self.audioFormatCombo.GetValue()
  283. self.optList.audioQuality = self.audioQualitySpnr.GetValue()
  284. class VideoPanel(wx.Panel):
  285. def __init__(self, parent, optList):
  286. self.optList = optList
  287. wx.Panel.__init__(self, parent)
  288. wx.StaticText(self, -1, 'Video Format', (15, 10))
  289. self.videoFormatCombo = wx.ComboBox(self, choices=VIDEOFORMATS, pos=(10, 30), size=(160, 30))
  290. wx.StaticText(self, -1, 'Playlist Options', (300, 30))
  291. wx.StaticText(self, -1, 'Start', (250, 60))
  292. self.startBox = wx.TextCtrl(self, -1, pos=(320, 55), size=(50, -1))
  293. wx.StaticText(self, -1, 'Stop', (250, 100))
  294. self.stopBox = wx.TextCtrl(self, -1, pos=(320, 95), size=(50, -1))
  295. wx.StaticText(self, -1, 'Max DLs', (250, 140))
  296. self.maxBox = wx.TextCtrl(self, -1, pos=(320, 135), size=(50, -1))
  297. def load_options(self):
  298. self.videoFormatCombo.SetValue(self.optList.videoFormat)
  299. self.startBox.SetValue(self.optList.startTrack)
  300. self.stopBox.SetValue(self.optList.endTrack)
  301. self.maxBox.SetValue(self.optList.maxDownloads)
  302. def save_options(self):
  303. self.optList.videoFormat = self.videoFormatCombo.GetValue()
  304. self.optList.startTrack = self.startBox.GetValue()
  305. self.optList.endTrack = self.stopBox.GetValue()
  306. self.optList.maxDownloads = self.maxBox.GetValue()
  307. class DownloadPanel(wx.Panel):
  308. def __init__(self, parent, optList):
  309. self.optList = optList
  310. wx.Panel.__init__(self, parent)
  311. wx.StaticText(self, -1, 'Rate Limit (e.g. 50k or 44.6m)', (250, 15))
  312. self.limitBox = wx.TextCtrl(self, -1, pos=(245, 35), size=(80, -1))
  313. wx.StaticText(self, -1, 'Retries', (15, 15))
  314. self.retriesBox = wx.TextCtrl(self, -1, pos=(10, 35), size=(50, -1))
  315. self.writeDescriptionChk = wx.CheckBox(self, -1, 'Write description to file', (10, 60))
  316. self.writeInfoChk = wx.CheckBox(self, -1, 'Write info to (.json) file', (10, 85))
  317. self.writeThumbnailChk = wx.CheckBox(self, -1, 'Write thumbnail to disk', (10, 110))
  318. self.ignoreErrorsChk = wx.CheckBox(self, -1, 'Ignore Errors', (10, 135))
  319. wx.StaticText(self, -1, 'Min Filesize (e.g. 50k or 44.6m)', (250, 65))
  320. self.minFilesizeBox = wx.TextCtrl(self, -1, pos=(245, 85), size=(80, -1))
  321. wx.StaticText(self, -1, 'Max Filesize (e.g. 50k or 44.6m)', (250, 115))
  322. self.maxFilesizeBox = wx.TextCtrl(self, -1, pos=(245, 135), size=(80, -1))
  323. def load_options(self):
  324. self.limitBox.SetValue(self.optList.rateLimit)
  325. self.retriesBox.SetValue(self.optList.retries)
  326. self.writeDescriptionChk.SetValue(self.optList.writeDescription)
  327. self.writeInfoChk.SetValue(self.optList.writeInfo)
  328. self.writeThumbnailChk.SetValue(self.optList.writeThumbnail)
  329. self.ignoreErrorsChk.SetValue(self.optList.ignoreErrors)
  330. self.minFilesizeBox.SetValue(self.optList.minFileSize)
  331. self.maxFilesizeBox.SetValue(self.optList.maxFileSize)
  332. def save_options(self):
  333. self.optList.rateLimit = self.limitBox.GetValue()
  334. self.optList.retries = self.retriesBox.GetValue()
  335. self.optList.writeDescription = self.writeDescriptionChk.GetValue()
  336. self.optList.writeInfo = self.writeInfoChk.GetValue()
  337. self.optList.writeThumbnail = self.writeThumbnailChk.GetValue()
  338. self.optList.ignoreErrors = self.ignoreErrorsChk.GetValue()
  339. self.optList.minFileSize = self.minFilesizeBox.GetValue()
  340. self.optList.maxFileSize = self.maxFilesizeBox.GetValue()
  341. class SubtitlesPanel(wx.Panel):
  342. def __init__(self, parent, optList):
  343. self.optList = optList
  344. wx.Panel.__init__(self, parent)
  345. self.writeSubsChk = wx.CheckBox(self, -1, 'Write subtitle file', (10, 10))
  346. self.writeAllSubsChk = wx.CheckBox(self, -1, 'Download all available subtitles', (10, 40))
  347. self.writeAutoSubsChk = wx.CheckBox(self, -1, 'Write automatic subtitle file (YOUTUBE ONLY)', (10, 70))
  348. wx.StaticText(self, -1, 'Subtitles Language', (15, 105))
  349. self.subsLangCombo = wx.ComboBox(self, choices=LANGUAGES, pos=(10, 125), size=(140, 30))
  350. self.Bind(wx.EVT_CHECKBOX, self.OnWriteSubsChk, self.writeSubsChk)
  351. self.Bind(wx.EVT_CHECKBOX, self.OnWriteAllSubsChk, self.writeAllSubsChk)
  352. self.Bind(wx.EVT_CHECKBOX, self.OnWriteAutoSubsChk, self.writeAutoSubsChk)
  353. def OnWriteAutoSubsChk(self, event):
  354. if (self.writeAutoSubsChk.GetValue()):
  355. self.writeAllSubsChk.Disable()
  356. self.writeSubsChk.Disable()
  357. self.subsLangCombo.Disable()
  358. else:
  359. self.writeAllSubsChk.Enable()
  360. self.writeSubsChk.Enable()
  361. self.subsLangCombo.Enable()
  362. def OnWriteSubsChk(self, event):
  363. if (self.writeSubsChk.GetValue()):
  364. self.writeAllSubsChk.Disable()
  365. self.writeAutoSubsChk.Disable()
  366. else:
  367. self.writeAllSubsChk.Enable()
  368. self.writeAutoSubsChk.Enable()
  369. def OnWriteAllSubsChk(self, event):
  370. if (self.writeAllSubsChk.GetValue()):
  371. self.writeSubsChk.Disable()
  372. self.subsLangCombo.Disable()
  373. self.writeAutoSubsChk.Disable()
  374. else:
  375. self.writeSubsChk.Enable()
  376. self.subsLangCombo.Enable()
  377. self.writeAutoSubsChk.Enable()
  378. def load_options(self):
  379. self.writeSubsChk.Enable()
  380. self.subsLangCombo.Enable()
  381. self.writeAllSubsChk.Enable()
  382. self.writeAutoSubsChk.Enable()
  383. self.writeSubsChk.SetValue(self.optList.writeSubs)
  384. self.writeAllSubsChk.SetValue(self.optList.writeAllSubs)
  385. self.subsLangCombo.SetValue(self.optList.subsLang)
  386. self.writeAutoSubsChk.SetValue(self.optList.writeAutoSubs)
  387. if (self.writeSubsChk.GetValue()):
  388. self.writeAllSubsChk.Disable()
  389. self.writeAllSubsChk.SetValue(False)
  390. self.writeAutoSubsChk.Disable()
  391. self.writeAutoSubsChk.SetValue(False)
  392. if (self.writeAllSubsChk.GetValue()):
  393. self.writeSubsChk.Disable()
  394. self.writeSubsChk.SetValue(False)
  395. self.subsLangCombo.Disable()
  396. self.writeAutoSubsChk.Disable()
  397. self.writeAutoSubsChk.SetValue(False)
  398. if (self.writeAutoSubsChk.GetValue()):
  399. self.writeAllSubsChk.Disable()
  400. self.writeAllSubsChk.SetValue(False)
  401. self.writeSubsChk.Disable()
  402. self.writeSubsChk.SetValue(False)
  403. self.subsLangCombo.Disable()
  404. def save_options(self):
  405. self.optList.writeSubs = self.writeSubsChk.GetValue()
  406. self.optList.writeAllSubs = self.writeAllSubsChk.GetValue()
  407. self.optList.subsLang = self.subsLangCombo.GetValue()
  408. self.optList.writeAutoSubs = self.writeAutoSubsChk.GetValue()
  409. class GeneralPanel(wx.Panel):
  410. def __init__(self, parent, optList, controlParent):
  411. self.optList = optList
  412. self.parent = controlParent
  413. wx.Panel.__init__(self, parent)
  414. wx.StaticText(self, -1, "Save Path", (15, 10))
  415. self.savePathBox = wx.TextCtrl(self, -1, pos=(10, 30), size=(350, -1))
  416. self.idAsNameChk = wx.CheckBox(self, -1, 'ID as Name', (10, 70))
  417. self.autoUpdateChk = wx.CheckBox(self, -1, 'Auto Update', (160, 70))
  418. self.aboutButton = wx.Button(self, label="About", pos=(380, 80), size=(100, 40))
  419. self.openButton = wx.Button(self, label="Open", pos=(380, 20), size=(100, 40))
  420. self.resetButton = wx.Button(self, label="Reset", pos=(380, 140), size=(100, 40))
  421. wx.StaticText(self, -1, "Settings: " + self.optList.settings_abs_path, (20, 155))
  422. self.Bind(wx.EVT_BUTTON, self.OnAbout, self.aboutButton)
  423. self.Bind(wx.EVT_BUTTON, self.OnOpen, self.openButton)
  424. self.Bind(wx.EVT_BUTTON, self.OnReset, self.resetButton)
  425. def OnReset(self, event):
  426. self.parent.reset()
  427. def OnOpen(self, event):
  428. dlg = wx.DirDialog(None, "Choose directory")
  429. if dlg.ShowModal() == wx.ID_OK:
  430. self.savePathBox.SetValue(dlg.GetPath())
  431. dlg.Destroy()
  432. def OnAbout(self, event):
  433. description = '''A cross platform front-end GUI of
  434. the popular youtube-dl written in Python.'''
  435. license = '''This is free and unencumbered software released into the public domain.
  436. Anyone is free to copy, modify, publish, use, compile, sell, or
  437. distribute this software, either in source code form or as a compiled
  438. binary, for any purpose, commercial or non-commercial, and by any
  439. means.
  440. In jurisdictions that recognize copyright laws, the author or authors
  441. of this software dedicate any and all copyright interest in the
  442. software to the public domain. We make this dedication for the benefit
  443. of the public at large and to the detriment of our heirs and
  444. successors. We intend this dedication to be an overt act of
  445. relinquishment in perpetuity of all present and future rights to this
  446. software under copyright law.
  447. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  448. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  449. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  450. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  451. OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  452. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  453. OTHER DEALINGS IN THE SOFTWARE.
  454. For more information, please refer to <http://unlicense.org/>'''
  455. info = wx.AboutDialogInfo()
  456. info.SetIcon(wx.Icon('../icons/ytube.png', wx.BITMAP_TYPE_ICO))
  457. info.SetName(TITLE)
  458. info.SetVersion(__version__)
  459. info.SetDescription(description)
  460. info.SetWebSite('https://github.com/MrS0m30n3/youtube-dl-gui')
  461. info.SetLicense(license)
  462. info.AddDeveloper('Sotiris Papadopoulos')
  463. wx.AboutBox(info)
  464. def load_options(self):
  465. self.savePathBox.SetValue(self.optList.savePath)
  466. self.idAsNameChk.SetValue(self.optList.idAsName)
  467. self.autoUpdateChk.SetValue(self.optList.autoUpdate)
  468. def save_options(self):
  469. self.optList.savePath = self.savePathBox.GetValue()
  470. self.optList.idAsName = self.idAsNameChk.GetValue()
  471. self.optList.autoUpdate = self.autoUpdateChk.GetValue()
  472. class OtherPanel(wx.Panel):
  473. def __init__(self, parent, optList):
  474. self.optList = optList
  475. wx.Panel.__init__(self, parent)
  476. wx.StaticText(self, -1, 'Command line arguments (e.g. --help)', (25, 20))
  477. self.cmdArgsBox = wx.TextCtrl(self, -1, pos=(20, 40), size=(450, -1))
  478. def load_options(self):
  479. self.cmdArgsBox.SetValue(self.optList.cmdArgs)
  480. def save_options(self):
  481. self.optList.cmdArgs = self.cmdArgsBox.GetValue()
  482. class OptionsFrame(wx.Frame):
  483. def __init__(self, optionsList, parent=None, id=-1):
  484. wx.Frame.__init__(self, parent, id, "Options", size=(540, 250))
  485. self.optionsList = optionsList
  486. panel = wx.Panel(self)
  487. notebook = wx.Notebook(panel)
  488. self.generalTab = GeneralPanel(notebook, self.optionsList, self)
  489. self.audioTab = AudioPanel(notebook, self.optionsList)
  490. self.connectionTab = ConnectionPanel(notebook, self.optionsList)
  491. self.videoTab = VideoPanel(notebook, self.optionsList)
  492. self.downloadTab = DownloadPanel(notebook, self.optionsList)
  493. self.subtitlesTab = SubtitlesPanel(notebook, self.optionsList)
  494. self.otherTab = OtherPanel(notebook, self.optionsList)
  495. notebook.AddPage(self.generalTab, "General")
  496. notebook.AddPage(self.audioTab, "Audio")
  497. notebook.AddPage(self.videoTab, "Video")
  498. notebook.AddPage(self.subtitlesTab, "Subtitles")
  499. notebook.AddPage(self.downloadTab, "Download")
  500. notebook.AddPage(self.connectionTab, "Connection")
  501. notebook.AddPage(self.otherTab, "Commands")
  502. sizer = wx.BoxSizer()
  503. sizer.Add(notebook, 1, wx.EXPAND)
  504. panel.SetSizer(sizer)
  505. self.Bind(wx.EVT_CLOSE, self.OnClose)
  506. self.load_all_options()
  507. def OnClose(self, event):
  508. self.save_all_options()
  509. self.Destroy()
  510. def reset(self):
  511. self.optionsList.load_default()
  512. self.load_all_options()
  513. def load_all_options(self):
  514. self.generalTab.load_options()
  515. self.audioTab.load_options()
  516. self.connectionTab.load_options()
  517. self.videoTab.load_options()
  518. self.downloadTab.load_options()
  519. self.subtitlesTab.load_options()
  520. self.otherTab.load_options()
  521. def save_all_options(self):
  522. self.generalTab.save_options()
  523. self.audioTab.save_options()
  524. self.connectionTab.save_options()
  525. self.videoTab.save_options()
  526. self.downloadTab.save_options()
  527. self.subtitlesTab.save_options()
  528. self.otherTab.save_options()