Example #1
0
 def __ensure_book_object_is_up_to_date(self):
     # Racecondition: Sometimes the "track-changed" event is fired in playback_speed first before titlebar. Then it might happen, that the current_book is None or not uptodate.
     # Only way to fix this is having a global truth that is accessed from everywhere.
     # TODO
     if player.get_current_track() and (
             not self.current_book or player.get_current_track() and
             self.current_book.id != player.get_current_track().book.id):
         self.update_track_ui()
Example #2
0
    def update_ui_time(self, widget):
        """
        Displays the value of the progress slider in the text boxes as time.
        """
        val = int(self.progress_scale.get_value())
        if tools.get_glib_settings().get_boolean("titlebar-remaining-time"):
            label_text = tools.seconds_to_str(val, display_zero_h=True)
        else:
            label_text = tools.seconds_to_str(val)

        self.current_label.set_markup("<tt><b>" + label_text + "</b></tt>")
        track = player.get_current_track()

        if track:
            if tools.get_glib_settings().get_boolean(
                    "titlebar-remaining-time"):
                total = self.progress_scale.get_adjustment().get_upper()
                remaining_secs: int = int((total - val))
                self.remaining_label.set_markup(
                    "<tt><b>-" +
                    tools.seconds_to_str(remaining_secs, display_zero_h=True) +
                    "</b></tt>")
            else:
                remaining_secs: int = int((track.length /
                                           self.ui.speed.get_speed()) - val)
                self.remaining_label.set_markup(
                    "<tt><b>-" + tools.seconds_to_str(
                        remaining_secs, display_zero_h=False) + "</b></tt>")

        if self.ui.book_overview.book and self.current_book.id == self.ui.book_overview.book.id:
            self.ui.book_overview.update_time()
Example #3
0
    def on_close(self, widget, data=None):
        """
        Close and dispose everything that needs to be when window is closed.
        """
        log.info("Closing.")
        self.titlebar.close()
        self.fs_monitor.close()
        if self.sleep_timer.is_running():
            self.sleep_timer.stop()

        # save current position when still playing
        if player.get_gst_player_state() == Gst.State.PLAYING:
            Track.update(position=player.get_current_duration()).where(
                Track.id == player.get_current_track().id).execute()
            player.stop()

        player.dispose()

        close_db()

        report.close()

        log.info("Closing app.")
        self.app.quit()
        log.info("App closed.")
Example #4
0
    def update_ui_time(self, widget):
        """
        Displays the value of the progress slider in the text boxes as time.
        """
        track = player.get_current_track()

        if not track:
            log.debug("update_ui_time: track was None.")
            return

        val = int(self.progress_scale.get_value())
        if self._application_settings.titlebar_remaining_time:
            total = self.progress_scale.get_adjustment().get_upper()
            remaining_secs: int = int((total - val))
            current_text = seconds_to_str(val, total)
            remaining_text = seconds_to_str(remaining_secs, total)
        else:
            remaining_secs = int((track.length / self.ui.speed.get_speed()) -
                                 val)
            remaining_text = seconds_to_str(remaining_secs, track.length)
            current_text = seconds_to_str(val, track.length)

        self.current_label.set_markup("<tt><b>" + current_text + "</b></tt>")
        self.remaining_label.set_markup("<tt><b>-" + remaining_text +
                                        "</b></tt>")

        if self.ui.book_overview.book and self.current_book.id == self.ui.book_overview.book.id:
            self.ui.book_overview.update_time()
Example #5
0
 def __load_last_book(self):
     """
     Loads the last book into the player
     """
     player.load_last_book()
     if player.get_current_track():
         self.titlebar.load_last_book()
Example #6
0
    def _play_chapter(self, book: Book, chapter: Chapter):
        current_track = player.get_current_track()

        book.last_played = int(time.time())
        if current_track and current_track.file == chapter.file:
            player.play_pause(None)
        else:
            player.load_file(chapter._db_object)
            player.play_pause(None, True)
