Exemplo n.º 1
0
 def __init__(self, marshaller):
     # Threads
     self.helperThread = HelperThread(marshaller)
     self.inserterThread = InserterThread(self.helperThread)
     self.inserterThread.message_callback = self.on_inserter_thread_callback
     
     # Gtk
     self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
     self.builder = Gtk.Builder()
     prepare_builder_for_translation(self.builder)
     self.builder.add_from_file(path_with("glade", "mainWindow.glade"))
     self.window = self.builder.get_object("mainWindow")
     self.insertLinksDialog = InsertLinksDialog()
     self.aboutDialog = AboutDialog()
     self.optionsDialog = OptionsDialog()
     self.destination = definitions.OPTIONS.defaultFolder
     self.folderChoose = Gtk.FileChooserDialog(
                             title=_("Choose destination folder"),
                             action=Gtk.FileChooserAction.SELECT_FOLDER,
                             buttons=(Gtk.STOCK_OK, Gtk.ResponseType.OK,
                                      Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL))
     
     #                              DownloadAndEncode, title, state
     self.liststore = self.builder.get_object("videoListStore")
     self.marshaller = marshaller
     self.marshaller.on_video_start_download = lambda x, y: GObject.idle_add(lambda *args: self.refresh_marshaller(), None)
     self.marshaller.on_video_progress = lambda *args: GObject.idle_add(lambda *args: self.refresh_download_progress(), None)
     self.marshaller.on_video_start_encoding = lambda x, y, z: GObject.idle_add(self.on_video_start_encoding, None)
     self.marshaller.on_video_finish = lambda x, y: GObject.idle_add(self.on_video_finish, x, y)
     self.helperThread.start()
     self.inserterThread.start()
     
     self.treeview = self.builder.get_object("videoTreeView")
     cellRendererTitle = Gtk.CellRendererText()
     columnTitle = Gtk.TreeViewColumn(_("Title"), cellRendererTitle, text=1)
     cellRendererState = Gtk.CellRendererText()
     columnState = Gtk.TreeViewColumn(_("State"), cellRendererState, text=2)
     self.treeview.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY)
     self.treeview.connect("drag-data-received", self.onTreeViewDragDataRecieved)
     self.treeview.drag_dest_add_text_targets()
     self.clear_list = self.builder.get_object("clearList")
     self.clear_list.set_sensitive(False)
     self.set_destination = self.builder.get_object("setDestination")
     
     self.treeview.append_column(columnTitle)
     self.treeview.append_column(columnState)
     
     self.popupTreeView = self.builder.get_object("popupTreeView")
     
     self.progressbar = self.builder.get_object("progressbar")
     self.download_progressbar = self.builder.get_object("downloadProgressbar")
     self.download_progressbar.set_show_text(True)
     self.download_progressbar.set_text("")
     self.general_data = self.builder.get_object("generalData")
     self.statusbar = self.builder.get_object("statusbar")
     ctx_id = self.statusbar.get_context_id("inserter")
     self.statusbar.push(ctx_id, _("Ready!"))
     self.itemFeedback = self.builder.get_object("imagemenuitemFeedback")
     
     self.refresh_marshaller()
     self.reset_destination()
     self.reset_data_label()
     
     self.builder.connect_signals(self)
     
     # LibNotify
     if not definitions.WINDOWS:
         self.notification = Notify.Notification.new("Bat-man", "",
                                                     path_with("glade", "batman-logo.png"))
