Ejemplo n.º 1
0
 def __init__(self, version):
     super().__init__(application_id='com.github.unrud.VideoDownloader',
                      flags=Gio.ApplicationFlags.NON_UNIQUE)
     self.add_main_option('url', ord('u'),
                          GLib.OptionFlags.NONE, GLib.OptionArg.STRING,
                          N_('Prefill URL field'), 'URL')
     GLib.set_application_name(N_('Video Downloader'))
     self.version = version
     self.model = Model(self)
     self._settings = Gio.Settings.new(self.props.application_id)
     self.model.download_dir = self._settings.get_string('download-folder')
     self.model.prefer_mpeg = self._settings.get_boolean('prefer-mpeg')
     self.model.mode = self._settings.get_string('mode')
     r = self._settings.get_uint('resolution')
     for resolution in sorted(x[0] for x in self.model.resolutions):
         if r <= resolution:
             break
     self.model.resolution = resolution
     bind_property(
         self.model,
         'mode',
         func_a_to_b=lambda x: self._settings.set_string('mode', x))
     bind_property(
         self.model,
         'resolution',
         func_a_to_b=lambda x: self._settings.set_uint('resolution', x))
Ejemplo n.º 2
0
 def __init__(self, version):
     super().__init__(application_id='com.github.unrud.VideoDownloader',
                      flags=Gio.ApplicationFlags.NON_UNIQUE)
     self.add_main_option('url', ord('u'),
                          GLib.OptionFlags.NONE, GLib.OptionArg.STRING,
                          N_('Prefill URL field'), 'URL')
     GLib.set_application_name(N_('Video Downloader'))
     self.version = version
     self.model = Model(self)
     self._settings = Gio.Settings.new(self.props.application_id)
     self.model.download_dir = self._settings.get_string('download-folder')
     self.model.prefer_mpeg = self._settings.get_boolean('prefer-mpeg')
     self._settings.bind('mode', self.model, 'mode',
                         (Gio.SettingsBindFlags.DEFAULT
                          | Gio.SettingsBindFlags.GET_NO_CHANGES))
     r = self._settings.get_uint('resolution')
     for resolution in sorted(x[0] for x in self.model.resolutions):
         if r <= resolution:
             break
     self.model.resolution = resolution
     self._settings.bind('resolution', self.model, 'resolution',
                         Gio.SettingsBindFlags.SET)
     self._settings.bind('dark-mode', Gtk.Settings.get_default(),
                         'gtk-application-prefer-dark-theme',
                         Gio.SettingsBindFlags.DEFAULT)
Ejemplo n.º 3
0
 def __init__(self):
     tk.Tk.__init__(self)
     # BUG: Fonts don't work, when they are not created here.
     f1 = tk.font.Font(self)
     f2 = tk.font.Font(self)
     icon = Image.open(os.path.join(pkgdatadir, "icon.png"))
     icon = ImageTk.PhotoImage(icon)
     self.wm_iconphoto(True, icon)
     BaseWindowMixin.__init__(self, Platform(self, [f1, f2]))
     self.active_page = None
     self.minsize(round(self.winfo_fpixels("480p")),
                  round(self.winfo_fpixels("180p")))
     self.title(g_("Video Downloader"))
     self.model = Model(self, self)
     self.protocol("WM_DELETE_WINDOW", self.quit)
     self.create_widgets()
Ejemplo n.º 4
0
 def __init__(self):
     super().__init__(application_id='com.github.unrud.VideoDownloader',
                      flags=Gio.ApplicationFlags.NON_UNIQUE)
     GLib.set_application_name(N_('Video Downloader'))
     self.model = Model(self)
     self._settings = Gio.Settings.new(self.props.application_id)
     self.model.download_dir = self._settings.get_string('download-folder')
     self.model.mode = self._settings.get_string('mode')
     r = self._settings.get_uint('resolution')
     for resolution in sorted(x[0] for x in self.model.resolutions):
         if r <= resolution:
             break
     self.model.resolution = resolution
     bind_property(
         self.model,
         'mode',
         func_a_to_b=lambda x: self._settings.set_string('mode', x))
     bind_property(
         self.model,
         'resolution',
         func_a_to_b=lambda x: self._settings.set_uint('resolution', x))
