def test_ioerror_load(): # Non existent with pytest.raises(IOError): core.load("filedoesnotexist.txt") # Non file with pytest.raises(IOError): core.load(os.path.abspath(os.path.curdir))
def set_mp3_tags(c, path, dry=False, verbose=False): """ Add title, album, artists tags, set album image, write table of contents to podcast episode mp3 file. The ToC should be readable by Apple Podcasts. """ full_path = _get_episode_mp3_full_path(path) # check that hugo template for new episode page is already exists # so we can parse table of contents from there episode_num = int(re.match(r".*rt_podcast(\d*)\.mp3", path).group(1)) episode_page_path = f"/srv/hugo/content/posts/podcast-{episode_num}.md" if not os.path.exists(episode_page_path): print( "Error:", f'New episode page "{episode_page_path}" does not exists', file=sys.stderr, ) sys.exit(1) # remove both ID3 v1.x and v2.x tags. remove_version = id3.ID3_ANY_VERSION id3.Tag.remove(full_path, remove_version) episode_file = core.load(full_path) # using ID3v2.3 tags, because using newer ID3v2.4 version leads to problems with Apple Podcasts and Telegram # (they will stop showing chapters with long titles at all, see https://github.com/radio-t/radio-t-site/issues/209) episode_file.initTag(version=id3.ID3_V2_3) tag = episode_file.tag try: print("Creating new album meta tags: title, cover, artists, etc...") set_mp3_album_tags(dict(c.tags), tag, episode_num) print( "Parsing episode articles from markdown template for the episode page in `/hugo/content/posts/`..." ) toc = parse_table_of_contents_from_md(episode_page_path, c.toc.first_mp3_chapter_name, c.toc.max_episode_hours) print("Generating table of contents...") set_mp3_table_of_contests(tag, toc) except Exception as exc: print("Error:", str(exc), file=sys.stderr) sys.exit(1) if not dry: tag.save(encoding="utf8") print("New mp3 tags are saved.") if verbose: print("\n") print_album_meta(tag) print_toc(tag)
def get_item_quality(item): preset = None if item.format == u'MP3': audio_file = core.load(item.path) lt = audio_file.info.lame_tag if not audio_file or not audio_file.info.lame_tag: pass elif lt.has_key('preset'): preset = lt['preset'] return {"preset": preset, "bitrate": item.bitrate, "format": item.format}
def print_mp3_tags(c, path): """ Print title, album, artist, ToC and other mp3 tags (relevant for Radio-T) from podcast episode file. """ full_path = _get_episode_mp3_full_path(path) episode_file = core.load(full_path) tag = episode_file.tag if not isinstance(tag, id3.Tag): print("Error: only ID3 tags can be extracted currently.", file=sys.stderr) sys.exit(1) print_album_meta(tag) print_toc(tag)
def main(mp3file, chaptersfile): total_length = int(core.load(mp3file).info.time_secs * 1000) chapters = [] n = 0 tag = Tag() tag.parse(mp3file) for i in open(chaptersfile, 'r').readlines(): chapter_time = to_millisecs(i[0:12]) chapter_title = u'{}'.format(i[13:]).rstrip() chapters.append([[chapter_time, 0], chapter_title, 'ch_' + str(n)]) if n > 0: chapters[n - 1][0][1] = chapter_time n += 1 chapters[n - 1][0][1] = total_length for times, title, id in chapters: chapter_frame = tag.chapters.set(id, tuple(times)) chapter_frame.sub_frames.setTextFrame(b"TIT2", title) tag.table_of_contents.set('toc', child_ids=[e[2] for e in chapters]) show_chapters(tag) tag.save()
def handleFile(self, f, *args, **kwargs): '''Loads ``f`` and sets ``self.audio_file`` to an instance of :class:`eyed3.core.AudioFile` or ``None`` if an error occurred or the file is not a recognized type. The ``*args`` and ``**kwargs`` are passed to :func:`eyed3.core.load`. ''' self.audio_file = None try: self.audio_file = core.load(f, *args, **kwargs) except NotImplementedError as ex: # Frame decryption, for instance... printError(ex) return if self.audio_file: self._num_loaded += 1 if self._file_cache is not None: self._file_cache.append(self.audio_file)
def add_chapters(tag, fname): chaps = parse_chapters_file(fname) audioFile = core.load(fname) total_length = audioFile.info.time_secs * 1000 chaps_ = [] for i, chap in enumerate(chaps): if i < (len(chaps) - 1): chaps_.append(((chap[0], chaps[i + 1][0]), chap[1])) chaps_.append(((chaps[-1][0], total_length), chaps[-1][1])) index = 0 child_ids = [] for chap in chaps_: element_id = "ch{}".format(index) times, title = chap new_chap = tag.chapters.set(element_id, times) new_chap.sub_frames.setTextFrame("TIT2", u"{}".format(title)) child_ids.append(element_id) index += 1 tag.table_of_contents.set("toc", child_ids=child_ids) list_chaps(tag) tag.save()
def handleFile(self, f, *args, **kwargs): '''Loads ``f`` and sets ``self.audio_file`` to an instance of :class:`eyed3.core.AudioFile` or ``None`` if an error occurred. The ``*args`` and ``**kwargs`` are passed to :func:`eyed3.core.load`. ''' self.audio_file = None mtype = utils.guessMimetype(f) if mtype is None or not (mtype.startswith("audio/") or mtype.startswith("application/")): return self._num_loaded += 1 try: self.audio_file = core.load(f, *args, **kwargs) except NotImplementedError as ex: # Frame decryption, for instance... printError(ex) else: if not self.audio_file: printError("Unsupported file type: %s" % f)
def handleFile(self, f, *args, **kwargs): """Loads ``f`` and sets ``self.audio_file`` to an instance of :class:`eyed3.core.AudioFile` or ``None`` if an error occurred or the file is not a recognized type. The ``*args`` and ``**kwargs`` are passed to :func:`eyed3.core.load`. """ try: self.audio_file = core.load(f, *args, **kwargs) except NotImplementedError as ex: # Frame decryption, for instance... printError(str(ex)) return if self.audio_file: self._num_loaded += 1 if self._file_cache is not None: self._file_cache.append(self.audio_file) elif self._dir_images is not None: mt = guessMimetype(f) if mt and mt.startswith("image/"): self._dir_images.append(f)
def add_chapters(fname, chaps): tag = Tag() tag.parse(fname) audioFile = core.load(fname) total_length = audioFile.info.time_secs * 1000 tag.setTextFrame(b"TLEN", str(int(total_length))) for i, chap in enumerate(chaps): if i < (len(chaps) - 1): chap.end = chaps[i + 1].start chaps[-1].end = total_length index = 0 child_ids = [] for chap in chaps: element_id = "ch{}".format(index).encode() print("Adding chapter {} at {}".format(chap.title, chap.start)) new_chap = tag.chapters.set(element_id, (chap.start, chap.end)) new_chap.sub_frames.setTextFrame(b"TIT2", u"{}".format(chap.title)) child_ids.append(element_id) index += 1 tag.table_of_contents.set(b"toc", child_ids=child_ids) list_chaps(tag) tag.save()
def handleFile(self, f, *args, **kwargs): """Loads ``f`` and sets ``self.audio_file`` to an instance of :class:`eyed3.core.AudioFile` or ``None`` if an error occurred or the file is not a recognized type. The ``*args`` and ``**kwargs`` are passed to :func:`eyed3.core.load`. """ self.audio_file = None try: self.audio_file = core.load(f, *args, **kwargs) except NotImplementedError as ex: # Frame decryption, for instance... printError(str(ex)) return if self.audio_file: self._num_loaded += 1 if self._file_cache is not None: self._file_cache.append(self.audio_file) elif self._dir_images is not None: mt = guessMimetype(f) if mt and mt.startswith("image/"): self._dir_images.append(f)
def test_none_load(): # File mimetypes that are not supported return None assert_equal(core.load(__file__), None)
def test_none_load(): # File mimetypes that are not supported return None assert core.load(__file__) == None