Example #7
0
    def __update_progress_scale_range(self):
        """
        Update the progress scale range including the current playback speed.
        """
        if tools.get_glib_settings().get_boolean("titlebar-remaining-time"):
            total = db.get_book_duration(
                self.current_book) / self.ui.speed.get_speed()
        else:
            total = player.get_current_track().length / self.ui.speed.get_speed()

        self.progress_scale.set_range(0, total)
Example #8
0
 def set_title_cover(self, pixbuf, size):
     """
     Sets the cover in the title bar.
     """
     if pixbuf:
         surface = Gdk.cairo_surface_create_from_pixbuf(pixbuf, self.ui.window.get_scale_factor(), None)
         self.cover_img.set_from_surface(surface)
         self.cover_img.set_tooltip_text(player.get_current_track().book.name)
     else:
         self.cover_img.set_from_icon_name("book-open-variant-symbolic", Gtk.IconSize.MENU)
         self.cover_img.props.pixel_size = size
Example #9
0
    def loaded_chapter(self) -> Optional[Chapter]:
        current_track = player.get_current_track()
        if not current_track:
            return None

        chapter = None

        for c in self._library.chapters:
            if c.id == current_track.id:
                chapter = c

        return chapter
Example #10
0
    def __init_components(self):
        self.titlebar = Titlebar()

        self.sleep_timer = SleepTimer()
        self.speed = PlaybackSpeed()
        player.init()

        self.titlebar.activate()

        if player.get_current_track() is None:
            self.block_ui_buttons(True)

        self._importer.add_listener(self._on_importer_event)
Example #11
0
    def loaded_book(self) -> Optional[Book]:
        current_track = player.get_current_track()
        if not current_track:
            return None

        track_id = current_track.id
        book = None

        for b in self._library.books:
            if any(chapter.id == track_id for chapter in b.chapters):
                book = b
                break

        return book
Example #12
0
    def track_changed(self):
        """
        The track loaded in the player has changed.
        Refresh the currently playing track and mark it in the track overview popover.
        """
        # also reset the book playing state
        if self.current_book_element:
            self.current_book_element.set_playing(False)

        curr_track = player.get_current_track()
        self.current_book_element = next(
            filter(lambda x: x.book.id == curr_track.book.id,
                   self.book_box.get_children()), None)

        self.block_ui_buttons(False, True)
Example #13
0
    def __init_components(self):
        self.titlebar = Titlebar()

        self.sleep_timer = SleepTimer()
        self.speed = PlaybackSpeed()
        self.settings = Settings()
        self.book_overview = BookOverview()
        self.fs_monitor = fs_monitor.FilesystemMonitor()
        self.offline_cache = offline_cache.OfflineCache()
        player.init()

        self.titlebar.activate()

        if player.get_current_track() is None:
            self.block_ui_buttons(True)
Example #14
0
    def __update_progress_scale_range(self):
        """
        Update the progress scale range including the current playback speed.
        """
        current_track = player.get_current_track()

        if not current_track or not self.current_book:
            return

        if self._application_settings.titlebar_remaining_time:
            total = get_book_duration(
                self.current_book) / self.ui.speed.get_speed()
        else:
            total = current_track.length / self.ui.speed.get_speed()

        self.progress_scale.set_range(0, total)
