Beispiel #1
0
 def __on_storage_changed(self, event, message):
     """
     """
     if (event == "storage-online" and not super().get_sensitive()
         ) or event == "external-storage-removed":
         if message in get_tracks(self.book).first().file:
             super().set_sensitive(True)
             self.box.set_tooltip_text(self.ONLINE_TOOLTIP_TEXT)
     elif (event == "storage-offline" and super().get_sensitive()):
         self.refresh_book_object()
         if message in get_tracks(
                 self.book).first().file and not self.book.offline:
             super().set_sensitive(False)
             self.box.set_tooltip_text(self.OFFLINE_TOOLTIP_TEXT)
     elif event == "external-storage-added":
         self.refresh_book_object()
         if FilesystemMonitor().is_book_online(self.book):
             super().set_sensitive(True)
         else:
             super().set_sensitive(False)
             self.box.set_tooltip_text(self.OFFLINE_TOOLTIP_TEXT)
     if event == "external-storage-removed":
         first_track = get_tracks(self.book).first()
         if first_track and message in first_track.file:
             self.box.set_tooltip_text(self.ONLINE_TOOLTIP_TEXT)
Beispiel #2
0
    def remove(self, book):
        """
        Remove all tracks of the given book from the cache.
        """
        #self._stop_processing()
        tracks = get_tracks(book)
        ids = [t.id for t in tracks]
        offline_elements = OfflineCacheModel.select().where(
            OfflineCacheModel.track << ids)

        for element in offline_elements:
            file_path = os.path.join(self.cache_dir, element.file)
            if file_path == self.cache_dir:
                continue

            file = Gio.File.new_for_path(file_path)
            if file.query_exists():
                file.delete()

            for item in self.queue:
                if self.current and item.id == self.current.id:
                    self.filecopy_cancel.cancel()

        OfflineCacheModel.delete().where(
            OfflineCacheModel.track in ids).execute()

        if len(self.queue) > 0:
            self._start_processing()
Beispiel #3
0
 def is_book_online(self, book):
     """
     """
     result = next(
         (storage.online for storage in self.external_storage
          if storage.storage.path in get_tracks(book).first().file), True)
     return (result)
Beispiel #4
0
 def __jump_to_folder(self, widget, parameter):
     """
     Opens the folder containing this books files in the default file explorer.
     """
     track = get_tracks(self.book).first()
     path = os.path.dirname(track.file)
     subprocess.Popen(['xdg-open', path])
Beispiel #5
0
def prev_track():
    """
    Play the previous track of the current book.
    Plays the same track again when it is the first of the book.
    """
    global __player
    global __current_track
    album_tracks = get_tracks(get_current_track().book)
    current = get_current_track()
    index = list(album_tracks).index(current)
    previous = None
    if index > -1:
        previous = album_tracks[index - 1]

    save_current_track_position()

    if previous:
        play_pause(previous)
        save_current_track_position(track=current, pos=0)
        save_current_book_position(previous)
    else:
        first_track = __current_track
        __player.set_state(Gst.State.NULL)
        __current_track = None
        play_pause(first_track)
        save_current_book_position(current, 0)
Beispiel #6
0
def next_track():
    """
    Play the next track of the current book.
    Stops playback if there isn't any.
    """
    global __current_track
    global __play_next

    album_tracks = get_tracks(get_current_track().book)
    current = get_current_track()
    index = list(album_tracks).index(current)
    next_track = None
    if index + 1 < len(album_tracks):
        next_track = album_tracks[index + 1]

    play_pause(None)
    save_current_track_position(0)

    if next_track:
        save_current_book_position(next_track)
        save_current_track_position(0, next_track)
        if __play_next:
            play_pause(next_track)
        else:
            load_file(next_track)
            __play_next = True
    else:
        stop()
        save_current_book_position(current, -1)
        unload()
        Settings.update(last_played_book=None).execute()
        emit_event("stop")
Beispiel #7
0
    def __settings_changed(self, event, message):
        """
        React to changes in user settings.
        """
        if not self.book:
            return

        if event == "storage-removed" or event == "external-storage-removed":
            if message in get_tracks(self.book).first().file:
                self.download_box.set_visible(False)
                self.download_switch.set_visible(False)
        elif "external-storage-added" or event == "storage-changed" or event == "storage-added":
            self.update_offline_status()
Beispiel #8
0
    def add(self, book):
        """
        Add all tracks of a book to the offline cache and start copying.
        """
        tracks = []
        for track in get_tracks(book):
            file = str(uuid.uuid4())
            tracks.append((track, file))
        chunks = [tracks[x:x + 500] for x in range(0, len(tracks), 500)]
        for chunk in chunks:
            query = OfflineCacheModel.insert_many(chunk, fields=[OfflineCacheModel.track, OfflineCacheModel.file])
            self.total_batch_count += len(chunk)
            query.execute()

        self._start_processing()
