Ejemplo n.º 1
0
    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])
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
 def __init__(self, filename):
     self.original = filename
     self.cleaned = TrackData.clean_string(filename, True)