Ejemplo n.º 5
0
class Application(Gtk.Application, Handler):
    def __init__(self):
        super().__init__(application_id='com.github.unrud.VideoDownloader',
                         flags=Gio.ApplicationFlags.NON_UNIQUE)
        self.add_main_option(
            'url', ord('u'), GLib.OptionFlags.NONE, GLib.OptionArg.STRING,
            N_('Prefill URL field'), 'URL')
        GLib.set_application_name(N_('Video Downloader'))
        self.model = Model(self)
        self._settings = Gio.Settings.new(self.props.application_id)
        self.model.download_dir = self._settings.get_string('download-folder')
        self.model.prefer_mpeg = self._settings.get_boolean('prefer-mpeg')
        self.model.mode = self._settings.get_string('mode')
        r = self._settings.get_uint('resolution')
        for resolution in sorted(x[0] for x in self.model.resolutions):
            if r <= resolution:
                break
        self.model.resolution = resolution
        bind_property(self.model, 'mode', func_a_to_b=lambda x:
                      self._settings.set_string('mode', x))
        bind_property(self.model, 'resolution', func_a_to_b=lambda x:
                      self._settings.set_uint('resolution', x))

    def do_startup(self):
        Gtk.Application.do_startup(self)
        Handy.init()

    def do_activate(self):
        for name in self.model.actions.list_actions():
            self.add_action(self.model.actions.lookup_action(name))
        win = self.props.active_window
        if not win:
            win = Window(application=self)
            win.set_default_icon_name(self.props.application_id)
        win.present()

    def do_shutdown(self):
        self.model.shutdown()
        Gtk.Application.do_shutdown(self)

    def do_handle_local_options(self, options):
        url_variant = options.lookup_value('url', GLib.VariantType('s'))
        if url_variant:
            self.model.url = url_variant.get_string()
        return -1

    def on_playlist_request(self):
        dialog = PlaylistDialog(self.props.active_window)
        res = dialog.run()
        dialog.destroy()
        return res == Gtk.ResponseType.YES

    def on_login_request(self):
        dialog = LoginDialog(self.props.active_window)
        res = dialog.run()
        dialog.destroy()
        if res == Gtk.ResponseType.OK:
            return (dialog.username, dialog.password)
        self.lookup_action('cancel').activate()
        return ('', '')

    def on_videopassword_request(self) -> str:
        dialog = PasswordDialog(self.props.active_window)
        res = dialog.run()
        dialog.destroy()
        if res == Gtk.ResponseType.OK:
            return dialog.password
        self.lookup_action('cancel').activate()
        return ''
Ejemplo n.º 6
0
 def __init__(self, application):
     super().__init__(application=application)
     self.uuid = str(uuid.uuid4())  # Id for matching notifications
     self.model = model = Model(self)
     # Setup actions
     for name in model.actions.list_actions():
         self.add_action(model.actions.lookup_action(name))
     about_action = Gio.SimpleAction.new('about', None)
     about_action.connect('activate', lambda *_: self._show_about_dialog())
     self.add_action(about_action)
     # Bind properties to UI
     bind_property(model, 'error', self.error_buffer, 'text')
     bind_property(model, 'url', self.audio_url_wdg, 'text', bi=True)
     bind_property(model, 'url', self.video_url_wdg, 'text', bi=True)
     for resolution, description in model.resolutions:
         it = self.resolutions_store.append()
         self.resolutions_store.set(it, 0, str(resolution), 1, description)
     bind_property(model,
                   'resolution',
                   self.resolution_wdg,
                   'active-id',
                   str,
                   int,
                   bi=True)
     bind_property(model,
                   'state',
                   self.main_stack_wdg,
                   'visible-child-name',
                   func_a_to_b=lambda s: {'cancel': 'download'}.get(s, s))
     bind_property(model, 'state', func_a_to_b=self._update_notification)
     bind_property(model,
                   'mode',
                   self.audio_video_stack_wdg,
                   'visible-child-name',
                   bi=True)
     bind_property(self.main_stack_wdg,
                   'visible-child-name',
                   func_a_to_b=self._update_focus_and_default)
     bind_property(self.audio_video_stack_wdg,
                   'visible-child-name',
                   func_a_to_b=self._update_focus_and_default)
     bind_property(model,
                   'download-dir-abs',
                   func_a_to_b=self._update_open_download_dir_wdg_tooltip)
     for name in [
             'download-bytes', 'download-bytes-total', 'download-speed',
             'download-eta'
     ]:
         bind_property(model, name, func_a_to_b=self._update_download_msg)
     bind_property(model,
                   'download-progress',
                   func_a_to_b=self._update_download_progress)
     model.connect('download-pulse', self._update_download_progress)
     for name in ['download-playlist-count', 'download-playlist-index']:
         bind_property(model,
                       name,
                       func_a_to_b=self._update_download_page_title)
     bind_property(model,
                   'download-title',
                   self.download_title_wdg,
                   'label',
                   func_a_to_b=lambda title: title or '…')
     bind_property(model,
                   'download-thumbnail',
                   func_a_to_b=self._add_thumbnail)
     bind_property(self.download_images_wdg,
                   'transition-running',
                   func_a_to_b=lambda b: b or self._clean_thumbnails())
     bind_property(Gtk.Settings.get_default(),
                   'gtk-application-prefer-dark-theme',
                   self.dark_mode_wdg,
                   'active',
                   bi=True)