Beispiel #9
0
def __load_pixbuf_from_file(book):
    """
    Try to load the artwork from a book from image files.
    :param book: The book to load the artwork from.
    :return: Artwork as pixbuf object.
    """
    pixbuf = None

    directory = os.path.dirname(os.path.normpath(get_tracks(book)[0].file))
    cover_files = []

    try:
        cover_files = [
            f for f in os.listdir(directory) if f.lower().endswith('.png')
            or f.lower().endswith(".jpg") or f.lower().endswith(".gif")
        ]
    except Exception as e:
        log.warning(
            "Could not open audiobook directory and look for cover files.")
        log.warning(e)
    for elem in (x for x in cover_files
                 if os.path.splitext(x.lower())[0] == "cover"):
        # find cover.[jpg,png,gif]
        try:
            pixbuf = GdkPixbuf.Pixbuf.new_from_file(
                os.path.join(directory, elem))
        except Exception as e:
            log.debug(e)
        if pixbuf:
            break
    if pixbuf is None:
        # find other cover file (sort alphabet)
        cover_files.sort(key=str.lower)
        for elem in cover_files:
            try:
                pixbuf = GdkPixbuf.Pixbuf.new_from_file(
                    os.path.join(directory, elem))
            except Exception as e:
                log.debug(e)
            if pixbuf:
                break
    return pixbuf
Beispiel #10
0
    def update_book_download_status(self, book):
        """
        Updates the downloaded status of a book.
        """
        downloaded = True
        tracks = get_tracks(book)
        offline_tracks = OfflineCacheModel.select().where(OfflineCacheModel.track in tracks)

        if offline_tracks.count() < 1:
            downloaded = False
        else:
            for track in offline_tracks:
                if not track.copied:
                    downloaded = False

        Book.update(downloaded=downloaded).where(Book.id == book.id).execute()
        if downloaded:
            self.emit_event("book-offline", book)
        else:
            self.emit_event("book-offline-removed", book)
Beispiel #11
0
    def set_book(self, book):
        """
        Display the given book in the book overview.
        """
        if self.book and self.book.id == book.id:
            self.update_time()
            return
        self.book = Book.get(Book.id == book.id)

        if player.is_playing(
        ) and self.ui.titlebar.current_book and self.book.id == self.ui.titlebar.current_book.id:
            self.play_book_button.set_image(self.pause_img)
        else:
            self.play_book_button.set_image(self.play_img)

        self.name_label.set_text(book.name)
        self.author_label.set_text(book.author)

        self.update_offline_status()

        pixbuf = self._artwork_cache.get_cover_pixbuf(
            book, self.ui.window.get_scale_factor(), 250)
        if pixbuf:
            surface = Gdk.cairo_surface_create_from_pixbuf(
                pixbuf, self.ui.window.get_scale_factor(), None)
            self.cover_img.set_from_surface(surface)
        else:
            self.cover_img.set_from_icon_name("book-open-variant-symbolic",
                                              Gtk.IconSize.DIALOG)
            self.cover_img.props.pixel_size = 250

        self.duration = get_book_duration(book)
        self.speed = self.book.playback_speed
        self.total_label.set_text(
            tools.seconds_to_human_readable(self.duration / self.speed))

        self.last_played_label.set_text(
            tools.past_date_to_human_readable(book.last_played))

        self.published_label.set_visible(False)
        self.published_text.set_visible(False)

        # track list
        # This box contains all track content
        self.track_box = Gtk.Box()
        self.track_box.set_orientation(Gtk.Orientation.VERTICAL)
        self.track_box.set_halign(Gtk.Align.START)
        self.track_box.set_valign(Gtk.Align.START)
        self.track_box.props.margin = 8

        disk_number = -1
        first_disk_element = None
        disk_count = 0

        for track in get_tracks(book):
            # Insert disk headers
            if track.disk != disk_number:
                disc_element = DiskElement(track.disk)
                self.track_box.add(disc_element)
                if disk_number == -1:
                    first_disk_element = disc_element
                    if track.disk < 2:
                        first_disk_element.set_hidden(True)
                else:
                    first_disk_element.show_all()
                    disc_element.show_all()

                disk_number = track.disk
                disk_count += 1

            track_element = TrackElement(track, self)
            self.track_box.add(track_element)
            track_element.show_all()

        self.track_list_container.remove_all_children()
        self.track_box.show()
        self.track_box.set_halign(Gtk.Align.FILL)
        self.track_list_container.add(self.track_box)

        self._mark_current_track()
        self.update_time()