fronzbot / blinkpy

A Python library for the Blink Camera system
MIT License
585 stars 121 forks source link

Videos do not delete from sync module local storage #970

Open apach3guy opened 4 months ago

apach3guy commented 4 months ago

I recently posted about a script to delete old videos from the local storage on the sync module and I updated my blinkpy to the latest development version. The script appeared to be working (i.e., no errors were generated) but the local storage continued to fill up. Looking in the blink app, I confirmed that old videos (currently defined in my script as older than 5 days) are still showing up, demonstrating that they have not been deleted.

Below is my code and the output.

#!/usr/bin/env python3.9

import asyncio
from datetime import datetime, timedelta
from sortedcontainers import SortedSet
from blinkpy.helpers.util import json_load
from blinkpy.blinkpy import Blink, BlinkSyncModule
from blinkpy.auth import Auth
from aiohttp import ClientSession

async def start(session: ClientSession):
    """Startup blink app."""
    blink = Blink(session=session)
    blink.auth = Auth(await json_load("/home/pi/utils/blink.auth"), session=session)
    await blink.start()
    return blink

async def main():
    session = ClientSession()
    try:
        blink = await start(session)
        await blink.refresh()
        my_sync: BlinkSyncModule = blink.sync["Laguna"]
        await my_sync.refresh()
        if my_sync.local_storage and my_sync.local_storage_manifest_ready:
            manifest = my_sync._local_storage["manifest"]
            # print(f"Manifest {manifest}")
            for item in reversed(manifest):
                current_date = datetime.now(item.created_at.tzinfo)
                time_difference = current_date - item.created_at

                if time_difference > timedelta(days=5):
                    try:
                        await item.delete_video(blink)
                        await asyncio.sleep(2)
                        print(f"Success deleting video {item.id}")
                    except Exception as e:
                        print(f"Error deleting video {item.id}: {e}")
        else:
            print("Manifest not ready")
    finally:
        await session.close()

asyncio.run(main())
Success deleting video 1165876146
Success deleting video 2357212475
Success deleting video 3389086544
Success deleting video 4061158032
Success deleting video 4198518603
Success deleting video 3066931222
Success deleting video 2397370008

Note that output is truncated for brevity.

fronzbot commented 4 months ago

Thanks for reporting!

Seems like there's at least two problems here: 1) Videos not being deleted (might be the wrong endpoint) 2) A log message stating that the deletion was successful without actually checking that it's gone

The second one is an easy fix but doesn't address the issue. The first one is more difficult as I do not have local storage in my setup so have no way to test so will need to rely on other to contribute here. I'll pin this issue though

apach3guy commented 4 months ago

Right, my code assumes that an exception would be thrown if there was a problem deleting the video. However, no exception is thrown so it assumes the video was deleted.

fronzbot commented 4 months ago

Gotcha. To check for a success/fail, the delete method will return "True" if the deletion worked and "False" if it failed. However we're only looking at the request response. It's possible a "True" is being returned even if the video is not deleted. If you get a chance, it's worth checking to make sure delete_video returns False

https://github.com/fronzbot/blinkpy/blob/0a3ba30f16e3bd81d867b107db59cdde65d7cc76/blinkpy/sync_module.py#L714

mmraz3 commented 3 months ago

I am not a Python developer, but I am using your repo and README to figure out what the URLs are for interacting with the sync module. To upload a video from the sync module, I am posting to /api/v1/accounts/{account-id}/networks/{network-id}/sync_modules/{sync-module-id}/local_storage/manifest/{manifest-id}/clip/request/{clip-id}

To download that video, I do a GET to the same URL. If I followed the Python code correctly, it looks like the URL it is using to delete a video is the same as above except that "request" becomes "delete", so:

/api/v1/accounts/{account-id}/networks/{network-id}/sync_modules/{sync-module-id}/local_storage/manifest/{manifest-id}/clip/delete/{clip-id}

And it is a POST to that URL. Is that correct? The behavior I am seeing is that the call returns 200, with a body that contains a single field, "id". I can repeat the identical call. I continue to get a 200 back each time I call it, and the id is different each time. I still see the video when I go into the Blink app, so the video is not being deleted. In fact, I see that if I change the clip id to any random number, I get the same behavior, so something is definitely wrong with the URL I am using.

mkmer commented 3 weeks ago

There is an "example" included. I haven't used this is awhile (so maybe it is also broken?) https://github.com/fronzbot/blinkpy/blob/e2c747b5ad295424b08ff4fb03204129155666fc/blinksync/blinksync.py#L81-L101 -Delete Button code should do it... Blink sync was intended as an example to download, delete, view files via a UI.