Advertisement
Guest User

Untitled

a guest
Mar 11th, 2019
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.79 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. __author__ = "Jannik Hauptvogel"
  4. __maintainer__ = "Jannik Hauptvogel"
  5. __email__ = "JannikHv@gmail.com"
  6. __twitter__ = "https://twitter.com/JannikHv"
  7. __git__ = "https://github.com/JannikHv/gydl"
  8. __aur__ = "https://aur.archlinux.org/packages/gydl-git/"
  9. __credits__ = "rg3"
  10. __license__ = "GPLv2"
  11.  
  12. import gi
  13. gi.require_version("Gtk", "3.0")
  14. from gi.repository import (Gtk, Gdk, GLib, Gio)
  15. from os import system
  16.  
  17. class Gydl:
  18. class DialogType:
  19. NET_ERROR = 0
  20. DL_ERROR = 1
  21. DL_FINISH = 2
  22.  
  23.  
  24.  
  25. class ViewType:
  26. AUDIO = 0
  27. VIDEO = 1
  28.  
  29.  
  30.  
  31. class Downloader:
  32. def get_can_reach(self, URL):
  33. try:
  34. Gio.NetworkMonitor.can_reach(Gio.NetworkMonitor.get_default(),
  35. Gio.NetworkAddress.new(URL, 0),
  36. Gio.Cancellable.new())
  37. return True
  38. except:
  39. pass
  40.  
  41. return False
  42.  
  43. def get_audio(self, URL, FORMAT, QUALITY):
  44. cmd = ("youtube-dl --no-playlist -x "
  45. + "--audio-format FFF "
  46. + "--audio-quality QQQ "
  47. + "-o \""
  48. + GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)
  49. + "/%(title)s.%(ext)s\" \"UUU\"")
  50.  
  51. cmd = cmd.replace("FFF", FORMAT)
  52. cmd = cmd.replace("QQQ", QUALITY)
  53. cmd = cmd.replace("UUU", URL)
  54.  
  55. if system(cmd) is 0:
  56. return True
  57. else:
  58. return False
  59.  
  60. def get_video(self, URL, FORMAT, QUALITY):
  61. cmd = ("youtube-dl --no-playlist "
  62. + "-f [ext=FFF+height=QQQ] "
  63. + "-o \""
  64. + GLib.get_user_special_dir(GLib.USER_DIRECTORY_DOWNLOAD)
  65. + "/%(title)s.%(ext)s\" \"UUU\"")
  66.  
  67. cmd = cmd.replace("FFF", FORMAT)
  68. cmd = cmd.replace("QQQ", QUALITY.replace("p", ""))
  69. cmd = cmd.replace("UUU", URL)
  70.  
  71. if system(cmd) is 0:
  72. return True
  73. else:
  74. return False
  75.  
  76.  
  77.  
  78. class Dialog(Gtk.Window):
  79. def __continue_button_clicked(self, widget, data):
  80. self.disconnect_by_func(Gtk.main_quit)
  81. self.close()
  82.  
  83. def __get_title_from_type(self, dialog_type):
  84. if dialog_type is Gydl.DialogType.NET_ERROR:
  85. return "Connection Error"
  86. elif dialog_type is Gydl.DialogType.DL_ERROR:
  87. return "Download Failed"
  88. elif dialog_type is Gydl.DialogType.DL_FINISH:
  89. return "Download Successful"
  90. else:
  91. return None
  92.  
  93. def __get_text_from_type(self, dialog_type):
  94. if dialog_type is Gydl.DialogType.NET_ERROR:
  95. return ("An internet connection error has occured.\n"
  96. + "Make sure you're connected to the internet.")
  97. elif dialog_type is Gydl.DialogType.DL_ERROR:
  98. return ("The download has been unsuccessful.\n"
  99. + "Make sure the URL you've entered is valid.")
  100. elif dialog_type is Gydl.DialogType.DL_FINISH:
  101. return ("The download has been successful.\n"
  102. + "The file has been saved in your download folder.")
  103. else:
  104. return None
  105.  
  106. def __init__(self, dialog_type):
  107. Gtk.Window.__init__(self, Gtk.WindowType.TOPLEVEL)
  108.  
  109. self.hbar = Gtk.HeaderBar()
  110. self.grid = Gtk.Grid()
  111.  
  112. self.label = Gtk.Label(None)
  113. self.btn_leave = Gtk.Button.new_with_mnemonic("_Leave")
  114. self.btn_continue = Gtk.Button.new_with_mnemonic("_Continue")
  115.  
  116. # Window
  117. self.set_default_size(400, 200)
  118. self.set_titlebar(self.hbar)
  119. self.set_position(Gtk.WindowPosition.CENTER)
  120. self.set_icon_name("gydl")
  121. self.add(self.grid)
  122. self.connect("destroy", Gtk.main_quit, None)
  123.  
  124. # Header bar
  125. self.hbar.set_title(self.__get_title_from_type(dialog_type))
  126.  
  127. # Grid
  128. self.grid.set_column_homogeneous(True)
  129. self.grid.set_row_homogeneous(True)
  130.  
  131. # Label
  132. self.label.set_text(self.__get_text_from_type(dialog_type))
  133.  
  134. # Buttons
  135. self.btn_leave.connect("clicked", Gtk.main_quit, None)
  136. self.btn_continue.connect("clicked", self.__continue_button_clicked, None)
  137. self.btn_continue.get_style_context().add_class("suggested-action")
  138.  
  139. # Attach widgets to grid
  140. self.grid.attach(self.label, 0, 0, 2, 3)
  141. self.grid.attach(self.btn_leave, 0, 3, 1, 1)
  142. self.grid.attach(self.btn_continue, 1, 3, 1, 1)
  143.  
  144.  
  145.  
  146. class View(Gtk.Grid):
  147. def __build_audio(self):
  148. for entry in ["aac", "m4a", "mp3", "vorbis", "wav"]:
  149. self.format.append_text(entry)
  150.  
  151. for entry in ["0 (Best)", "1", "2", "3", "4", "5 (Average)", "6", "7", "8", "9 (Smallest)"]:
  152. self.quality.append_text(entry)
  153.  
  154. self.format.set_active(2)
  155. self.quality.set_active(0)
  156.  
  157. def __build_video(self):
  158. for entry in ["3gp", "flv", "mp4", "webm"]:
  159. self.format.append_text(entry)
  160.  
  161. for entry in ["2160p", "1440p", "1080p", "720p",
  162. "480p", "360p", "240p", "144p"]:
  163. self.quality.append_text(entry)
  164.  
  165. self.format.set_active(2)
  166. self.quality.set_active(3)
  167.  
  168. def get_url(self):
  169. return self.entry.get_text()
  170.  
  171. def get_format(self):
  172. return self.format.get_active_text()
  173.  
  174. def get_quality(self):
  175. return self.quality.get_active_text()[0]
  176.  
  177. def __init__(self, view_type):
  178. Gtk.Grid.__init__(self)
  179.  
  180. self.l_entry = Gtk.Label(None)
  181. self.l_format = Gtk.Label(None)
  182. self.l_quality = Gtk.Label(None)
  183.  
  184. self.entry = Gtk.Entry()
  185. self.format = Gtk.ComboBoxText()
  186. self.quality = Gtk.ComboBoxText()
  187.  
  188. # Grid
  189. self.set_column_homogeneous(True)
  190. self.set_border_width(10)
  191.  
  192. # Labels
  193. self.l_entry.set_markup("<span size='15000'><u>\nEnter the URL\n</u></span>")
  194. self.l_format.set_markup("<span size='15000'><u>\nFormat\n</u></span>")
  195. self.l_quality.set_markup("<span size='15000'><u>\nQuality\n</u></span>")
  196.  
  197. # Entry
  198. self.entry.set_placeholder_text("https://youtube.com/watch...")
  199.  
  200. # Combo boxes
  201. self.format.set_border_width(5)
  202. self.quality.set_border_width(5)
  203.  
  204. # Attach widgets to grid
  205. self.attach(self.l_entry, 0, 0, 4, 1)
  206. self.attach(self.entry, 0, 1, 4, 1)
  207. self.attach(self.l_format, 0, 2, 2, 1)
  208. self.attach(self.l_quality, 2, 2, 2, 1)
  209. self.attach(self.format, 0, 3, 2, 1)
  210. self.attach(self.quality, 2, 3, 2, 1)
  211.  
  212. # Check view type
  213. if view_type is Gydl.ViewType.AUDIO:
  214. self.__build_audio()
  215. elif view_type is Gydl.ViewType.VIDEO:
  216. self.__build_video()
  217. else:
  218. pass
  219.  
  220.  
  221.  
  222. class Window(Gtk.Window):
  223. def __hide_all(self):
  224. self.hide()
  225. Gdk.flush()
  226.  
  227. def __show_all(self):
  228. self.show_all()
  229. Gdk.flush()
  230.  
  231. def __dialog_closed(self, widget, data, null):
  232. self.__show_all()
  233.  
  234. def __download_button_clicked(self, widget, data):
  235. self.__hide_all()
  236.  
  237. # Check internet connection
  238. if not self.downloader.get_can_reach("youtube.com"):
  239. dialog = Gydl.Dialog(Gydl.DialogType.NET_ERROR)
  240. dialog.show_all()
  241. dialog.connect("delete-event", self.__dialog_closed, None)
  242. return
  243.  
  244. # Collect data
  245. if self.stack.get_visible_child_name() == "Audio":
  246. dl_exit = self.downloader.get_audio(self.view_audio.get_url(),
  247. self.view_audio.get_format(),
  248. self.view_audio.get_quality())
  249. elif self.stack.get_visible_child_name() == "Video":
  250. dl_exit = self.downloader.get_video(self.view_video.get_url(),
  251. self.view_video.get_format(),
  252. self.view_video.get_quality())
  253. else:
  254. dl_exit = False
  255.  
  256. if dl_exit:
  257. dialog = Gydl.Dialog(Gydl.DialogType.DL_FINISH)
  258. else:
  259. dialog = Gydl.Dialog(Gydl.DialogType.DL_ERROR)
  260.  
  261. dialog.connect("delete-event", self.__dialog_closed, None)
  262. dialog.show_all()
  263.  
  264. def __init__(self):
  265. Gtk.Window.__init__(self, Gtk.WindowType.TOPLEVEL)
  266.  
  267. self.downloader = Gydl.Downloader()
  268.  
  269. self.hbar = Gtk.HeaderBar()
  270. self.stack = Gtk.Stack()
  271. self.view_audio = Gydl.View(Gydl.ViewType.AUDIO)
  272. self.view_video = Gydl.View(Gydl.ViewType.VIDEO)
  273.  
  274. self.switcher = Gtk.StackSwitcher()
  275. self.btn_lv = Gtk.Button.new_with_mnemonic("_Leave")
  276. self.btn_dl = Gtk.Button.new_with_mnemonic("_Download")
  277.  
  278. # Window
  279. self.set_default_size(525, 275)
  280. self.set_titlebar(self.hbar)
  281. self.set_position(Gtk.WindowPosition.CENTER)
  282. self.set_icon_name("gydl")
  283. self.add(self.stack)
  284.  
  285. # Header bar
  286. self.hbar.pack_start(self.btn_lv)
  287. self.hbar.pack_end(self.btn_dl)
  288. self.hbar.set_custom_title(self.switcher)
  289.  
  290. # Stack
  291. self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
  292. self.stack.add_titled(self.view_audio, "Audio", "Audio")
  293. self.stack.add_titled(self.view_video, "Video", "Video")
  294.  
  295. # Stack switcher
  296. self.switcher.set_stack(self.stack)
  297.  
  298. # Header bar buttons
  299. self.btn_lv.connect("clicked", Gtk.main_quit, None)
  300. self.btn_dl.connect("clicked", self.__download_button_clicked, None)
  301. self.btn_dl.get_style_context().add_class("suggested-action")
  302.  
  303.  
  304.  
  305. if __name__ == "__main__":
  306. Window = Gydl.Window()
  307. Window.connect("delete-event", Gtk.main_quit, None)
  308. Window.show_all()
  309. Gtk.main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement