def Get(self, interface, property_name): if property_name in ["CanQuit", "CanRaise", "CanSeek", "CanControl", "HasRatingsExtension"]: return GLib.Variant("b", True) elif property_name == "HasTrackList": return GLib.Variant("b", False) elif property_name == "Identity": return GLib.Variant("s", "Cozy") elif property_name == "DesktopEntry": return GLib.Variant("s", "com.github.geigi.cozy") elif property_name == "SupportedUriSchemes": return GLib.Variant("as", ["file"]) elif property_name == "SupportedMimeTypes": return GLib.Variant("as", ["application/ogg", "audio/x-vorbis+ogg", "audio/x-flac", "audio/mpeg"]) elif property_name == "PlaybackStatus": return GLib.Variant("s", self.__get_status()) elif property_name == "Metadata": return GLib.Variant("a{sv}", self.__metadata) elif property_name == "Position": return GLib.Variant( "x", round(self._player.position * 10**-3)) elif property_name in ["CanGoNext", "CanGoPrevious", "CanPlay", "CanPause"]: return GLib.Variant("b", self._player.loaded_book is not None) elif property_name == "Volume": return GLib.Variant("d", self._player.volume) else: reporter.warning("mpris", "MPRIS required an unknown information: {}".format(property_name)) return None
def _on_book_changed(self): if not self._view_model.book: msg = "ViewModel book was None." log.warning(msg) reporter.warning("BookDetailView", msg) return book = self._view_model.book self._current_selected_chapter = None self.published_label.set_visible(False) self.published_text.set_visible(False) self.book_label.set_text(book.name) self.author_label.set_text(book.author) self.last_played_label.set_text(self._view_model.last_played_text) self.total_label.set_text(self._view_model.total_text) self._set_cover_image(book) self._display_chapters(book) self._on_current_chapter_changed() self._display_external_section() self._set_book_download_status() self._set_progress() self._on_play_changed() self._on_book_available_changed() self._main_stack.set_visible_child_name("book_overview") self._toolbar_revealer.set_reveal_child(False)
def jump_to_ns(ns): """ Jumps to the given ns. Caps at 0 and the file length :param ns: time in ns """ global __player global __speed new_position = ns if ns < 0: new_position = 0 elif int(ns / 1000000000) > get_current_track().length: new_position = int(get_current_track().length) * 1000000000 counter = 0 seeked = False while not seeked and counter < 100: counter += 1 time.sleep(0.01) seeked = __player.seek(__speed, Gst.Format.TIME, Gst.SeekFlags.FLUSH, Gst.SeekType.SET, new_position, Gst.SeekType.NONE, 0) if not seeked: log.info("Failed to seek, counter expired.") reporter.warning("player", "Failed to seek, counter expired.") save_current_track_position(new_position)
def delete_book_files(self, book: Book): for chapter in book.chapters: try: os.remove(chapter.file) log.info("Deleted file: {}".format(chapter.file)) except Exception as e: log.error("Failed to delete file: {}".format(chapter.file)) log.debug(e) reporter.warning("library_view_model", "Failed to delete a file.")
def last_played_book(self) -> Optional[Book]: try: return self._db_object.last_played_book except peewee.DoesNotExist: log.warning("last_played_book references an non existent object. Setting last_played_book to None.") reporter.warning("settings_model", "last_played_book references an non existent object. Setting last_played_book to None.") self.last_played_book = None return None
def _load_pixbuf_from_db(self, book): pixbuf = None if book and book.cover: try: loader = GdkPixbuf.PixbufLoader.new() loader.write(book.cover) loader.close() pixbuf = loader.get_pixbuf() except Exception as e: reporter.warning("artwork_cache", "Could not get book cover from db.") log.warning("Could not get cover for book " + book.name) log.warning(e) return pixbuf
def __on_gst_message(bus, message: Gst.Message): """ Handle messages from gst. """ global __speed global __set_speed t = message.type if t == Gst.MessageType.BUFFERING: if (message.percentage < 100): __player.set_state(Gst.State.PAUSED) log.info("Buffering…") else: __player.set_state(Gst.State.PLAYING) log.info("Buffering finished.") elif t == Gst.MessageType.EOS: next_track() elif t == Gst.MessageType.ERROR: error, debug_msg = message.parse_error() if error.code == Gst.ResourceError.NOT_FOUND: track = get_current_track() stop() unload() emit_event("stop") log.warning("gst: Resource not found. Stopping player.") reporter.warning("player", "gst: Resource not found. Stopping player.") emit_event("resource-not-found", track) return reporter.error("player", error) log.error(error) log.debug(debug_msg) emit_event("error", error) elif t == Gst.MessageType.STATE_CHANGED: state = get_gst_player_state() if state == Gst.State.PLAYING or state == Gst.State.PAUSED: auto_jump()
def _create_artwork_cache(self, book, pixbuf, size): """ Creates a resized cache version of the given pixbuf and saves it in the cozy cache folder under a unique identifier. :param book: Book which the artwork is from :param pixbuf: Pixbuf to be cached :param size: Size for the cached version :return: Resized pixbuf """ query = ArtworkCacheModel.select().where( ArtworkCacheModel.book == book.id) gen_uuid = "" if query.exists(): gen_uuid = str(query.first().uuid) else: gen_uuid = str(uuid.uuid4()) ArtworkCacheModel.create(book=book.id, uuid=gen_uuid) cache_dir = os.path.join(os.path.join(get_cache_dir(), "artwork"), gen_uuid) if not os.path.exists(cache_dir): os.makedirs(cache_dir) resized_pixbuf = self._resize_pixbuf(pixbuf, size) file_path = os.path.join(cache_dir, str(size) + ".jpg") if not os.path.exists(file_path): try: resized_pixbuf.savev(file_path, "jpeg", ["quality", None], ["95"]) except Exception as e: reporter.warning("artwork_cache", "Failed to save resized cache albumart") log.warning( "Failed to save resized cache albumart for following uuid: " + gen_uuid) log.warning(e) return resized_pixbuf