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.

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