def testChapters(): test_file = "/tmp/chapters.id3" t = Tag() ch1 = t.chapters.set("c1", (0, 200)) ch2 = t.chapters.set("c2", (200, 300)) ch3 = t.chapters.set("c3", (300, 375)) ch4 = t.chapters.set("c4", (375, 600)) assert_equal(len(t.chapters), 4) for i, c in enumerate(iter(t.chapters), 1): if i != 2: c.title = u"Chapter %d" % i c.subtitle = u"Subtitle %d" % i c.user_url = "http://example.com/%d" % i t.save(test_file) try: t2 = eyed3.load(test_file).tag finally: os.remove(test_file) assert_equal(len(t2.chapters), 4) for i in range(1, 5): c = t2.chapters.get("c%d" % i) if i == 2: assert_is_none(c.title) assert_is_none(c.subtitle) assert_is_none(c.user_url) else: assert_equal(c.title, u"Chapter %d" % i) assert_equal(c.subtitle, u"Subtitle %d" % i) assert_equal(c.user_url, u"http://example.com/%d" % i)
def testChapters(): test_file = "/tmp/chapters.id3" t = Tag() ch1 = t.chapters.set(b"c1", (0, 200)) ch2 = t.chapters.set(b"c2", (200, 300)) ch3 = t.chapters.set(b"c3", (300, 375)) ch4 = t.chapters.set(b"c4", (375, 600)) assert len(t.chapters) == 4 for i, c in enumerate(iter(t.chapters), 1): if i != 2: c.title = "Chapter %d" % i c.subtitle = "Subtitle %d" % i c.user_url = "http://example.com/%d" % i t.save(test_file) try: t2 = eyed3.load(test_file).tag finally: os.remove(test_file) assert len(t2.chapters) == 4 for i in range(1, 5): c = t2.chapters.get(str("c%d" % i).encode("latin1")) if i == 2: assert c.title is None assert c.subtitle is None assert c.user_url is None else: assert c.title == "Chapter %d" % i assert c.subtitle == "Subtitle %d" % i assert c.user_url == "http://example.com/%d" % i
def _write_to_mp3(chapters=List[Chapter], filepath=str): import eyed3 from eyed3.id3 import Tag # write chapters to mp3 metadata tag = Tag() tag.parse(filepath) # remove chapters if already set # tag.table_of_contents.set(b'toc', child_ids=[]) # for every chapter id (i.e. 'ch0' od. 'chp0'), do # tag.chapters.remove(b'chp3') chapterIds = [] for i, chapter in enumerate(chapters): endTime = int(chapter.time * 1000) startTime = 0 if i != 0: startTime = int(chapters[i - 1].time * 1000) chapterId = str.encode('ch' + str(i)) newChapter = tag.chapters.set(chapterId, (startTime, endTime)) newChapter.sub_frames.setTextFrame(b'TIT2', u'{}'.format(chapter.title)) chapterIds.append(chapterId) tag.table_of_contents.set(b"toc", child_ids=chapterIds) tag.save()
def music_naming(path_to_file, music_performer, music_title): logger.info(path_to_file) audiofile = Tag() logger.info(audiofile) audiofile.parse(path_to_file) audiofile.artist = f"{music_performer}" audiofile.title = f"{music_title}" audiofile.save() logger.info( f'New audio attribute: Artist: {audiofile.artist}, Title: {audiofile.title}' )
def add_mp3_tags(path, tags, image, lyrics=None, image_mimetype='image/png'): tag = Tag() tag.parse(path) for key, val in tags.items(): try: setattr(tag, key, val) except Exception as e: print(e) if lyrics: tag.lyrics.set(lyrics) if image: tag.images.set(type_=3, img_data=image, mime_type=image_mimetype) tag.save(encoding='utf-8')
def testReadOnly(): assert not(Tag.read_only) t = Tag() assert not(t.read_only) t.read_only = True with pytest.raises(RuntimeError): t.save() with pytest.raises(RuntimeError): t._saveV1Tag(None) with pytest.raises(RuntimeError): t._saveV2Tag(None, None, None)
def testReadOnly(): assert not (Tag.read_only) t = Tag() assert not (t.read_only) t.read_only = True with pytest.raises(RuntimeError): t.save() with pytest.raises(RuntimeError): t._saveV1Tag(None) with pytest.raises(RuntimeError): t._saveV2Tag(None, None, None)
def test_issue382_genres(audiofile): """Tags always written in v2.3 format, always including ID. https://github.com/nicfit/eyeD3/issues/382 """ tag = Tag() tag.genre = "Dubstep" assert tag.genre.id == 189 assert tag.genre.name == "Dubstep" audiofile.tag = tag tag.save() new_audiofile = eyed3.load(audiofile.path) # Prior versions would be `(189)Dubstep`, now no index. assert new_audiofile.tag.frame_set[b"TCON"][0].text == "Dubstep"
def testTableOfContents(): test_file = "/tmp/toc.id3" t = Tag() assert_equal(len(t.table_of_contents), 0) toc_main = t.table_of_contents.set("main", toplevel=True, child_ids=["c1", "c2", "c3", "c4"], description=u"Table of Conents") assert_is_not_none(toc_main) assert_equal(len(t.table_of_contents), 1) toc_dc = t.table_of_contents.set("director-cut", toplevel=False, ordered=False, child_ids=["d3", "d1", "d2"]) assert_is_not_none(toc_dc) assert_equal(len(t.table_of_contents), 2) toc_dummy = t.table_of_contents.set("test") assert_equal(len(t.table_of_contents), 3) t.table_of_contents.remove(toc_dummy.element_id) assert_equal(len(t.table_of_contents), 2) t.save(test_file) try: t2 = eyed3.load(test_file).tag finally: os.remove(test_file) assert_equal(len(t.table_of_contents), 2) assert_equal(t2.table_of_contents.get("main").toplevel, True) assert_equal(t2.table_of_contents.get("main").ordered, True) assert_equal( t2.table_of_contents.get("main").description, toc_main.description) assert_equal( t2.table_of_contents.get("main").child_ids, toc_main.child_ids) assert_equal( t2.table_of_contents.get("director-cut").toplevel, toc_dc.toplevel) assert_equal(t2.table_of_contents.get("director-cut").ordered, False) assert_equal( t2.table_of_contents.get("director-cut").description, toc_dc.description) assert_equal( t2.table_of_contents.get("director-cut").child_ids, toc_dc.child_ids)
def testTableOfContents(): test_file = "/tmp/toc.id3" t = Tag() assert (len(t.table_of_contents) == 0) toc_main = t.table_of_contents.set(b"main", toplevel=True, child_ids=[b"c1", b"c2", b"c3", b"c4"], description=u"Table of Conents") assert toc_main is not None assert (len(t.table_of_contents) == 1) toc_dc = t.table_of_contents.set(b"director-cut", toplevel=False, ordered=False, child_ids=[b"d3", b"d1", b"d2"]) assert toc_dc is not None assert (len(t.table_of_contents) == 2) toc_dummy = t.table_of_contents.set(b"test") assert (len(t.table_of_contents) == 3) t.table_of_contents.remove(toc_dummy.element_id) assert (len(t.table_of_contents) == 2) t.save(test_file) try: t2 = eyed3.load(test_file).tag finally: os.remove(test_file) assert len(t.table_of_contents) == 2 assert t2.table_of_contents.get(b"main").toplevel assert t2.table_of_contents.get(b"main").ordered assert t2.table_of_contents.get( b"main").description == toc_main.description assert t2.table_of_contents.get(b"main").child_ids == toc_main.child_ids assert ( t2.table_of_contents.get(b"director-cut").toplevel == toc_dc.toplevel) assert not t2.table_of_contents.get(b"director-cut").ordered assert (t2.table_of_contents.get(b"director-cut").description == toc_dc.description) assert (t2.table_of_contents.get(b"director-cut").child_ids == toc_dc.child_ids)
def testTableOfContents(): test_file = "/tmp/toc.id3" t = Tag() assert (len(t.table_of_contents) == 0) toc_main = t.table_of_contents.set(b"main", toplevel=True, child_ids=[b"c1", b"c2", b"c3", b"c4"], description="Table of Conents") assert toc_main is not None assert (len(t.table_of_contents) == 1) toc_dc = t.table_of_contents.set(b"director-cut", toplevel=False, ordered=False, child_ids=[b"d3", b"d1", b"d2"]) assert toc_dc is not None assert (len(t.table_of_contents) == 2) toc_dummy = t.table_of_contents.set(b"test") assert (len(t.table_of_contents) == 3) t.table_of_contents.remove(toc_dummy.element_id) assert (len(t.table_of_contents) == 2) t.save(test_file) try: t2 = eyed3.load(test_file).tag finally: os.remove(test_file) assert len(t.table_of_contents) == 2 assert t2.table_of_contents.get(b"main").toplevel assert t2.table_of_contents.get(b"main").ordered assert t2.table_of_contents.get(b"main").description == toc_main.description assert t2.table_of_contents.get(b"main").child_ids == toc_main.child_ids assert (t2.table_of_contents.get(b"director-cut").toplevel == toc_dc.toplevel) assert not t2.table_of_contents.get(b"director-cut").ordered assert (t2.table_of_contents.get(b"director-cut").description == toc_dc.description) assert (t2.table_of_contents.get(b"director-cut").child_ids == toc_dc.child_ids)
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 download_tracks(tracks, filetype): def to_valid_filename(name): bad_path_characters = '<>:"/\\|?*' name = "".join( [x if not x in bad_path_characters else '_' for x in name]) return name.strip(".") is_first_track = True for track in tracks: (num, title, url, album, artist) = (track["track"], unicode(track["title"]), track["url"], unicode(track["album"]), unicode(track["artist"])) print("%s: %s . . . " % (num, title), end='') path = os.path.join(to_valid_filename(artist), to_valid_filename(album)) if is_first_track: try: os.makedirs(path) except OSError: pass art_url = track["art_url"] art_path = os.path.join(path, "cover.jpg") download(art_url, art_path) is_first_track = False filename = "%s %s.%s" % (padded( num, 1)[-2:], to_valid_filename(title[:40]), filetype) filepath = os.path.join(path, filename) download(url.rstrip(), filepath) t = Tag(title=title, artist=artist, album=album, album_artist=artist, track_num=num) t.save(filepath) print("-> %s" % filepath)
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()
class ID3Tagger(object): def __init__(self, filepath): self.filepath = filepath self.tag = Tag() def parse(self): self.tag.parse(self.filepath) return self def save(self): try: self.tag.save(self.filepath, version=ID3_V2_4, encoding="utf8") except TagException: pass try: self.tag.save(self.filepath, version=ID3_V2_3, encoding="utf8") except TagException: pass # Loss of the release date month and day. # Loss of the comment with description. try: self.tag.save(self.filepath, version=ID3_V1_1, encoding="utf8") except (TagException, UnicodeEncodeError): pass # Loses what v1.1 loses, and the track # try: self.tag.save(self.filepath, version=ID3_V1_0, encoding="utf8") except (TagException, UnicodeEncodeError): pass def __getattr__(self, name): return getattr(self.tag, name) def __setattr__(self, name, value): if name in ['filepath', 'tag']: self.__dict__[name] = value else: setattr(self.tag, name, value)
class Track(object): def __init__(self, library, data): self.__library = library if 'track' in data: # Playlists manage tracks in a different way self.__id = data['trackId'] data = data['track'] elif 'id' in data: self.__id = data['id'] elif 'storeId' in data: self.__id = data['storeId'] else: self.__id = data['nid'] self.__data = data self.__title = data['title'] self.__number = int(data['trackNumber']) self.__year = int(data.get('year', 0)) self.__album = self.__library.albums.get(data['albumId'], None) self.__url = None self.__stream_cache = "" self.__rendered_tag = None self.__tag = None def __gen_tag(self): log.info("Creating tag idv3...") self.__tag = Tag() self.__tag.album = self.__data['album'] self.__tag.artist = self.__data['artist'] if self.__data.has_key('album'): self.__tag.album = self.__data['album'] if self.__data.has_key('artist'): self.__tag.artist = self.__data['artist'] if self.__data.has_key('title'): self.__tag.title = self.__data['title'] if self.__data.has_key('discNumber'): self.__tag.disc_num = int(self.__data['discNumber']) if self.__data.has_key('trackNumber'): self.__tag.track_num = int(self.__data['trackNumber']) if self.__data.has_key('genre'): self.__tag.genre = self.__data['genre'] if self.__data.has_key('albumArtist') and self.__data[ 'albumArtist'] != self.__data['artist']: self.__tag.album_artist = self.__data['albumArtist'] if self.__data.has_key('year') and int(self.__data['year']) != 0: self.__tag.recording_date = self.__data['year'] if self.album and self.album.art: self.__tag.images.set(0x03, self.album.art, 'image/jpeg', u'Front cover') tmpfd, tmpfile = tempfile.mkstemp() os.close(tmpfd) self.__tag.save(tmpfile, ID3_V2_4) tmpfd = open(tmpfile, "r") self.__rendered_tag = tmpfd.read() tmpfd.close() os.unlink(tmpfile) @property def id(self): return self.__id @property def number(self): return self.__number @property def title(self): return self.__title @property def album(self): return self.__album @property def year(self): return self.__year def get_attr(self): st = {} st['st_mode'] = (S_IFREG | 0o444) st['st_nlink'] = 1 st['st_ctime'] = st['st_mtime'] = st['st_atime'] = 0 if 'bytes' in self.__data: st['st_size'] = int(self.__data['bytes']) elif 'estimatedSize' in self.__data: st['st_size'] = int(self.__data['estimatedSize']) else: st['st_size'] = int(self.__data['tagSize']) if 'creationTimestamp' in self.__data: st['st_ctime'] = st['st_mtime'] = int( self.__data['creationTimestamp']) / 1000000 if 'recentTimestamp' in self.__data: st['st_atime'] = int(self.__data['recentTimestamp']) / 1000000 return st def _open(self): pass #self.__url = urllib2.urlopen(self.__library.get_stream_url(self.id)) #self.__stream_cache += self.__url.read(8192) # Some caching def read(self, offset, size): if not self.__tag: # Crating tag only when needed self.__gen_tag() self.__stream_cache = str(self.__rendered_tag or "") if offset == 0 and not self.__url: self.__url = urllib2.urlopen(self.__library.get_stream_url( self.id)) if not self.__url: return '' self.__stream_cache += self.__url.read(offset + size - len(self.__stream_cache)) return self.__stream_cache[offset:offset + size] def close(self): pass #if self.__url: # log.info("killing url") # self.__stream_cache = str(self.__rendered_tag or "") # self.__url.close() # self.__url = None def __str__(self): return "{0.number:02d} - {0.title}.mp3".format(self)
Youknowmsayin? Representin for Brooklyn Most of all my cousin Prince Leroy, Big Mal, rest in peace [ Billy Danzenie ] Danzenie up in this muthaf**ka I`d like to say what`s up to the whole M.O.P. Brooklyn, period Them n****s that just don`t give a f**k [ O.G. Bu-Bang Bet yo ass, n***a Hey yo, this muthaf**kin Babyface [Name] Aka O.G. Bu-Bang Yo, I wanna say what`s up to the whole muthaf**kin M.O.P. boyyeee """) t.save("example-v2_4.id3", version=ID3_V2_4) t.save("example-v2_3.id3", version=ID3_V2_3) # Loss of the release date month and day. # Loss of the comment with description. t.save("example-v1_1.id3", version=ID3_V1_1) # Loses what v1.1 loses, and the track # t.save("example-v1_0.id3", version=ID3_V1_0) ''' from eyed3.id3.tag import TagTemplate template = "$artist/"\ "$best_release_date:year - $album/"\ "$artist - $track:num - $title.$file:ext" print TagTemplate(template).substitute(t, zeropad=True)
Youknowmsayin? Representin for Brooklyn Most of all my cousin Prince Leroy, Big Mal, rest in peace [ Billy Danzenie ] Danzenie up in this muthaf**ka I`d like to say what`s up to the whole M.O.P. Brooklyn, period Them n****s that just don`t give a f**k [ O.G. Bu-Bang Bet yo ass, n***a Hey yo, this muthaf**kin Babyface [Name] Aka O.G. Bu-Bang Yo, I wanna say what`s up to the whole muthaf**kin M.O.P. boyyeee """) t.save("example-v2_4.id3", version=ID3_V2_4) t.save("example-v2_3.id3", version=ID3_V2_3) # Loss of the release date month and day. # Loss of the comment with description. t.save("example-v1_1.id3", version=ID3_V1_1) # Loses what v1.1 loses, and the track # t.save("example-v1_0.id3", version=ID3_V1_0) ''' from eyed3.id3.tag import TagTemplate template = "$artist/"\ "$best_release_date:year - $album/"\ "$artist - $track:num - $title.$file:ext" print TagTemplate(template).substitute(t, zeropad=True) '''
class CleanMyMusic: def __init__(self): self.regex = r"" self.t = Tag() self.parser = argparse.ArgumentParser(description='A Python Script to clean/format mp3 file metadata', prog='mp3clean', usage='python %(prog)s.py [options]', formatter_class=argparse.ArgumentDefaultsHelpFormatter, epilog="And that's how its done") self.args = None self.t_map = {'Title': 'title', 'Album': 'album', 'Artist': 'artist', 'AlbumArtist': 'album_artist', 'Genre': 'genre.name'} def main(self): self._parse_args() if self.args.case: self._title_case() if self.args.trim == 'r': self._rtrim() if self.args.trim == 'l': self._ltrim() if self.args.nocomments: self._no_comments() if self.args.set: self._set_value() if self.args.cleanse: self._cleanse() if self.args.trackno: self._get_track() if self.args.invtrackno: self._inv_track() if self.args.gettrack: self._set_track() if self.args.newtrack: self._new_track() if self.args.gettitle: self._get_title() def _title_case(self): for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) self.t.parse(file_path) if "All" in self.args.entity: for et in self.t_map: eval('self.t._set' + et + '(self.t.' + self.t_map[et] + '.title())') else: for et in self.args.entity: if et != "Filename": try: eval('self.t._set' + et + '(self.t.' + self.t_map[et] + '.title())') except NotImplementedError: continue self.t.save() if "Filename" in self.args.entity or "All" in self.args.entity: os.rename(file_path, file_path[:-4].title() + ".mp3") def _rtrim(self): for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) self.t.parse(file_path) if "All" in self.args.entity: for et in self.t_map: eval('self.t._set' + et + '(self.t.' + self.t_map[et] + '[:-self.args.num])') else: for et in self.args.entity: if et != "Filename": eval('self.t._set' + et + '(self.t.' + self.t_map[et] + '[:-self.args.num])') self.t.save() if "Filename" in self.args.entity or "All" in self.args.entity: os.rename(file_path, os.path.join(self.args.dir, filename[:-4 - self.args.num]) + ".mp3") def _ltrim(self): for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) self.t.parse(file_path) if "All" in self.args.entity: for et in self.t_map: eval('self.t._set' + et + '(self.t.' + self.t_map[et] + '[self.args.num:])') else: for et in self.args.entity: if et != "Filename": eval('self.t._set' + et + '(self.t.' + self.t_map[et] + '[self.args.num:])') self.t.save() if "Filename" in self.args.entity or "All" in self.args.entity: os.rename(file_path, os.path.join(self.args.dir, filename[self.args.num:])) def _no_comments(self): for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) self.t.parse(file_path) self.t.comments.set(u"") self.t.save() def _set_value(self): for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) self.t.parse(file_path) eval('self.t._set' + self.args.set + '(u"\u0020".join(self.args.value))') self.t.save() @staticmethod def _clean_using_regex(strng, regex): if regex == "[*]": return re.sub(r"\[*\]", '', strng) elif regex == "(*)": return re.sub(r"\(*\)", '', strng) elif regex == "* -": return strng.split(" -")[-1].strip() elif regex == "- *": return strng.split("- ")[0].strip() elif regex == ":: *": return strng.split(":: ")[0].strip() elif regex == '-': return re.sub("-", '', strng) elif regex == '-': return re.sub("_", ' ', strng) else: return strng def _cleanse(self): for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) self.t.parse(file_path.strip()) for et in self.args.entity: if et == "Filename": old = filename new = self._clean_using_regex(old, self.args.cleanse) os.rename(file_path, os.path.join(self.args.dir, new) + ".mp3") else: old = eval('self.t.' + self.t_map[et]) new = re.sub(' ', u"\u0020", self._clean_using_regex(old, self.args.cleanse)) eval('self.t._set' + et + '(u\"' + new + '\")') self.t.save() def _get_track(self): for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) self.t.parse(file_path) self.t.track_num = (filename[:2], 5) self.t.save() def _set_track(self): for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) self.t.parse(file_path) self.t.track_num = (self.t.title[:2], 5) self.t.save() def _inv_track(self): for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) self.t.parse(file_path) if len(str(self.t.track_num[0])) == 1: new_name = "0" + str(self.t.track_num[0]) + " " + filename else: new_name = str(self.t.track_num[0]) + " " + filename new_path = os.path.join(self.args.dir, new_name) os.rename(file_path, new_path) def _new_track(self): i = 1 for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) self.t.parse(file_path) self.t.track_num = (i, 5) self.t.save() if len(str(self.t.track_num[0])) == 1: new_name = "0" + str(i) + " " + filename else: new_name = str(i) + " " + filename new_path = os.path.join(self.args.dir, new_name) os.rename(file_path, new_path) i += 1 def _get_title(self): # fails for single word titles for filename in os.listdir(self.args.dir): if filename.endswith(".mp3"): file_path = os.path.join(self.args.dir, filename) try: self.t.parse(file_path) new_title = re.sub(' ', u"\u0020", filename[:-4]) self.t._setTitle(new_title) self.t.save() except TypeError: continue def _parse_args(self): group = self.parser.add_argument_group('options') self.parser.add_argument('--version', action='version', version='%(prog)s 0.5.0') self.parser.add_argument('dir', help='Directory of the files to be formatted', type=str) group.add_argument('-c', '--case', help='Change the case to Title Case', action='store_true') group.add_argument('-nc', '--nocomments', help='Remove comments if any', action='store_true') group.add_argument('-tn', '--trackno', help='Get Track No from Filename', action='store_true') group.add_argument('-itn', '--invtrackno', help='Add Track No to Filename', action='store_true') group.add_argument('-cl', '--cleanse', help='Remove unwanted characters that match a pattern', choices=['[*]', '(*)', '- *', '* -', ':: *', '_', '-'], type=str) group.add_argument('-gt', '--gettrack', help='Gets track number from Title', action='store_true') group.add_argument('-gtn', '--gettitle', help='Gets Title from Filename', action='store_true') group.add_argument('-nt', '--newtrack', help='Adds new track numbers', action='store_true') group.add_argument('-e', '--entity', help='What to format', required=False, action='append', choices=['Title', 'Filename', 'Album', 'Artist', 'AlbumArtist', 'Genre', 'All'], type=str) group.add_argument('-t', '--trim', help='Trim characters to left or right', choices=['l', 'r'], type=str) group.add_argument('-n', '--num', help='Number of character to be trimmed', type=int) group.add_argument('-s', '--set', help='Set any option', choices=['Album', 'Artist', 'AlbumArtist', 'Genre'], type=str) group.add_argument('-v', '--value', nargs="*", help='Value of choice given in set', type=str) self.args = self.parser.parse_args() if self.args.entity == "All": self.args.entity = self.t_map.keys()