Example #15
0
 def __player_changed(self, event, message):
     """
     Listen to and handle all gst player messages that are important for the ui.
     """
     if event == "stop":
         if self.__inhibit_cookie:
             self.app.uninhibit(self.__inhibit_cookie)
         self.is_playing = False
         self.stop()
         self.titlebar.stop()
         self.sleep_timer.stop()
     elif event == "play":
         self.is_playing = True
         self.play()
         self.titlebar.play()
         self.sleep_timer.start()
         self.book_overview.select_track(None, True)
         self.refresh_recent()
         self.__inhibit_cookie = self.app.inhibit(
             self.window, Gtk.ApplicationInhibitFlags.SUSPEND, "Playback of audiobook")
     elif event == "pause":
         if self.__inhibit_cookie:
             self.app.uninhibit(self.__inhibit_cookie)
         self.is_playing = False
         self.pause()
         self.titlebar.pause()
         self.sleep_timer.stop()
         self.book_overview.select_track(None, False)
     elif event == "track-changed":
         self.track_changed()
         if self.sort_stack.props.visible_child_name == "recent":
             self.book_box.invalidate_filter()
             self.book_box.invalidate_sort()
     elif event == "error":
         if self.dialog_open:
             return
         if "Resource not found" in str(message):
             current_track = player.get_current_track()
             if db.is_external(current_track.book):
                 player.stop()
                 player.unload()
                 player.emit_event("stop")
             else:
                 self.dialog_open = True
                 dialog = FileNotFoundDialog(
                     current_track.file)
                 dialog.show()
Example #16
0
    def __on_button_press(self, eventbox, event):
        """
        Play the selected track.
        """
        current_track = player.get_current_track()

        if current_track and current_track.id == self.track.id:
            player.play_pause(None)
            if player.get_gst_player_state() == Gst.State.PLAYING:
                player.jump_to_ns(Track.select().where(
                    Track.id == self.track.id).get().position)
        else:
            player.load_file(
                Track.select().where(Track.id == self.track.id).get())
            player.play_pause(None, True)
            Book.update(position=self.track).where(
                Book.id == self.track.book.id).execute()
Example #17
0
    def __on_play_clicked(self, event):
        """
        Play button clicked.
        Start/pause playback.
        """
        track = get_track_for_playback(self.book)
        current_track = player.get_current_track()

        if current_track and current_track.book.id == self.book.id:
            player.play_pause(None)
            if player.get_gst_player_state() == Gst.State.PLAYING:
                player.jump_to_ns(track.position)
        else:
            player.load_file(track)
            player.play_pause(None, True)

        return True
Example #18
0
    def load_last_book(self):
        if Settings.get().last_played_book:
            self.update_track_ui()
            self.update_ui_time(self.progress_scale)
            cur_m, cur_s = player.get_current_duration_ui()
            self.__set_progress_scale_value(cur_m * 60 + cur_s)

            pos = int(player.get_current_track().position)
            if tools.get_glib_settings().get_boolean("replay"):
                log.info("Replaying the previous 30 seconds.")
                amount = 30 * 1000000000
                if (pos < amount):
                    pos = 0
                else:
                    pos = pos - amount
            self.__set_progress_scale_value(
                int(pos / 1000000000 / self.ui.speed.get_speed()))
Example #19
0
 def switch_to_playing(self):
     """
     Switch the UI state back to playing.
     This enables all UI functionality for the user.
     """
     self.titlebar.switch_to_playing()
     if self.main_stack.props.visible_child_name != "book_overview" and self.main_stack.props.visible_child_name != "nothing_here" and self.main_stack.props.visible_child_name != "no_media":
         self.main_stack.props.visible_child_name = "main"
     if self.main_stack.props.visible_child_name != "no_media" and self.main_stack.props.visible_child_name != "book_overview":
         self.category_toolbar.set_visible(True)
     if player.get_current_track():
         self.block_ui_buttons(False, True)
     else:
         # we want to only block the player controls
         self.block_ui_buttons(False, True)
         self.block_ui_buttons(True, False)
     self.window.props.window.set_cursor(None)
Example #20
0
    def get_playback_start_position(self):
        """
        Returns the position where to start playback of the current track.
        This checks for the automatic replay option.
        :return: Position in ns
        """
        pos = player.get_current_track().position
        if self.first_play:
            self.first_play = False

            if tools.get_glib_settings().get_boolean("replay"):
                amount = 30 * 1000000000
                if pos < amount:
                    pos = 0
                else:
                    pos = pos - amount

        return pos