Ejemplo n.º 7
0
class Application(Gtk.Application, Handler):
    def __init__(self, version):
        super().__init__(application_id='com.github.unrud.VideoDownloader',
                         flags=Gio.ApplicationFlags.NON_UNIQUE)
        self.add_main_option('url', ord('u'),
                             GLib.OptionFlags.NONE, GLib.OptionArg.STRING,
                             N_('Prefill URL field'), 'URL')
        GLib.set_application_name(N_('Video Downloader'))
        self.version = version
        self.model = Model(self)
        self._settings = Gio.Settings.new(self.props.application_id)
        self.model.download_dir = self._settings.get_string('download-folder')
        self.model.prefer_mpeg = self._settings.get_boolean('prefer-mpeg')
        self._settings.bind('mode', self.model, 'mode',
                            (Gio.SettingsBindFlags.DEFAULT
                             | Gio.SettingsBindFlags.GET_NO_CHANGES))
        r = self._settings.get_uint('resolution')
        for resolution in sorted(x[0] for x in self.model.resolutions):
            if r <= resolution:
                break
        self.model.resolution = resolution
        self._settings.bind('resolution', self.model, 'resolution',
                            Gio.SettingsBindFlags.SET)
        self._settings.bind('dark-mode', Gtk.Settings.get_default(),
                            'gtk-application-prefer-dark-theme',
                            Gio.SettingsBindFlags.DEFAULT)

    def do_startup(self):
        Gtk.Application.do_startup(self)
        Handy.init()

    def do_activate(self):
        for name in self.model.actions.list_actions():
            self.add_action(self.model.actions.lookup_action(name))
        about_action = Gio.SimpleAction.new('about', None)
        about_action.connect('activate', lambda *_: self._show_about_dialog())
        self.add_action(about_action)

        # Setup the CSS and load it.
        css_uri = 'resource:///com/github/unrud/VideoDownloader/style.css'
        css_provider = Gtk.CssProvider()
        css_provider.load_from_file(Gio.File.new_for_uri(css_uri))
        Gtk.StyleContext.add_provider_for_screen(
            Gdk.Screen.get_default(), css_provider,
            Gtk.STYLE_PROVIDER_PRIORITY_USER)

        win = self.props.active_window
        if not win:
            win = Window(application=self)
            win.set_default_icon_name(self.props.application_id)
        win.present()

    def do_shutdown(self):
        self.model.shutdown()
        Gtk.Application.do_shutdown(self)

    def do_handle_local_options(self, options):
        url_variant = options.lookup_value('url', GLib.VariantType('s'))
        if url_variant:
            self.model.url = url_variant.get_string()
        return -1

    def on_playlist_request(self):
        dialog = PlaylistDialog(self.props.active_window)
        res = dialog.run()
        dialog.destroy()
        return res == Gtk.ResponseType.YES

    def on_login_request(self):
        dialog = LoginDialog(self.props.active_window)
        res = dialog.run()
        dialog.destroy()
        if res == Gtk.ResponseType.OK:
            return (dialog.username, dialog.password)
        self.lookup_action('cancel').activate()
        return ('', '')

    def on_videopassword_request(self) -> str:
        dialog = PasswordDialog(self.props.active_window)
        res = dialog.run()
        dialog.destroy()
        if res == Gtk.ResponseType.OK:
            return dialog.password
        self.lookup_action('cancel').activate()
        return ''

    def _show_about_dialog(self):
        dialog = AboutDialog(self.props.active_window, self.version)
        dialog.run()
        dialog.destroy()
