def __init__(self, header_data, xheader_data): """Interprets byte data as a tag header to build object Args: header_data: character array of bytes representing the tag header. Must contain an ID3v1 tag xheader_data: character array of bytes representing the extended tag header. This does not have to contain an extended header (in which case it will be ignored). """ # Check we're actually looking at an ID3v1 tag if header_data[:3] != "TAG": raise Exception("Given data does not contain an ID3v1 tag header") # Extract data self.data = TrackData.TrackData() self.data.title = _strip_null_bytes(header_data[3:33]) self.data.artist = _strip_null_bytes(header_data[33:63]) self.data.album = _strip_null_bytes(header_data[63:93]) self.data.year = TrackData.mint(_strip_null_bytes(header_data[93:97])) if ord(header_data[125]) == 0 and ord(header_data[126]) != 0: self.version = 1 # id3 v1.1 self.comment = _strip_null_bytes(header_data[97:125]) self.data.track = ord(header_data[126]) else: self.version = 0 # id3 v1.0 self.comment = _strip_null_bytes(header_data[97:127]) self.data.track = None self.genre = ord(header_data[127]) # Check if we have an extended tag and extract it self.is_extended = xheader_data[:4] == "TAG+" if self.is_extended: self.data.title += _strip_null_bytes(xheader_data[4:64]) self.data.artist += _strip_null_bytes(xheader_data[64:124]) self.data.album += _strip_null_bytes(xheader_data[124:184])
def __init__(self, file_path, cleaned_filename=""): """ Creates the TrackFile object. Args: file_path: String path to the music file. cleaned_filename: File name removed of any unnecessary data. Optional argument. Opting not to provide it will cause the cleaned filename to be generated automatically. The downside of this is that when automatic cleaning of the filename occurs it is treated in isolation to all other files in the directory (as it does not have access to them) so it cannot perform common word removal or other similar, contextual techniques. Returns: The initialised TrackFile object. """ if file_path == "": raise Exception("Cannot create a TrackFile with an empty file_path.") self.file_path = file_path if cleaned_filename: self.cleaned_filename = cleaned_filename else: self.cleaned_filename = TrackData.clean_string(file_path.split('/')[-1], True) # Initialise track data objects self.finalised = False self.fp = None self.v1 = None self.v2 = None self.final = None
def read_file_path_data(file_path, cleaned_filename): """ Parses TrackData from a file path. The file path provides the majority of the information though a cleaned_filename needs to be passed in (which is designed to be one of the outputs from clean_folder()) as this method will have access to only the single file, not the entire folder of files which is necessary for the full cleaning (e.g. removing repeated words). Args: file_path: String path to the file to generate data for. cleaned_filename: The file name, cleaned to remove unusual formatting. Returns: A TrackData with the fields initialised to the parsed data. Unparsable fields will be initialised to None. """ data = TrackData.TrackData() # Attempt to collect information from the file's path (the album / artist). file_path_split = file_path.split(r'/') # If correctly set up: -1 holds the file name; -2 the album folder; -3 the # artist folder. if len(file_path_split) >= 3: candidate_album_name = TrackData.clean_string(file_path_split[-2]) if re.match(r'\[\d\d\d\d\] ', candidate_album_name) != None: data.album = candidate_album_name[7:] data.year = int(candidate_album_name[1:5]) else: data.album = candidate_album_name data.artist = TrackData.clean_string(file_path_split[-3]) # Attempt to collect information from the file's name (the track number / name). filename_split = cleaned_filename.split() if filename_split[0].isdigit(): data.track = int(filename_split[0]) data.title = ' '.join(filename_split[1:]).split('.')[0] else: data.title = ' '.join(filename_split).split('.')[0] return data
def get_year(self, file_handle): """Retrieves the track year from this tag Args: file_handle: open file handle to read the frame body from Returns: int track year or None if this tag doesn't contain it """ version = self.header.version if version == 2: frame_id = "TYE" elif version == 3 or version == 4: frame_id = "TYER" else: return None frame = self.__get_frame(frame_id) if frame: body_data = _read_frame_text(frame.read_body(file_handle)) return TrackData.mint(body_data[0:4]) return None
def __init__(self, filename): self.original = filename self.cleaned = TrackData.clean_string(filename, True)