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.

1051 lines
38 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. #!/usr/bin/env python2
  2. ''' Contains code for youtube-dlG options frame. '''
  3. from os import name
  4. import wx
  5. from .LogManager import LogGUI
  6. from .version import __version__
  7. from .utils import (
  8. get_icon_path,
  9. fix_path,
  10. is_dash
  11. )
  12. from .data import (
  13. __descriptionfull__,
  14. __licensefull__,
  15. __projecturl__,
  16. __appname__,
  17. __author__
  18. )
  19. AUDIO_QUALITY = ['high', 'mid', 'low']
  20. AUDIO_FORMATS = [
  21. "mp3",
  22. "wav",
  23. "aac",
  24. "m4a",
  25. "vorbis"
  26. ]
  27. VIDEO_FORMATS = [
  28. "default",
  29. "3gp [176x144]",
  30. "3gp [320x240]",
  31. "flv [400x240]",
  32. "flv [640x360]",
  33. "flv [854x480]",
  34. "webm [640x360]",
  35. "webm [854x480]",
  36. "webm [1280x720]",
  37. "webm [1920x1080]",
  38. "mp4 [640x360]",
  39. "mp4 [1280x720]",
  40. "mp4 [1920x1080]",
  41. "mp4 [4096x3072]",
  42. "mp4 144p (DASH)",
  43. "mp4 240p (DASH)",
  44. "mp4 360p (DASH)",
  45. "mp4 480p (DASH)",
  46. "mp4 720p (DASH)",
  47. "mp4 1080p (DASH)",
  48. "mp4 1440p (DASH)",
  49. "mp4 2160p (DASH)",
  50. "webm 240p (DASH)",
  51. "webm 360p (DASH)",
  52. "webm 480p (DASH)",
  53. "webm 720p (DASH)",
  54. "webm 1080p (DASH)",
  55. "webm 1440p (DASH)",
  56. "webm 2160p (DASH)",
  57. "mp4 360p (3D)",
  58. "mp4 480p (3D)",
  59. "mp4 720p (3D)",
  60. "mp4 1080p (3D)",
  61. "webm 360p (3D)",
  62. "webm 480p (3D)",
  63. "webm 720p (3D)"
  64. ]
  65. DASH_AUDIO_FORMATS = [
  66. "none",
  67. "m4a 48k (DASH)",
  68. "m4a 128k (DASH)",
  69. "m4a 256k (DASH)",
  70. "webm 48k (DASH)",
  71. "webm 256k (DASH)"
  72. ]
  73. SUBS_LANG = [
  74. "English",
  75. "Greek",
  76. "Portuguese",
  77. "French",
  78. "Italian",
  79. "Russian",
  80. "Spanish",
  81. "German"
  82. ]
  83. # Set wx.CheckBox height for Windows & Linux
  84. # so it looks the same on both platforms
  85. WX_CHECKBOX_SIZE = (-1, -1)
  86. if name == 'nt':
  87. WX_CHECKBOX_SIZE = (-1, 25)
  88. class OptionsFrame(wx.Frame):
  89. '''
  90. Youtube-dlG options frame.
  91. Params
  92. opt_manager: OptionsManager.OptionsManager object.
  93. parent: Frame parent.
  94. logger: LogManager.LogManager object.
  95. Accessible Methods
  96. reset()
  97. Params: None
  98. Return: None
  99. load_all_options()
  100. Params: None
  101. Return: None
  102. save_all_options()
  103. Params: None
  104. Return: None
  105. '''
  106. def __init__(self, opt_manager, parent=None, logger=None):
  107. wx.Frame.__init__(self, parent, -1, "Options", size=(640, 270))
  108. self.opt_manager = opt_manager
  109. # Create GUI
  110. panel = wx.Panel(self)
  111. notebook = wx.Notebook(panel)
  112. # Create Tabs
  113. self.tabs = (
  114. (GeneralPanel(notebook, self.opt_manager, self.reset), "General"),
  115. (VideoPanel(notebook), "Video"),
  116. (AudioPanel(notebook), "Audio"),
  117. (PlaylistPanel(notebook), "Playlist"),
  118. (OutputPanel(notebook), "Output"),
  119. (SubtitlesPanel(notebook), "Subtitles"),
  120. (FilesystemPanel(notebook), "Filesystem"),
  121. (ShutdownPanel(notebook), "Shutdown"),
  122. (AuthenticationPanel(notebook), "Authentication"),
  123. (ConnectionPanel(notebook), "Connection"),
  124. (LogPanel(notebook, logger), "Log"),
  125. (OtherPanel(notebook), "Commands")
  126. )
  127. # Add tabs on notebook
  128. for tab, label in self.tabs:
  129. notebook.AddPage(tab, label)
  130. sizer = wx.BoxSizer()
  131. sizer.Add(notebook, 1, wx.EXPAND)
  132. panel.SetSizer(sizer)
  133. self.Bind(wx.EVT_CLOSE, self.OnClose)
  134. self.load_all_options()
  135. def OnClose(self, event):
  136. ''' Event handler for wx.EVT_CLOSE. '''
  137. self.save_all_options()
  138. self.Destroy()
  139. def reset(self):
  140. ''' Reset default options. '''
  141. self.opt_manager.load_default()
  142. self.load_all_options()
  143. def load_all_options(self):
  144. ''' Load tabs options. '''
  145. for tab, _ in self.tabs:
  146. tab.load_options(self.opt_manager)
  147. def save_all_options(self):
  148. ''' Save tabs options '''
  149. for tab, _ in self.tabs:
  150. tab.save_options(self.opt_manager)
  151. class LogPanel(wx.Panel):
  152. '''
  153. Options frame log tab panel.
  154. Params
  155. parent: wx.Panel parent.
  156. logger: LogManager.LogManager.object.
  157. '''
  158. def __init__(self, parent, logger):
  159. wx.Panel.__init__(self, parent)
  160. self.logger = logger
  161. # Create components
  162. self.enable_checkbox = wx.CheckBox(self, label='Enable Log', size=WX_CHECKBOX_SIZE)
  163. self.time_checkbox = wx.CheckBox(self, label='Write Time', size=WX_CHECKBOX_SIZE)
  164. self.clear_button = wx.Button(self, label='Clear Log')
  165. self.view_button = wx.Button(self, label='View Log')
  166. if self.logger is None:
  167. self.time_checkbox.Disable()
  168. self.clear_button.Disable()
  169. self.view_button.Disable()
  170. # Set BoxSizer
  171. main_sizer = wx.BoxSizer(wx.VERTICAL)
  172. main_sizer.AddSpacer(20)
  173. main_sizer.Add(self.enable_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  174. main_sizer.AddSpacer(5)
  175. main_sizer.Add(self.time_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  176. main_sizer.AddSpacer(15)
  177. main_sizer.Add(self._create_buttons_sizer(), flag=wx.ALIGN_CENTER_HORIZONTAL)
  178. # Create extra items
  179. if logger is not None:
  180. path_text = wx.StaticText(self, label="Path: " + self.logger.log_file)
  181. self.log_size = wx.StaticText(self, label="Log Size %s Bytes" % self.logger.size())
  182. main_sizer.AddSpacer(20)
  183. main_sizer.Add(path_text, flag=wx.ALIGN_CENTER_HORIZONTAL)
  184. main_sizer.AddSpacer(10)
  185. main_sizer.Add(self.log_size, flag=wx.ALIGN_CENTER_HORIZONTAL)
  186. self.SetSizer(main_sizer)
  187. # Set Events
  188. self.Bind(wx.EVT_CHECKBOX, self.OnEnable, self.enable_checkbox)
  189. self.Bind(wx.EVT_CHECKBOX, self.OnTime, self.time_checkbox)
  190. self.Bind(wx.EVT_BUTTON, self.OnClear, self.clear_button)
  191. self.Bind(wx.EVT_BUTTON, self.OnView, self.view_button)
  192. def _create_buttons_sizer(self):
  193. ''' Create buttons BoxSizer. '''
  194. sizer = wx.BoxSizer(wx.HORIZONTAL)
  195. sizer.Add(self.clear_button)
  196. sizer.AddSpacer(20)
  197. sizer.Add(self.view_button)
  198. return sizer
  199. def _create_popup(self, text, title, style):
  200. ''' Create popup. '''
  201. wx.MessageBox(text, title, style)
  202. def OnTime(self, event):
  203. ''' Event handler for self.time_checkbox. '''
  204. if self.logger is not None:
  205. self.logger.add_time = self.time_checkbox.GetValue()
  206. def OnEnable(self, event):
  207. ''' Event handler for self.enable_checkbox. '''
  208. self._create_popup(
  209. 'Please restart ' + __appname__,
  210. 'Restart',
  211. wx.OK | wx.ICON_INFORMATION
  212. )
  213. def OnClear(self, event):
  214. ''' Event handler for self.clear_button. '''
  215. if self.logger is not None:
  216. self.logger.clear()
  217. self.log_size.SetLabel("Log Size %s Bytes" % self.logger.size())
  218. def OnView(self, event):
  219. ''' Event handler for self.view_button. '''
  220. if self.logger is not None:
  221. logger_gui = LogGUI(self)
  222. logger_gui.Show()
  223. logger_gui.load(self.logger.log_file)
  224. def load_options(self, opt_manager):
  225. ''' Load panel options from OptionsHandler object. '''
  226. self.enable_checkbox.SetValue(opt_manager.options['enable_log'])
  227. self.time_checkbox.SetValue(opt_manager.options['log_time'])
  228. def save_options(self, opt_manager):
  229. ''' Save panel options to OptionsHandler object. '''
  230. opt_manager.options['enable_log'] = self.enable_checkbox.GetValue()
  231. opt_manager.options['log_time'] = self.time_checkbox.GetValue()
  232. class ShutdownPanel(wx.Panel):
  233. '''
  234. Options frame shutdown tab panel.
  235. Params
  236. parent: wx.Panel parent.
  237. '''
  238. def __init__(self, parent):
  239. wx.Panel.__init__(self, parent)
  240. self.shutdown_checkbox = wx.CheckBox(self, label='Shutdown when finished', size=WX_CHECKBOX_SIZE)
  241. self.sudo_pass_box = wx.TextCtrl(self, size=(250, 25), style=wx.TE_PASSWORD)
  242. main_sizer = wx.BoxSizer(wx.VERTICAL)
  243. main_sizer.AddSpacer(40)
  244. main_sizer.Add(self.shutdown_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  245. main_sizer.AddSpacer(20)
  246. main_sizer.Add(wx.StaticText(self, label='SUDO password'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  247. main_sizer.AddSpacer(5)
  248. main_sizer.Add(self.sudo_pass_box, flag=wx.ALIGN_CENTER_HORIZONTAL)
  249. self.SetSizer(main_sizer)
  250. self.Bind(wx.EVT_CHECKBOX, self.OnShutdownCheck, self.shutdown_checkbox)
  251. def OnShutdownCheck(self, event):
  252. ''' Event handler for self.shutdown_checkbox. '''
  253. if name != 'nt':
  254. self.sudo_pass_box.Enable(self.shutdown_checkbox.GetValue())
  255. def load_options(self, opt_manager):
  256. ''' Load panel options from OptionsHandler object. '''
  257. self.shutdown_checkbox.SetValue(opt_manager.options['shutdown'])
  258. self.sudo_pass_box.SetValue(opt_manager.options['sudo_password'])
  259. if name == 'nt' or not opt_manager.options['shutdown']:
  260. self.sudo_pass_box.Disable()
  261. def save_options(self, opt_manager):
  262. ''' Save panel options to OptionsHandler object. '''
  263. opt_manager.options['shutdown'] = self.shutdown_checkbox.GetValue()
  264. opt_manager.options['sudo_password'] = self.sudo_pass_box.GetValue()
  265. class PlaylistPanel(wx.Panel):
  266. '''
  267. Options frame playlist tab panel.
  268. Params
  269. parent: wx.Panel parent.
  270. '''
  271. def __init__(self, parent):
  272. wx.Panel.__init__(self, parent)
  273. self.start_spinner = wx.SpinCtrl(self, size=(70, 20))
  274. self.start_spinner.SetRange(1, 999)
  275. self.stop_spinner = wx.SpinCtrl(self, size=(70, 20))
  276. self.stop_spinner.SetRange(0, 999)
  277. self.max_spinner = wx.SpinCtrl(self, size=(70, 20))
  278. self.max_spinner.SetRange(0, 999)
  279. main_sizer = wx.BoxSizer(wx.VERTICAL)
  280. main_sizer.AddSpacer(20)
  281. main_sizer.Add(wx.StaticText(self, label='Playlist Start'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  282. main_sizer.AddSpacer(5)
  283. main_sizer.Add(self.start_spinner, flag=wx.ALIGN_CENTER_HORIZONTAL)
  284. main_sizer.AddSpacer(15)
  285. main_sizer.Add(wx.StaticText(self, label='Playlist Stop'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  286. main_sizer.AddSpacer(5)
  287. main_sizer.Add(self.stop_spinner, flag=wx.ALIGN_CENTER_HORIZONTAL)
  288. main_sizer.AddSpacer(15)
  289. main_sizer.Add(wx.StaticText(self, label='Max Downloads'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  290. main_sizer.AddSpacer(5)
  291. main_sizer.Add(self.max_spinner, flag=wx.ALIGN_CENTER_HORIZONTAL)
  292. self.SetSizer(main_sizer)
  293. def load_options(self, opt_manager):
  294. ''' Load panel options from OptionsHandler object. '''
  295. self.start_spinner.SetValue(opt_manager.options['playlist_start'])
  296. self.stop_spinner.SetValue(opt_manager.options['playlist_end'])
  297. self.max_spinner.SetValue(opt_manager.options['max_downloads'])
  298. def save_options(self, opt_manager):
  299. ''' Save panel options to OptionsHandler object. '''
  300. opt_manager.options['playlist_start'] = self.start_spinner.GetValue()
  301. opt_manager.options['playlist_end'] = self.stop_spinner.GetValue()
  302. opt_manager.options['max_downloads'] = self.max_spinner.GetValue()
  303. class ConnectionPanel(wx.Panel):
  304. '''
  305. Options frame connection tab panel.
  306. Params
  307. parent: wx.Panel parent.
  308. '''
  309. def __init__(self, parent):
  310. wx.Panel.__init__(self, parent)
  311. # Create components
  312. self.retries_spinner = wx.SpinCtrl(self, size=(50, -1))
  313. self.retries_spinner.SetRange(1, 99)
  314. self.user_agent_box = wx.TextCtrl(self, size=(550, -1))
  315. self.referer_box = wx.TextCtrl(self, size=(550, -1))
  316. self.proxy_box = wx.TextCtrl(self, size=(550, -1))
  317. # Set BoxSizer
  318. main_sizer = wx.BoxSizer(wx.VERTICAL)
  319. main_sizer.AddSpacer(10)
  320. main_sizer.Add(self._create_retries_sizer())
  321. main_sizer.AddSpacer(10)
  322. main_sizer.Add(wx.StaticText(self, label='User Agent'), flag=wx.LEFT, border=10)
  323. main_sizer.AddSpacer(5)
  324. main_sizer.Add(self.user_agent_box, flag=wx.LEFT, border=10)
  325. main_sizer.AddSpacer(10)
  326. main_sizer.Add(wx.StaticText(self, label='Referer'), flag=wx.LEFT, border=10)
  327. main_sizer.AddSpacer(5)
  328. main_sizer.Add(self.referer_box, flag=wx.LEFT, border=10)
  329. main_sizer.AddSpacer(10)
  330. main_sizer.Add(wx.StaticText(self, label='Proxy'), flag=wx.LEFT, border=10)
  331. main_sizer.AddSpacer(5)
  332. main_sizer.Add(self.proxy_box, flag=wx.LEFT, border=10)
  333. self.SetSizer(main_sizer)
  334. def _create_retries_sizer(self):
  335. ''' Create retries BoxSizer. '''
  336. sizer = wx.BoxSizer(wx.HORIZONTAL)
  337. sizer.AddSpacer(10)
  338. sizer.Add(wx.StaticText(self, label='Retries'))
  339. sizer.AddSpacer(5)
  340. sizer.Add(self.retries_spinner)
  341. return sizer
  342. def load_options(self, opt_manager):
  343. ''' Load panel options from OptionsHandler object. '''
  344. self.proxy_box.SetValue(opt_manager.options['proxy'])
  345. self.referer_box.SetValue(opt_manager.options['referer'])
  346. self.retries_spinner.SetValue(opt_manager.options['retries'])
  347. self.user_agent_box.SetValue(opt_manager.options['user_agent'])
  348. def save_options(self, opt_manager):
  349. ''' Save panel options to OptionsHandler object. '''
  350. opt_manager.options['proxy'] = self.proxy_box.GetValue()
  351. opt_manager.options['referer'] = self.referer_box.GetValue()
  352. opt_manager.options['retries'] = self.retries_spinner.GetValue()
  353. opt_manager.options['user_agent'] = self.user_agent_box.GetValue()
  354. class AuthenticationPanel(wx.Panel):
  355. '''
  356. Options frame authentication tab panel.
  357. Params
  358. parent: wx.Panel parent.
  359. '''
  360. def __init__(self, parent):
  361. wx.Panel.__init__(self, parent)
  362. self.username_box = wx.TextCtrl(self, size=(250, 25))
  363. self.password_box = wx.TextCtrl(self, size=(250, 25), style=wx.TE_PASSWORD)
  364. self.video_pass_box = wx.TextCtrl(self, size=(250, 25), style=wx.TE_PASSWORD)
  365. main_sizer = wx.BoxSizer(wx.VERTICAL)
  366. main_sizer.AddSpacer(15)
  367. main_sizer.Add(wx.StaticText(self, label='Username'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  368. main_sizer.AddSpacer(5)
  369. main_sizer.Add(self.username_box, flag=wx.ALIGN_CENTER_HORIZONTAL)
  370. main_sizer.AddSpacer(15)
  371. main_sizer.Add(wx.StaticText(self, label='Password'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  372. main_sizer.AddSpacer(5)
  373. main_sizer.Add(self.password_box, flag=wx.ALIGN_CENTER_HORIZONTAL)
  374. main_sizer.AddSpacer(15)
  375. main_sizer.Add(wx.StaticText(self, label='Video Password (vimeo, smotri)'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  376. main_sizer.AddSpacer(5)
  377. main_sizer.Add(self.video_pass_box, flag=wx.ALIGN_CENTER_HORIZONTAL)
  378. self.SetSizer(main_sizer)
  379. def load_options(self, opt_manager):
  380. ''' Load panel options from OptionsHandler object. '''
  381. self.username_box.SetValue(opt_manager.options['username'])
  382. self.password_box.SetValue(opt_manager.options['password'])
  383. self.video_pass_box.SetValue(opt_manager.options['video_password'])
  384. def save_options(self, opt_manager):
  385. ''' Save panel options to OptionsHandler object. '''
  386. opt_manager.options['username'] = self.username_box.GetValue()
  387. opt_manager.options['password'] = self.password_box.GetValue()
  388. opt_manager.options['video_password'] = self.video_pass_box.GetValue()
  389. class AudioPanel(wx.Panel):
  390. '''
  391. Options frame audio tab panel.
  392. Params
  393. parent: wx.Panel parent.
  394. '''
  395. def __init__(self, parent):
  396. wx.Panel.__init__(self, parent)
  397. self.to_audio_checkbox = wx.CheckBox(self, label='Convert to Audio', size=WX_CHECKBOX_SIZE)
  398. self.keep_video_checkbox = wx.CheckBox(self, label='Keep Video', size=WX_CHECKBOX_SIZE)
  399. self.audio_format_combo = wx.ComboBox(self, choices=AUDIO_FORMATS, size=(160, 30))
  400. self.audio_quality_combo = wx.ComboBox(self, choices=AUDIO_QUALITY, size=(80, 25))
  401. main_sizer = wx.BoxSizer(wx.VERTICAL)
  402. main_sizer.AddSpacer(15)
  403. main_sizer.Add(self.to_audio_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  404. main_sizer.AddSpacer(5)
  405. main_sizer.Add(self.keep_video_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  406. main_sizer.AddSpacer(10)
  407. main_sizer.Add(wx.StaticText(self, label='Audio Format'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  408. main_sizer.AddSpacer(5)
  409. main_sizer.Add(self.audio_format_combo, flag=wx.ALIGN_CENTER_HORIZONTAL)
  410. main_sizer.AddSpacer(10)
  411. main_sizer.Add(wx.StaticText(self, label='Audio Quality'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  412. main_sizer.AddSpacer(5)
  413. main_sizer.Add(self.audio_quality_combo, flag=wx.ALIGN_CENTER_HORIZONTAL)
  414. self.SetSizer(main_sizer)
  415. self.Bind(wx.EVT_CHECKBOX, self.OnAudioCheck, self.to_audio_checkbox)
  416. def OnAudioCheck(self, event):
  417. ''' Event handler for self.to_audio_checkbox. '''
  418. if self.to_audio_checkbox.GetValue():
  419. self.keep_video_checkbox.Enable()
  420. self.audio_format_combo.Enable()
  421. self.audio_quality_combo.Enable()
  422. else:
  423. self.keep_video_checkbox.Disable()
  424. self.audio_format_combo.Disable()
  425. self.audio_quality_combo.Disable()
  426. def load_options(self, opt_manager):
  427. ''' Load panel options from OptionsHandler object. '''
  428. self.to_audio_checkbox.SetValue(opt_manager.options['to_audio'])
  429. self.keep_video_checkbox.SetValue(opt_manager.options['keep_video'])
  430. self.audio_format_combo.SetValue(opt_manager.options['audio_format'])
  431. self.audio_quality_combo.SetValue(opt_manager.options['audio_quality'])
  432. self.OnAudioCheck(None)
  433. def save_options(self, opt_manager):
  434. ''' Save panel options to OptionsHandler object. '''
  435. opt_manager.options['to_audio'] = self.to_audio_checkbox.GetValue()
  436. opt_manager.options['keep_video'] = self.keep_video_checkbox.GetValue()
  437. opt_manager.options['audio_format'] = self.audio_format_combo.GetValue()
  438. opt_manager.options['audio_quality'] = self.audio_quality_combo.GetValue()
  439. class VideoPanel(wx.Panel):
  440. '''
  441. Options frame video tab panel.
  442. Params
  443. parent: wx.Panel parent.
  444. '''
  445. def __init__(self, parent):
  446. wx.Panel.__init__(self, parent)
  447. self.video_format_combo = wx.ComboBox(self, choices=VIDEO_FORMATS, size=(180, 30))
  448. self.dash_audio_combo = wx.ComboBox(self, choices=DASH_AUDIO_FORMATS, size=(180, 30))
  449. self.clear_dash_checkbox = wx.CheckBox(self, label='Clear DASH audio/video files', size=WX_CHECKBOX_SIZE)
  450. main_sizer = wx.BoxSizer(wx.VERTICAL)
  451. main_sizer.AddSpacer(20)
  452. main_sizer.Add(wx.StaticText(self, label='Video Format'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  453. main_sizer.AddSpacer(5)
  454. main_sizer.Add(self.video_format_combo, flag=wx.ALIGN_CENTER_HORIZONTAL)
  455. main_sizer.AddSpacer(10)
  456. main_sizer.Add(wx.StaticText(self, label='DASH Audio'), flag=wx.ALIGN_CENTER_HORIZONTAL)
  457. main_sizer.AddSpacer(5)
  458. main_sizer.Add(self.dash_audio_combo, flag=wx.ALIGN_CENTER_HORIZONTAL)
  459. main_sizer.AddSpacer(20)
  460. main_sizer.Add(self.clear_dash_checkbox, flag=wx.ALIGN_CENTER_HORIZONTAL)
  461. self.SetSizer(main_sizer)
  462. self.Bind(wx.EVT_COMBOBOX, self.OnVideoFormatPick, self.video_format_combo)
  463. self.Bind(wx.EVT_COMBOBOX, self.OnAudioFormatPick, self.dash_audio_combo)
  464. def OnAudioFormatPick(self, event):
  465. ''' Event handler for self.dash_audio_combo. '''
  466. if is_dash(self.dash_audio_combo.GetValue()):
  467. self.clear_dash_checkbox.Enable()
  468. else:
  469. self.clear_dash_checkbox.SetValue(False)
  470. self.clear_dash_checkbox.Disable()
  471. def OnVideoFormatPick(self, event):
  472. ''' Event handler for self.video_format_combo. '''
  473. if is_dash(self.video_format_combo.GetValue()):
  474. self.dash_audio_combo.Enable()
  475. else:
  476. self.dash_audio_combo.Disable()
  477. self.clear_dash_checkbox.Disable()
  478. self.clear_dash_checkbox.SetValue(False)
  479. self.OnAudioFormatPick(None)
  480. def load_options(self, opt_manager):
  481. ''' Load panel options from OptionsHandler object. '''
  482. self.video_format_combo.SetValue(opt_manager.options['video_format'])
  483. self.dash_audio_combo.SetValue(opt_manager.options['dash_audio_format'])
  484. self.clear_dash_checkbox.SetValue(opt_manager.options['clear_dash_files'])
  485. self.OnVideoFormatPick(None)
  486. def save_options(self, opt_manager):
  487. ''' Save panel options to OptionsHandler object. '''
  488. opt_manager.options['video_format'] = self.video_format_combo.GetValue()
  489. opt_manager.options['dash_audio_format'] = self.dash_audio_combo.GetValue()
  490. opt_manager.options['clear_dash_files'] = self.clear_dash_checkbox.GetValue()
  491. class OutputPanel(wx.Panel):
  492. '''
  493. Options frame output tab panel.
  494. Params
  495. parent: wx.Panel parent.
  496. '''
  497. def __init__(self, parent):
  498. wx.Panel.__init__(self, parent)
  499. self.restrict_filenames_checkbox = wx.CheckBox(self, label='Restrict filenames (ASCII)', size=WX_CHECKBOX_SIZE)
  500. self.id_as_name_checkbox = wx.CheckBox(self, label='ID as Name', size=WX_CHECKBOX_SIZE)
  501. self.title_checkbox = wx.CheckBox(self, label='Title as Name', size=WX_CHECKBOX_SIZE)
  502. self.custom_title_checkbox = wx.CheckBox(self, label='Custom Template (youtube-dl)', size=WX_CHECKBOX_SIZE)
  503. self.title_template_box = wx.TextCtrl(self, size=(300, 20))
  504. main_sizer = wx.BoxSizer(wx.VERTICAL)
  505. main_sizer.AddSpacer(15)
  506. main_sizer.Add(self.restrict_filenames_checkbox, flag=wx.LEFT, border=5)
  507. main_sizer.AddSpacer(5)
  508. main_sizer.Add(self.id_as_name_checkbox, flag=wx.LEFT, border=5)
  509. main_sizer.AddSpacer(5)
  510. main_sizer.Add(self.title_checkbox, flag=wx.LEFT, border=5)
  511. main_sizer.AddSpacer(5)
  512. main_sizer.Add(self.custom_title_checkbox, flag=wx.LEFT, border=5)
  513. main_sizer.AddSpacer(10)
  514. main_sizer.Add(self.title_template_box, flag=wx.LEFT, border=5)
  515. self.SetSizer(main_sizer)
  516. self.Bind(wx.EVT_CHECKBOX, self.OnCheck, self.id_as_name_checkbox)
  517. self.Bind(wx.EVT_CHECKBOX, self.OnCheck, self.title_checkbox)
  518. self.Bind(wx.EVT_CHECKBOX, self.OnCheck, self.custom_title_checkbox)
  519. def _group_load(self, output_format):
  520. ''' Disable components base on output_format. '''
  521. if output_format == 'id':
  522. self.id_as_name_checkbox.SetValue(True)
  523. self.title_checkbox.SetValue(False)
  524. self.custom_title_checkbox.SetValue(False)
  525. self.title_template_box.Disable()
  526. elif output_format == 'title':
  527. self.id_as_name_checkbox.SetValue(False)
  528. self.title_checkbox.SetValue(True)
  529. self.custom_title_checkbox.SetValue(False)
  530. self.title_template_box.Disable()
  531. elif output_format == 'custom':
  532. self.id_as_name_checkbox.SetValue(False)
  533. self.title_checkbox.SetValue(False)
  534. self.custom_title_checkbox.SetValue(True)
  535. self.title_template_box.Enable()
  536. def _get_output_format(self):
  537. ''' Return output_format. '''
  538. if self.id_as_name_checkbox.GetValue():
  539. return 'id'
  540. elif self.title_checkbox.GetValue():
  541. return 'title'
  542. elif self.custom_title_checkbox.GetValue():
  543. return 'custom'
  544. def OnCheck(self, event):
  545. ''' Event handler for output checkboxes. '''
  546. box = event.GetEventObject()
  547. if box == self.id_as_name_checkbox:
  548. output_format = 'id'
  549. elif box == self.title_checkbox:
  550. output_format = 'title'
  551. else:
  552. output_format = 'custom'
  553. self._group_load(output_format)
  554. def load_options(self, opt_manager):
  555. ''' Load panel options from OptionsHandler object. '''
  556. self._group_load(opt_manager.options['output_format'])
  557. self.title_template_box.SetValue(opt_manager.options['output_template'])
  558. self.restrict_filenames_checkbox.SetValue(opt_manager.options['restrict_filenames'])
  559. def save_options(self, opt_manager):
  560. ''' Save panel options to OptionsHandler object. '''
  561. opt_manager.options['output_format'] = self._get_output_format()
  562. opt_manager.options['output_template'] = self.title_template_box.GetValue()
  563. opt_manager.options['restrict_filenames'] = self.restrict_filenames_checkbox.GetValue()
  564. class FilesystemPanel(wx.Panel):
  565. '''
  566. Options frame filesystem tab panel.
  567. Params
  568. parent: wx.Panel parent.
  569. '''
  570. def __init__(self, parent):
  571. wx.Panel.__init__(self, parent)
  572. self.ignore_errors_checkbox = wx.CheckBox(self, label='Ignore Errors', size=WX_CHECKBOX_SIZE)
  573. self.open_dir_checkbox = wx.CheckBox(self, label='Open download folder', size=WX_CHECKBOX_SIZE)
  574. self.write_info_checkbox = wx.CheckBox(self, label='Write info to (.json) file', size=WX_CHECKBOX_SIZE)
  575. self.write_desc_checkbox = wx.CheckBox(self, label='Write description to file', size=WX_CHECKBOX_SIZE)
  576. self.write_thumbnail_checkbox = wx.CheckBox(self, label='Write thumbnail to disk', size=WX_CHECKBOX_SIZE)
  577. self.min_filesize_box = wx.TextCtrl(self, size=(70, -1))
  578. self.max_filesize_box = wx.TextCtrl(self, size=(70, -1))
  579. main_sizer = wx.BoxSizer(wx.HORIZONTAL)
  580. main_sizer.Add(self._set_left_sizer(), flag=wx.EXPAND)
  581. main_sizer.AddSpacer(150)
  582. main_sizer.Add(self._set_right_sizer(), 1, flag=wx.EXPAND)
  583. self.SetSizer(main_sizer)
  584. def _set_left_sizer(self):
  585. ''' Set left BoxSizer. '''
  586. sizer = wx.BoxSizer(wx.VERTICAL)
  587. sizer.AddSpacer(15)
  588. sizer.Add(self.ignore_errors_checkbox, flag=wx.LEFT, border=5)
  589. sizer.AddSpacer(5)
  590. sizer.Add(self.open_dir_checkbox, flag=wx.LEFT, border=5)
  591. sizer.AddSpacer(5)
  592. sizer.Add(self.write_desc_checkbox, flag=wx.LEFT, border=5)
  593. sizer.AddSpacer(5)
  594. sizer.Add(self.write_thumbnail_checkbox, flag=wx.LEFT, border=5)
  595. sizer.AddSpacer(5)
  596. sizer.Add(self.write_info_checkbox, flag=wx.LEFT, border=5)
  597. return sizer
  598. def _set_right_sizer(self):
  599. ''' Set right BoxSizer. '''
  600. static_box = wx.StaticBox(self, label='Filesize (e.g. 50k or 44.6m)')
  601. sizer = wx.StaticBoxSizer(static_box, wx.VERTICAL)
  602. sizer.AddSpacer(50)
  603. # Cross platform hack for the horizontal sizer
  604. # so it looks the same both on Windows & Linux
  605. extra_border = 0
  606. if name != 'nt':
  607. extra_border = 3
  608. hor_sizer = wx.BoxSizer(wx.HORIZONTAL)
  609. hor_sizer.Add(wx.StaticText(self, label='Min'))
  610. hor_sizer.AddSpacer(10 + extra_border)
  611. hor_sizer.Add(self.min_filesize_box)
  612. sizer.Add(hor_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)
  613. sizer.AddSpacer(10)
  614. hor_sizer = wx.BoxSizer(wx.HORIZONTAL)
  615. hor_sizer.Add(wx.StaticText(self, label='Max'))
  616. hor_sizer.AddSpacer(10)
  617. hor_sizer.Add(self.max_filesize_box)
  618. sizer.Add(hor_sizer, flag=wx.ALIGN_CENTER_HORIZONTAL)
  619. return sizer
  620. def load_options(self, opt_manager):
  621. ''' Load panel options from OptionsHandler object. '''
  622. self.open_dir_checkbox.SetValue(opt_manager.options['open_dl_dir'])
  623. self.min_filesize_box.SetValue(opt_manager.options['min_filesize'])
  624. self.max_filesize_box.SetValue(opt_manager.options['max_filesize'])
  625. self.write_info_checkbox.SetValue(opt_manager.options['write_info'])
  626. self.ignore_errors_checkbox.SetValue(opt_manager.options['ignore_errors'])
  627. self.write_desc_checkbox.SetValue(opt_manager.options['write_description'])
  628. self.write_thumbnail_checkbox.SetValue(opt_manager.options['write_thumbnail'])
  629. def save_options(self, opt_manager):
  630. ''' Save panel options to OptionsHandler object. '''
  631. opt_manager.options['write_thumbnail'] = self.write_thumbnail_checkbox.GetValue()
  632. opt_manager.options['write_description'] = self.write_desc_checkbox.GetValue()
  633. opt_manager.options['ignore_errors'] = self.ignore_errors_checkbox.GetValue()
  634. opt_manager.options['write_info'] = self.write_info_checkbox.GetValue()
  635. opt_manager.options['open_dl_dir'] = self.open_dir_checkbox.GetValue()
  636. opt_manager.options['min_filesize'] = self.min_filesize_box.GetValue()
  637. opt_manager.options['max_filesize'] = self.max_filesize_box.GetValue()
  638. # Check min_filesize input
  639. if opt_manager.options['min_filesize'] == '':
  640. opt_manager.options['min_filesize'] = '0'
  641. if opt_manager.options['max_filesize'] == '':
  642. opt_manager.options['max_filesize'] = '0'
  643. class SubtitlesPanel(wx.Panel):
  644. '''
  645. Options frame subtitles tab panel.
  646. Params
  647. parent: wx.Panel parent.
  648. '''
  649. def __init__(self, parent):
  650. wx.Panel.__init__(self, parent)
  651. self.write_subs_checkbox = wx.CheckBox(self, label='Download subtitle file by language', size=WX_CHECKBOX_SIZE)
  652. self.write_all_subs_checkbox = wx.CheckBox(self, label='Download all available subtitles', size=WX_CHECKBOX_SIZE)
  653. self.write_auto_subs_checkbox = wx.CheckBox(self, label='Download automatic subtitle file (YOUTUBE ONLY)', size=WX_CHECKBOX_SIZE)
  654. self.embed_subs_checkbox = wx.CheckBox(self, label='Embed subtitles in the video (only for mp4 videos)', size=WX_CHECKBOX_SIZE)
  655. self.subs_languages_combo = wx.ComboBox(self, choices=SUBS_LANG, size=(140, 30))
  656. self.embed_subs_checkbox.Disable()
  657. self.subs_languages_combo.Disable()
  658. main_sizer = wx.BoxSizer(wx.VERTICAL)
  659. main_sizer.AddSpacer(15)
  660. main_sizer.Add(self.write_subs_checkbox, flag=wx.LEFT, border=5)
  661. main_sizer.AddSpacer(5)
  662. main_sizer.Add(self.write_all_subs_checkbox, flag=wx.LEFT, border=5)
  663. main_sizer.AddSpacer(5)
  664. main_sizer.Add(self.write_auto_subs_checkbox, flag=wx.LEFT, border=5)
  665. main_sizer.AddSpacer(5)
  666. main_sizer.Add(self.embed_subs_checkbox, flag=wx.LEFT, border=5)
  667. main_sizer.AddSpacer(10)
  668. main_sizer.Add(wx.StaticText(self, label='Subtitles Langues'), flag=wx.LEFT, border=10)
  669. main_sizer.AddSpacer(5)
  670. main_sizer.Add(self.subs_languages_combo, flag=wx.LEFT, border=15)
  671. self.SetSizer(main_sizer)
  672. self.Bind(wx.EVT_CHECKBOX, self.OnWriteSubsChk, self.write_subs_checkbox)
  673. self.Bind(wx.EVT_CHECKBOX, self.OnWriteAllSubsChk, self.write_all_subs_checkbox)
  674. self.Bind(wx.EVT_CHECKBOX, self.OnWriteAutoSubsChk, self.write_auto_subs_checkbox)
  675. def OnWriteAutoSubsChk(self, event):
  676. ''' Event handler for self.write_auto_subs_checkbox. '''
  677. if self.write_auto_subs_checkbox.GetValue():
  678. self.embed_subs_checkbox.Enable()
  679. self.write_subs_checkbox.Disable()
  680. self.write_all_subs_checkbox.Disable()
  681. else:
  682. self.embed_subs_checkbox.Disable()
  683. self.embed_subs_checkbox.SetValue(False)
  684. self.write_subs_checkbox.Enable()
  685. self.write_all_subs_checkbox.Enable()
  686. def OnWriteSubsChk(self, event):
  687. ''' Event handler for self.write_subs_checkbox. '''
  688. if self.write_subs_checkbox.GetValue():
  689. self.embed_subs_checkbox.Enable()
  690. self.subs_languages_combo.Enable()
  691. self.write_all_subs_checkbox.Disable()
  692. self.write_auto_subs_checkbox.Disable()
  693. else:
  694. self.embed_subs_checkbox.Disable()
  695. self.embed_subs_checkbox.SetValue(False)
  696. self.subs_languages_combo.Disable()
  697. self.write_all_subs_checkbox.Enable()
  698. self.write_auto_subs_checkbox.Enable()
  699. def OnWriteAllSubsChk(self, event):
  700. ''' Event handler for self.write_all_subs_checkbox. '''
  701. if self.write_all_subs_checkbox.GetValue():
  702. self.write_subs_checkbox.Disable()
  703. self.write_auto_subs_checkbox.Disable()
  704. else:
  705. self.write_subs_checkbox.Enable()
  706. self.write_auto_subs_checkbox.Enable()
  707. def load_options(self, opt_manager):
  708. ''' Load panel options from OptionsHandler object. '''
  709. self.write_subs_checkbox.SetValue(opt_manager.options['write_subs'])
  710. self.subs_languages_combo.SetValue(opt_manager.options['subs_lang'])
  711. self.embed_subs_checkbox.SetValue(opt_manager.options['embed_subs'])
  712. self.write_all_subs_checkbox.SetValue(opt_manager.options['write_all_subs'])
  713. self.write_auto_subs_checkbox.SetValue(opt_manager.options['write_auto_subs'])
  714. self.OnWriteSubsChk(None)
  715. self.OnWriteAllSubsChk(None)
  716. self.OnWriteAutoSubsChk(None)
  717. def save_options(self, opt_manager):
  718. ''' Save panel options to OptionsHandler object. '''
  719. opt_manager.options['write_subs'] = self.write_subs_checkbox.GetValue()
  720. opt_manager.options['subs_lang'] = self.subs_languages_combo.GetValue()
  721. opt_manager.options['embed_subs'] = self.embed_subs_checkbox.GetValue()
  722. opt_manager.options['write_all_subs'] = self.write_all_subs_checkbox.GetValue()
  723. opt_manager.options['write_auto_subs'] = self.write_auto_subs_checkbox.GetValue()
  724. class GeneralPanel(wx.Panel):
  725. '''
  726. Options frame general tab panel.
  727. Params
  728. parent: wx.Panel parent.
  729. opt_manager: OptionsHandler.OptionsHandler object.
  730. reset_handler: Method to reset all options & frame.
  731. '''
  732. def __init__(self, parent, opt_manager, reset_handler):
  733. wx.Panel.__init__(self, parent)
  734. self.reset_handler = reset_handler
  735. self.savepath_box = wx.TextCtrl(self)
  736. self.about_button = wx.Button(self, label='About', size=(110, 40))
  737. self.open_button = wx.Button(self, label='Open', size=(110, 40))
  738. self.reset_button = wx.Button(self, label='Reset Options', size=(110, 40))
  739. main_sizer = wx.BoxSizer(wx.VERTICAL)
  740. main_sizer.AddSpacer(20)
  741. sp_label = wx.StaticText(self, label='Save Path')
  742. main_sizer.Add(sp_label, flag=wx.ALIGN_CENTER_HORIZONTAL)
  743. main_sizer.AddSpacer(10)
  744. main_sizer.Add(self._create_savepath_sizer(), flag=wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND)
  745. main_sizer.AddSpacer(20)
  746. main_sizer.Add(self._create_buttons_sizer(), flag=wx.ALIGN_CENTER_HORIZONTAL)
  747. main_sizer.AddSpacer(30)
  748. settings_file = wx.StaticText(self, label='Settings: ' + opt_manager.settings_file)
  749. main_sizer.Add(settings_file, flag=wx.ALIGN_CENTER_HORIZONTAL)
  750. self.SetSizer(main_sizer)
  751. self.Bind(wx.EVT_BUTTON, self.OnOpen, self.open_button)
  752. self.Bind(wx.EVT_BUTTON, self.OnAbout, self.about_button)
  753. self.Bind(wx.EVT_BUTTON, self.OnReset, self.reset_button)
  754. def _create_savepath_sizer(self):
  755. ''' Return self.savepath_box BoxSizer. '''
  756. sizer = wx.BoxSizer(wx.HORIZONTAL)
  757. sizer.Add(self.savepath_box, 1, flag=wx.LEFT | wx.RIGHT, border=80)
  758. return sizer
  759. def _create_buttons_sizer(self):
  760. ''' Return buttons BoxSizer. '''
  761. sizer = wx.BoxSizer(wx.HORIZONTAL)
  762. sizer.Add(self.about_button)
  763. sizer.Add(self.open_button, flag=wx.LEFT | wx.RIGHT, border=50)
  764. sizer.Add(self.reset_button)
  765. return sizer
  766. def OnReset(self, event):
  767. ''' Event handler reset button. '''
  768. self.reset_handler()
  769. def OnOpen(self, event):
  770. ''' Event handler open button. '''
  771. dlg = wx.DirDialog(None, "Choose directory")
  772. if dlg.ShowModal() == wx.ID_OK:
  773. self.savepath_box.SetValue(dlg.GetPath())
  774. dlg.Destroy()
  775. def OnAbout(self, event):
  776. ''' Event handler about button. '''
  777. info = wx.AboutDialogInfo()
  778. # Load about icon
  779. app_icon = get_icon_path()
  780. if app_icon is not None:
  781. info.SetIcon(wx.Icon(app_icon, wx.BITMAP_TYPE_PNG))
  782. info.SetName(__appname__)
  783. info.SetVersion(__version__)
  784. info.SetDescription(__descriptionfull__)
  785. info.SetWebSite(__projecturl__)
  786. info.SetLicense(__licensefull__)
  787. info.AddDeveloper(__author__)
  788. wx.AboutBox(info)
  789. def load_options(self, opt_manager):
  790. ''' Load panel options from OptionsHandler object. '''
  791. self.savepath_box.SetValue(opt_manager.options['save_path'])
  792. def save_options(self, opt_manager):
  793. ''' Save panel options to OptionsHandler object. '''
  794. opt_manager.options['save_path'] = fix_path(self.savepath_box.GetValue())
  795. class OtherPanel(wx.Panel):
  796. '''
  797. Options frame command tab panel.
  798. Params
  799. parent: wx.Panel parent.
  800. '''
  801. def __init__(self, parent):
  802. wx.Panel.__init__(self, parent)
  803. self.cmd_args_box = wx.TextCtrl(self)
  804. main_sizer = wx.BoxSizer(wx.VERTICAL)
  805. main_sizer.AddSpacer(50)
  806. label = wx.StaticText(self, label='Command line arguments (e.g. --help)')
  807. main_sizer.Add(label, flag=wx.ALIGN_CENTER_HORIZONTAL)
  808. main_sizer.AddSpacer(10)
  809. main_sizer.Add(self._create_cmd_sizer(), flag=wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND)
  810. self.SetSizer(main_sizer)
  811. def _create_cmd_sizer(self):
  812. ''' Create BoxSizer for self.cmd_args_box. '''
  813. sizer = wx.BoxSizer(wx.HORIZONTAL)
  814. sizer.Add(self.cmd_args_box, 1, wx.LEFT | wx.RIGHT, border=80)
  815. return sizer
  816. def load_options(self, opt_manager):
  817. ''' Load panel options from OptionsHandler object. '''
  818. self.cmd_args_box.SetValue(opt_manager.options['cmd_args'])
  819. def save_options(self, opt_manager):
  820. ''' Save panel options to OptionsHandler object. '''
  821. opt_manager.options['cmd_args'] = self.cmd_args_box.GetValue()