def books(): """ Find all books in the database :return: all books """ return Book.select()
def authors(): """ Find all authors in the database :return: all authors """ return Book.select(Book.author).distinct().order_by(Book.author)
def readers(): """ Find all readers in the database :return: all readers """ return Book.select(Book.reader).distinct().order_by(Book.reader)
def update_time(self): if self.book is None: return # update book object # TODO: optimize usage by only asking from the db on track change query = Book.select().where(Book.id == self.book.id) if (query.exists()): self.book = query.get() else: self.book = None return if self.ui.titlebar.current_book and self.book.id == self.ui.titlebar.current_book.id: progress = get_book_progress(self.book, False) progress += (player.get_current_duration() / 1000000000) remaining = (self.duration - progress) else: progress = get_book_progress(self.book) remaining = get_book_remaining(self.book) percentage = progress / self.duration self.total_label.set_text( tools.seconds_to_human_readable(self.duration / self.speed)) if percentage > 0.005: self.remaining_text.set_visible(True) self.remaining_label.set_visible(True) self.remaining_label.set_text( tools.seconds_to_human_readable(remaining / self.speed)) else: self.remaining_text.set_visible(False) self.remaining_label.set_visible(False) self.progress_bar.set_fraction(percentage)
def search_readers(search_string): """ Search all readers in the db with the given substring. This ignores upper/lowercase and returns each reader only once. :param search_string: substring to search for :return: readers matching the substring """ return Book.select(Book.reader).where( Book.reader.contains(search_string)).distinct().order_by(Book.reader)
def search_books(search_string): """ Search all book names in the db with the given substring. This ignores upper/lowercase and returns each book name only once. :param search_string: substring to search for :return: book names matching the substring """ return Book.select(Book.name, Book.cover, Book.id).where( Book.name.contains(search_string) | Book.author.contains(search_string) | Book.reader.contains(search_string)).distinct().order_by(Book.name)
def clean_books(): """ Remove all books that have no tracks """ for book in Book.select(): if not get_track_for_playback(book): Book.update(position=0).where(Book.id == book.id).execute() if Track.select().where(Track.book == book).count() < 1: if Settings.get().last_played_book.id == book.id: Settings.update(last_played_book=None).execute() book.delete_instance()
def jump_to_book(self, book): """ Open book overview with the given book. """ # first update track ui book = Book.select().where(Book.id == book.id).get() self.book_overview.set_book(book) # then switch the stacks self.main_stack.props.visible_child_name = "book_overview" self.toolbar_revealer.set_reveal_child(False) self.search.close()
def __ui_changed(self, event, message): """ Handler for events that occur in the main ui. """ 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 == "playback-speed-changed": self.speed = Book.select().where( Book.id == self.book.id).get().playback_speed if self.ui.main_stack.props.visible_child_name == "book_overview": self.update_time()
def __on_sort_stack_changed(self, widget, page): """ Switch to author selection """ page = self.sort_stack.props.visible_child_name if page == "recent": self.sort_stack_revealer.set_reveal_child(False) if Book.select().where(Book.last_played > 0).count() < 1: self.main_stack.props.visible_child_name = "nothing_here" else: self.sort_stack_revealer.set_reveal_child(True) self.main_stack.props.visible_child_name = "main" self.__on_listbox_changed(None, None)
def get_track_for_playback(book): """ Finds the current track to playback for a given book. :param book: book which the next track is required from :return: current track position from book db """ book = Book.select().where(Book.id == book.id).get() query = Track.select().where(Track.id == book.position) if book.position < 1: track_items = get_tracks(book) if len(track_items) > 0: track = get_tracks(book)[0] else: track = None elif query.exists(): track = query.get() else: track = None return track
def import_file(file, directory, path, update=False): """ Imports all information about a track into the database. Note: This creates also a new album object when it doesnt exist yet. Note: This does not check whether the file is already imported. :return: True if file was imported, otherwise False :return: Track object to be imported when everything passed successfully and track is not in the db already. """ if is_blacklisted(path): return True, None media_type = tools.__get_media_type(path) track = TrackContainer(None, path) cover = None reader = None track_number = None track_data = None # getting the some data is file specific ### MP3 ### if "audio/mpeg" in media_type: track_data = _get_mp3_tags(track, path) ### FLAC ### elif "audio/flac" in media_type or "audio/x-flac" in media_type: track_data = _get_flac_tags(track, path) ### OGG ### elif "audio/ogg" in media_type or "audio/x-ogg" in media_type: track_data = _get_ogg_tags(track, path) ### OPUS ### elif "audio/opus" in media_type or "audio/x-opus" in media_type or "codecs=opus" in media_type: track_data = _get_opus_tags(track, path) ### MP4 ### elif "audio/mp4" in media_type or "audio/x-m4a" in media_type: track_data = _get_mp4_tags(track, path) ### WAV ### elif "audio/wav" in media_type or "audio/x-wav" in media_type: track_data = TrackData(path) track_data.length = __get_wav_track_length(path) ### File will not be imported ### else: # don't use _ for ignored return value -> it is reserved for gettext ignore, file_extension = os.path.splitext(path) log.warning("Skipping file " + path + " because of mime type " + media_type + ".") reporter.error( "importer", "Mime type not detected as audio: " + media_type + " with file ending: " + file_extension) return False, None track_data.modified = __get_last_modified(path) # try to get all the remaining tags try: if track_data.track_number is None: # The track number can contain the total number of tracks track_text = str(__get_common_tag(track, "tracknumber")) track_data.track_number = int(track_text.split("/")[0]) except Exception as e: log.debug(e) track_data.track_number = 0 if track_data.book_name is None: track_data.book_name = __guess_book_name(directory) if track_data.author is None or track_data.author == "": if track_data.reader and len(track_data.reader) > 0: track_data.author = track_data.reader track_data.reader = "" else: track_data.author = _("Unknown Author") if track_data.reader is None or track_data.reader == "": track_data.reader = _("Unknown Reader") if track_data.name is None: track_data.name = __guess_title(file) if not track_data.disk: track_data.disk = 1 if not track_data.length: # Try to get the length by using gstreamer success, track_data.length = get_gstreamer_length(path) if not success: return False, None if update: if Book.select().where(Book.name == track_data.book_name).count() < 1: track_data.book = Book.create(name=track_data.book_name, author=track_data.author, reader=track_data.reader, position=0, rating=-1, cover=track_data.cover) else: track_data.book = Book.select().where( Book.name == track_data.book_name).get() Book.update(name=track_data.book_name, author=track_data.author, reader=track_data.reader, cover=track_data.cover).where( Book.id == track_data.book.id).execute() Track.update(name=track_data.name, number=track_data.track_number, book=track_data.book, disk=track_data.disk, length=track_data.length, modified=track_data.modified).where( Track.file == track_data.file).execute() else: # create database entries if Book.select().where(Book.name == track_data.book_name).count() < 1: track_data.book = Book.create(name=track_data.book_name, author=track_data.author, reader=track_data.reader, position=0, rating=-1, cover=track_data.cover) else: track_data.book = Book.select().where( Book.name == track_data.book_name).get() return True, track_data return True, None
def generate_artwork_cache(): """ Generates the default artwork cache for cover preview. """ for book in Book.select(): get_cover_pixbuf(book, 180)
def get_book(self): """ Get this book element with the newest values from the """ return Book.select().where(Book.id == self.book.id).get()