Example #21
0
    def _on_play_button_press(self, widget, event):
        """
        Play this book.
        """
        if event.type == Gdk.EventType.BUTTON_PRESS and event.button != 1:
            return

        track = db.get_track_for_playback(self.book)
        current_track = player.get_current_track()

        if current_track and current_track.book.id == self.book.id:
            player.play_pause(None)
            if player.get_gst_player_state() == Gst.State.PLAYING:
                player.jump_to_ns(track.position)
        else:
            player.load_file(track)
            player.play_pause(None, True)

        return True
Example #22
0
    def __player_changed(self, event, message):
        """
        React to player changes.
        """
        if self.book is None or self.ui.titlebar.current_book is None or self.ui.titlebar.current_book.id != self.book.id:
            return

        if event == "play":
            self.play_book_button.set_image(self.pause_img)
            self.current_track_element.set_playing(True)
            self.last_played_label.set_text(
                tools.past_date_to_human_readable(message.book.last_played))
        elif event == "pause":
            self.play_book_button.set_image(self.play_img)
            self.current_track_element.set_playing(False)
        elif event == "stop":
            self._mark_current_track()
        elif event == "track-changed":
            track = player.get_current_track()
            self._set_active_track(track, player.is_playing())
Example #23
0
    def __on_progress_clicked(self, widget, sender):
        """
        Jump to the slided time and release the progress scale update lock.
        """
        value = self.progress_scale.get_value() * self.ui.speed.get_speed()

        if tools.get_glib_settings().get_boolean("titlebar-remaining-time"):
            track, time = get_track_from_book_time(self.current_book, value)
            if track.id == player.get_current_track().id:
                player.jump_to(time)
            else:
                player.load_file(track)
                player.play_pause(None, True)
                self.__set_progress_scale_value(time /
                                                self.ui.speed.get_speed())
                player.jump_to(time)
        else:
            player.jump_to(value)
        self.progress_scale_clicked = False

        return False
Example #24
0
    def __on_rewind_clicked(self, button):
        """
        """
        seconds = 30 * self.ui.speed.get_speed()
        if self.ui.first_play:
            ns = seconds * 1000000000
            track = player.get_current_track()
            pos = track.position
            if (pos > ns):
                pos -= ns
            else:
                pos = 0
            player.save_current_track_position(pos=pos, track=track)
        else:
            player.rewind(seconds)

        # we want to see the jump imediatly therefore we apply the new time manually
        if self.progress_scale.get_value() > 30:
            self.progress_scale.set_value(self.progress_scale.get_value() - 30)
        else:
            self.progress_scale.set_value(0)
Example #25
0
    def update_track_ui(self):
        # set data of new stream in ui
        track = player.get_current_track()
        if track is None:
            return

        self.title_label.set_text(track.book.name)
        self.subtitle_label.set_text(track.name)
        self.block_ui_buttons(False)
        self.progress_scale.set_sensitive(True)
        self.progress_scale.set_visible(True)

        # only change cover when book has changed
        if self.current_book is not track.book:
            self.current_book = track.book
            if tools.is_elementary():
                size = 28
            else:
                size = 40
            self.set_title_cover(
                artwork_cache.get_cover_pixbuf(
                    track.book, self.ui.window.get_scale_factor(), size), size)

        self.current_remaining = db.get_book_remaining(self.current_book,
                                                       False)
        self.current_elapsed = db.get_book_progress(self.current_book, False)

        self.__update_progress_scale_range()

        if tools.get_glib_settings().get_boolean("titlebar-remaining-time"):
            self.progress_scale.set_value(self.current_elapsed /
                                          self.ui.speed.get_speed())
        else:
            self.progress_scale.set_value(0)
        self.update_ui_time(None)

        self.current_label.set_visible(True)
        self.remaining_label.set_visible(True)
Example #26
0
    def __init_components(self):
        if player.get_current_track() is None:
            self.block_ui_buttons(True)

        self._importer.add_listener(self._on_importer_event)