Exemplo n.º 2
0
class MainWindow(object):
    def __init__(self, marshaller):
        # Threads
        self.helperThread = HelperThread(marshaller)
        self.inserterThread = InserterThread(self.helperThread)
        self.inserterThread.message_callback = self.on_inserter_thread_callback
        
        # Gtk
        self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
        self.builder = Gtk.Builder()
        prepare_builder_for_translation(self.builder)
        self.builder.add_from_file(path_with("glade", "mainWindow.glade"))
        self.window = self.builder.get_object("mainWindow")
        self.insertLinksDialog = InsertLinksDialog()
        self.aboutDialog = AboutDialog()
        self.optionsDialog = OptionsDialog()
        self.destination = definitions.OPTIONS.defaultFolder
        self.folderChoose = Gtk.FileChooserDialog(
                                title=_("Choose destination folder"),
                                action=Gtk.FileChooserAction.SELECT_FOLDER,
                                buttons=(Gtk.STOCK_OK, Gtk.ResponseType.OK,
                                         Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL))
        
        #                              DownloadAndEncode, title, state
        self.liststore = self.builder.get_object("videoListStore")
        self.marshaller = marshaller
        self.marshaller.on_video_start_download = lambda x, y: GObject.idle_add(lambda *args: self.refresh_marshaller(), None)
        self.marshaller.on_video_progress = lambda *args: GObject.idle_add(lambda *args: self.refresh_download_progress(), None)
        self.marshaller.on_video_start_encoding = lambda x, y, z: GObject.idle_add(self.on_video_start_encoding, None)
        self.marshaller.on_video_finish = lambda x, y: GObject.idle_add(self.on_video_finish, x, y)
        self.helperThread.start()
        self.inserterThread.start()
        
        self.treeview = self.builder.get_object("videoTreeView")
        cellRendererTitle = Gtk.CellRendererText()
        columnTitle = Gtk.TreeViewColumn(_("Title"), cellRendererTitle, text=1)
        cellRendererState = Gtk.CellRendererText()
        columnState = Gtk.TreeViewColumn(_("State"), cellRendererState, text=2)
        self.treeview.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.COPY)
        self.treeview.connect("drag-data-received", self.onTreeViewDragDataRecieved)
        self.treeview.drag_dest_add_text_targets()
        self.clear_list = self.builder.get_object("clearList")
        self.clear_list.set_sensitive(False)
        self.set_destination = self.builder.get_object("setDestination")
        
        self.treeview.append_column(columnTitle)
        self.treeview.append_column(columnState)
        
        self.popupTreeView = self.builder.get_object("popupTreeView")
        
        self.progressbar = self.builder.get_object("progressbar")
        self.download_progressbar = self.builder.get_object("downloadProgressbar")
        self.download_progressbar.set_show_text(True)
        self.download_progressbar.set_text("")
        self.general_data = self.builder.get_object("generalData")
        self.statusbar = self.builder.get_object("statusbar")
        ctx_id = self.statusbar.get_context_id("inserter")
        self.statusbar.push(ctx_id, _("Ready!"))
        self.itemFeedback = self.builder.get_object("imagemenuitemFeedback")
        
        self.refresh_marshaller()
        self.reset_destination()
        self.reset_data_label()
        
        self.builder.connect_signals(self)
        
        # LibNotify
        if not definitions.WINDOWS:
            self.notification = Notify.Notification.new("Bat-man", "",
                                                        path_with("glade", "batman-logo.png"))
    
    def on_inserter_thread_callback(self, inserter, element):
        # BUGFIX?
        return
        # Inserter has a new message! Let's hear it...
        size = len(self.inserterThread.queue)
        # WTF?
        ctx_id = self.statusbar.get_context_id("inserter")
        
        # Updating statusbar...
        if element == None and size > 0:
            self.statusbar.push(ctx_id, _("Adding videos... ({}/{})").format(0, size))
        elif element == None and size == 0:
            self.statusbar.push(ctx_id, _("Ready!"))
        else:
            i = self.inserterThread.queue.index(element)        
            self.statusbar.push(ctx_id, _("Adding videos... ({}/{})").format(i, size))
        
        # Updating data label
        self.reset_data_label()
    
    def on_video_start_encoding(self, *args):
        logging.info("on_video_start_encoding called")
        self.refresh_marshaller()
        self.refresh_download_progress()
    
    def on_video_finish(self, marshaller, video):
        logging.info("on_video_finish called")
        self.refresh_marshaller()
        self.refresh_download_progress()
        self.reset_data_label()
        if not definitions.WINDOWS:
            finished = len(self.marshaller.finished)
            total = len(self.marshaller.all)
            string = _("\"{}\" finished. ({}/{})").format(video.video.title, finished, total)             
            self.notification.update("Bat-man", string, path_with("glade", "batman-logo.png"))
            self.notification.show()

    def reset_data_label(self):
        self.general_data.set_text(_("- {} video(s)\n"\
        "- Destination: {}").format(len(self.marshaller.all), self.destination))
    
    def reset_destination(self):
        for i in self.marshaller.all:
            i.set_outfolder(self.destination)
    
    def refresh_marshaller(self):
        progress = 0
        size = len(self.marshaller.all)
        self.liststore.clear()
        for video in self.marshaller.all:
            state = self.marshaller.find_state_of_video(video)
            if state == bd.DownloadAndEncodeMarshaller.NON_EXISTANT:
                progress += 0
                self.liststore.append([video, video.video.title, _("Non existant")])
            elif state == bd.DownloadAndEncodeMarshaller.PENDING:
                progress += 0
                self.liststore.append([video, video.video.title, _("Pending")])
            elif state == bd.DownloadAndEncodeMarshaller.DOWNLOADING:
                progress += 1/3/size
                self.liststore.append([video, video.video.title, _("Downloading")])
            elif state == bd.DownloadAndEncodeMarshaller.ENCODING:
                progress += 2/3/size
                self.liststore.append([video, video.video.title, _("Encoding")])
            elif state == bd.DownloadAndEncodeMarshaller.FINISHED:
                progress += 1/size
                self.liststore.append([video, video.video.title, _("Finished")])
            elif state == bd.DownloadAndEncodeMarshaller.NOT_FOUND:
                progress += 0
                self.liststore.append([video, video.video.title, _("Not found")])
        self.progressbar.set_fraction(progress)
        
        # Should we be able to activate clear list?
        if len(self.marshaller.finished) > 0:
            self.clear_list.set_sensitive(True)
    
    def refresh_download_progress(self):
        size = len(self.marshaller.downloading)
        progress = 0.0
        speed = 0
        for video in self.marshaller.downloading:
            # May happen it be None, there is a small-to-medium gap between the
            # start of the download function(where it is set as downloading by
            # the marshaller) and the current downloading.
            if video.download_progress != None:
                progress += video.download_progress[2]/size
                speed += video.download_progress[3]
        self.download_progressbar.set_fraction(progress)
        if size != 0:
            self.download_progressbar.set_text("{:.2%} @ {:.0f} KBps".format(progress, speed/size))
        else:
            self.download_progressbar.set_text("")
    
    def onItemInsertActivate(self, *args):
        links = self.insertLinksDialog.add_new_links()
        self.insertLinksDialog.hide()
        if links != None:
            for l in links:
                if l.strip() != "":
                    self.inserterThread.add_video_to_download(l,
                                                          self.destination,
                                                          definitions.OPTIONS.quality,
                                                          definitions.OPTIONS.VBRquality)
            self.refresh_marshaller()
            self.reset_data_label()
    
    def onCloseCalled(self, *args):
        Gtk.main_quit()
        self.inserterThread.quit()
        self.helperThread.quit()