Ejemplo n.º 8
0
class App(BaseWindowMixin, tk.Tk, Handler):
    def __init__(self):
        tk.Tk.__init__(self)
        # BUG: Fonts don't work, when they are not created here.
        f1 = tk.font.Font(self)
        f2 = tk.font.Font(self)
        icon = Image.open(os.path.join(pkgdatadir, "icon.png"))
        icon = ImageTk.PhotoImage(icon)
        self.wm_iconphoto(True, icon)
        BaseWindowMixin.__init__(self, Platform(self, [f1, f2]))
        self.active_page = None
        self.minsize(round(self.winfo_fpixels("480p")),
                     round(self.winfo_fpixels("180p")))
        self.title(g_("Video Downloader"))
        self.model = Model(self, self)
        self.protocol("WM_DELETE_WINDOW", self.quit)
        self.create_widgets()

    def quit(self):
        with contextlib.suppress(AssertionError):
            self.model.cancel()
        super().quit()

    def focus_set(self):
        self.pages[self.active_page].focus_set()

    def create_widgets(self):
        self.bind_class("TEntry", "<<ContextMenu>>", self.show_context_menu)
        # HACK: Fix select all
        self.bind_class(
            "TEntry", "<<SelectAll>>", lambda event:
            (self.after_idle(event.widget.select_range, 0, tk.END)))
        self.bind_class(
            "TEntry", "<<SelectAll>>", lambda event:
            (self.after_idle(event.widget.select_range, 0, tk.END)))
        self.bind_class(
            "TEntry", "<Control-Key-a>", lambda event:
            (event.widget.event_generate("<<SelectAll>>")))
        self.bind_class(
            "TEntry", "<Control-Key-A>", lambda event:
            (event.widget.event_generate("<<SelectAll>>")))
        self.main_frame = MainFrame(self)
        self.download_frame = DownloadFrame(self)
        self.error_frame = ErrorFrame(self)
        self.success_frame = SuccessFrame(self)
        self.model.page.trace("w", self.on_page_changed)
        self.pages = {
            "main": self.main_frame,
            "download": self.download_frame,
            "error": self.error_frame,
            "success": self.success_frame
        }
        self.on_page_changed()

    def on_playlist_request(self):
        result = PlaylistDialog(self).wait()
        if result is None:
            self.model.cancel()
            return False
        return result

    def on_login_request(self):
        result = LoginDialog(self).wait()
        if result is None:
            self.model.cancel()
            return ("", "")
        return result

    def on_videopassword_request(self):
        result = VideopasswordDialog(self).wait()
        if result is None:
            self.model.cancel()
            return ""
        return result

    def on_page_changed(self, *_):
        if self.active_page == self.model.page.get():
            return
        self.active_page = self.model.page.get()
        for frame in self.pages.values():
            frame.pack_forget()
        self.pages[self.active_page].pack(expand=1, fill=tk.BOTH)
        self.focus_set()

    def show_context_menu(self, event):
        menu = tk.Menu(self, tearoff=0)
        menu.add_command(label=g_("Cut"))
        menu.add_command(label=g_("Copy"))
        menu.add_command(label=g_("Paste"))
        widget = event.widget
        select = widget.select_present()
        menu.entryconfig(0,
                         state=tk.NORMAL if select else tk.DISABLED,
                         command=lambda: widget.event_generate("<<Cut>>"))
        menu.entryconfig(1,
                         state=tk.NORMAL if select else tk.DISABLED,
                         command=lambda: widget.event_generate("<<Copy>>"))
        menu.entryconfig(2, command=lambda: widget.event_generate("<<Paste>>"))
        self.tk.call("tk_popup", menu, event.x_root, event.y_root)