picklepete / pyicloud

A Python + iCloud wrapper to access iPhone and Calendar data.
MIT License
2.5k stars 443 forks source link

PhotoAlbum object seems to return random order of PhotoAssets #273

Open landall opened 4 years ago

landall commented 4 years ago

When I download the photos of an album, I record the photo.id of those downloaded. When my program is killed, I restart the download and skip those id recorded. But I find they are not always on the top of the download list.

And I get only 6269 files from an album with 7523 photo assets. It seems there is a bug.

dict = []
for album in api.photos.albums:
    print album, len(api.photos.albums[album])
    path = 'd:/pyicloud/' + album + '/'
    infopath = 'd:/pyicloud/album_' + album + '.json'
    tmppath = 'd:/pyicloud/tmp_' + album + '.json'
    if os.path.exists(infopath):
        continue
    use_tmp = os.path.exists(tmppath)
    if use_tmp:
        file = open(tmppath, mode="rb")
        print 'loading cache...'
        tmp = json.load(file)
        file.close()
    else:
        tmp = {}
    if not os.path.exists(path):
        os.makedirs(path)
    info = []
    for photo in api.photos.albums[album]:
        #print "    ", photo.id, photo.filename, photo.created, photo.asset_date, photo.added_date
        info.append({'id': photo.id, 'filename': photo.filename, 'size': photo.size, 
            'created': photo.created.strftime('%Y-%m-%d %H:%M:%S %Z'), 
            'asset_date': photo.asset_date.strftime('%Y-%m-%d %H:%M:%S %Z'), 
            'added_date': photo.added_date.strftime('%Y-%m-%d %H:%M:%S %Z')})
        if use_tmp:
            if tmp.has_key(photo.id):
                print "    ", photo.id, photo.size, " skipped"
                continue;
        print "    ", photo.id, photo.size
        download = photo.download()
        with open(path+photo.filename, 'wb') as opened_file:
            opened_file.write(download.raw.read())
        tmp[photo.id] = True
        if len(tmp)%10 == 0:
            file = open(tmppath, mode='wb')
            json.dump(tmp, file, ensure_ascii=False, sort_keys=True, indent=4)
            file.close()
    file = open(infopath, mode='wb')
    json.dump(info, file, ensure_ascii=False, sort_keys=True, indent=4)
    print json.dumps(info, ensure_ascii=False, sort_keys=True, indent=4)
    file.close()
    os.remove(tmppath)
magus0219 commented 4 years ago

@landall

274 is my answer, hope it can help you

landall commented 4 years ago

@landall

274 is my answer, hope it can help you

Thanks for reply. It is close to my intuition. And I find a bug in my code that I cannot save the image with photo.filename because filename is not a unique field. I use photo.id to help change filename now.

magus0219 commented 4 years ago

@landall yes, i also found that id problem. yet further more, photo.id(master recordName) is just a piece of checksum of asset(you can find this lead in http response data), so it still may be not unique in some case or if you have dup assets.

At last I change my file id to asset recordName. It is something really unique.

landall commented 3 years ago

@landall yes, i also found that id problem. yet further more, photo.id(master recordName) is just a piece of checksum of asset(you can find this lead in http response data), so it still may be not unique in some case or if you have dup assets.

At last I change my file id to asset recordName. It is something really unique.

I find asset recordName is also not unique. I get 66413 items in my 'All Photos' album but 66502 unique asset recordName and 65751 unique master recordName. Do you know why?