def parse_tle(fileobj):
    """Parse a file of TLE satellite element sets.

    Builds an Earth satellite from each pair of adjacent lines in the
    file that start with "1 " and "2 " and have 69 or more characters
    each.  If the preceding line is exactly 24 characters long, then it
    is parsed as the satellite's name.  For each satellite found, yields
    a tuple `(names, sat)` giving the name(s) on the preceding line (or
    `None` if no name was found) and the satellite object itself.

    An exception is raised if the attempt to parse a pair of candidate
    lines as TLE elements fails.

    """
    b0 = b1 = b''
    for b2 in fileobj:
        if (b1.startswith(b'1 ') and len(b1) >= 69 and
            b2.startswith(b'2 ') and len(b2) >= 69):

            b0 = b0.rstrip(b'\n\r')
            if len(b0) == 24:   # Celestrak
                name = b0.decode('ascii').rstrip()
                names = [name]
            elif b0.startswith(b'0 '): # Spacetrack 3-line format
                name = b0[2:].decode('ascii').rstrip()
                names = [name]
            else:
                name = None
                names = ()

            line1 = b1.decode('ascii')
            line2 = b2.decode('ascii')
            sat = EarthSatellite(line1, line2, name)

            if name and ' (' in name:
                # Given a name like `ISS (ZARYA)` or `HTV-6 (KOUNOTORI
                # 6)`, also support lookup by the name inside or outside
                # the parentheses.
                short_name, secondary_name = name.split(' (')
                secondary_name = secondary_name.rstrip(')')
                names.append(short_name)
                names.append(secondary_name)

            yield names, sat

        b0 = b1
        b1 = b2
Parse a file of TLE satellite element sets.

    Builds an Earth satellite from each pair of adjacent lines in the
    file that start with "1 " and "2 " and have 69 or more characters
    each.  If the preceding line is exactly 24 characters long, then it
    is parsed as the satellite's name.  For each satellite found, yields
    a tuple `(names, sat)` giving the name(s) on the preceding line (or
    `None` if no name was found) and the satellite object itself.

    An exception is raised if the attempt to parse a pair of candidate
    lines as TLE elements fails.