Example #1
0
def get_iphoto_or_aperture_pictures(plistpath: Path, photo_class):
    # The structure of iPhoto and Aperture libraries for the base photo list are excactly the same.
    if not plistpath.exists():
        return []
    s = plistpath.open("rt", encoding="utf-8").read()
    # There was a case where a guy had 0x10 chars in his plist, causing expat errors on loading
    s = remove_invalid_xml(s, replace_with="")
    # It seems that iPhoto sometimes doesn't properly escape & chars. The regexp below is to find
    # any & char that is not a &-based entity (&, ", etc.). based on TextMate's XML
    # bundle's regexp
    s, count = re.subn(r"&(?![a-zA-Z0-9_-]+|#[0-9]+|#x[0-9a-fA-F]+;)", "", s)
    if count:
        logging.warning("%d invalid XML entities replacement made", count)
    parser = IPhotoPlistParser()
    try:
        plist = parser.parse(io.BytesIO(s.encode("utf-8")))
    except Exception:
        logging.warning("iPhoto plist parsing choked on data: %r", parser.lastdata)
        raise
    result = []
    for key, photo_data in plist["Master Image List"].items():
        if photo_data["MediaType"] != "Image":
            continue
        photo_path = Path(photo_data["ImagePath"])
        photo = photo_class(photo_path, key)
        result.append(photo)
    return result
Example #2
0
def get_iphoto_or_aperture_pictures(plistpath: Path, photo_class):
    # The structure of iPhoto and Aperture libraries for the base photo list are excactly the same.
    if not plistpath.exists():
        return []
    s = plistpath.open('rt', encoding='utf-8').read()
    # There was a case where a guy had 0x10 chars in his plist, causing expat errors on loading
    s = remove_invalid_xml(s, replace_with='')
    # It seems that iPhoto sometimes doesn't properly escape & chars. The regexp below is to find
    # any & char that is not a &-based entity (&, ", etc.). based on TextMate's XML
    # bundle's regexp
    s, count = re.subn(r'&(?![a-zA-Z0-9_-]+|#[0-9]+|#x[0-9a-fA-F]+;)', '', s)
    if count:
        logging.warning("%d invalid XML entities replacement made", count)
    parser = IPhotoPlistParser()
    try:
        plist = parser.parse(io.BytesIO(s.encode('utf-8')))
    except Exception:
        logging.warning("iPhoto plist parsing choked on data: %r",
                        parser.lastdata)
        raise
    result = []
    for key, photo_data in plist['Master Image List'].items():
        if photo_data['MediaType'] != 'Image':
            continue
        photo_path = Path(photo_data['ImagePath'])
        photo = photo_class(photo_path, key)
        result.append(photo)
    return result
Example #3
0
def get_iphoto_or_aperture_pictures(plistpath: Path, photo_class):
    # The structure of iPhoto and Aperture libraries for the base photo list are excactly the same.
    if not plistpath.exists():
        return []
    s = plistpath.open('rt', encoding='utf-8').read()
    # There was a case where a guy had 0x10 chars in his plist, causing expat errors on loading
    s = remove_invalid_xml(s, replace_with='')
    # It seems that iPhoto sometimes doesn't properly escape & chars. The regexp below is to find
    # any & char that is not a &-based entity (&, ", etc.). based on TextMate's XML
    # bundle's regexp
    s, count = re.subn(r'&(?![a-zA-Z0-9_-]+|#[0-9]+|#x[0-9a-fA-F]+;)', '', s)
    if count:
        logging.warning("%d invalid XML entities replacement made", count)
    plist = plistlib.readPlistFromBytes(s.encode('utf-8'))
    result = []
    for key, photo_data in plist['Master Image List'].items():
        if photo_data['MediaType'] != 'Image':
            continue
        photo_path = Path(photo_data['ImagePath'])
        photo = photo_class(photo_path, key)
        result.append(photo)
    return result