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.

1020 lines
37 KiB

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