#        self.inserterThread.join()
#        self.helperThread.join() #Helper thread won't be joined. Sorry, die now.
#        del self.inserterThread
#        del self.helperThread
#        del self.marshaller
        sys.exit(0)
        # Kill thread? Need to see this. Or sys.exit
    
    def onItemAboutActivate(self, *args):
        self.aboutDialog.dialog.run()
        self.aboutDialog.dialog.hide()
    
    def onItemFeedbackActivate(self, *args):
        feedback.open_email_sender_for_feedback()
    
    def onItemOptionsActivate(self, *args):
        self.optionsDialog.dialog.run()
        self.optionsDialog.dialog.hide()
        # Reloading codecs if they are changed - reload on batch_downloader
        self.marshaller.reload_codecs()
            
    def onSetDestinationClicked(self, *args):
        response = self.folderChoose.run()
        self.folderChoose.hide()
        if response == Gtk.ResponseType.OK:
            self.destination = self.folderChoose.get_filename()
            definitions.OPTIONS.defaultFolder = self.destination
            definitions.OPTIONS.write()
            self.reset_destination()
            self.reset_data_label()
    
    def onClearListClicked(self, *args):
        for video in self.marshaller.finished:
            try:
                self.marshaller.finished.remove(video)
                self.marshaller.all.remove(video)
            except Exception as e:
                logging.debug(e.strerror)
        
        self.refresh_marshaller()
        self.reset_data_label()
        # Dumb logic - if we cleared the list already, the list can't be cleared.
        # At least this is what I think.
        self.clear_list.set_sensitive(False)
    
    def onTreeViewClicked(self, widget, event):
        # 3 == right click
        if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3:
            self.popupTreeView.popup(None, None, None, None, event.button, event.time)
    
    def onTreeViewPaste(self, *args):
        content = self.clipboard.wait_for_text()
        
        if content != None:
            for line in content.split("\n"):
                self.inserterThread.add_video_to_download(line, self.destination,
                                                          definitions.OPTIONS.quality,
                                                          definitions.OPTIONS.VBRquality)
            self.refresh_marshaller()
            self.reset_data_label()
    
    def onTreeViewDragDataRecieved(self, widget, drag_context, x, y, data, info, time):
        links = data.get_text().split("\n")
        for line in links:
            self.inserterThread.add_video_to_download(line, self.destination,
                                                      definitions.OPTIONS.quality,
                                                      definitions.OPTIONS.VBRquality)
        self.refresh_marshaller()
        self.reset_data_label()