Merge pull request #171 from fronzbot/fix-video-api
Added changed video download endpoint
This commit is contained in:
+2
-2
@@ -168,8 +168,8 @@ def request_videos(blink, time=None, page=0):
|
||||
:param page: Page number to get videos from.
|
||||
"""
|
||||
timestamp = get_time(time)
|
||||
url = "{}/api/v2/videos/changed?since={}&page={}".format(
|
||||
blink.urls.base_url, timestamp, page)
|
||||
url = "{}/api/v1/accounts/{}/media/changed?since={}&page={}".format(
|
||||
blink.urls.base_url, blink.account_id, timestamp, page)
|
||||
return http_get(blink, url)
|
||||
|
||||
|
||||
|
||||
+21
-14
@@ -247,7 +247,8 @@ class Blink():
|
||||
combined = merge_dicts(combined, self.sync[sync].cameras)
|
||||
return combined
|
||||
|
||||
def download_videos(self, path, since=None, camera='all', stop=10):
|
||||
def download_videos(self, path, since=None,
|
||||
camera='all', stop=10, debug=False):
|
||||
"""
|
||||
Download all videos from server since specified time.
|
||||
|
||||
@@ -258,6 +259,8 @@ class Blink():
|
||||
:param camera: Camera name to retrieve. Defaults to "all".
|
||||
Use a list for multiple cameras.
|
||||
:param stop: Page to stop on (~25 items per page. Default page 10).
|
||||
:param debug: Set to TRUE to prevent downloading of items.
|
||||
Instead of downloading, entries will be printed to log.
|
||||
"""
|
||||
if since is None:
|
||||
since_epochs = self.last_refresh
|
||||
@@ -275,23 +278,23 @@ class Blink():
|
||||
response = api.request_videos(self, time=since_epochs, page=page)
|
||||
_LOGGER.debug("Processing page %s", page)
|
||||
try:
|
||||
result = response['videos']
|
||||
result = response['media']
|
||||
if not result:
|
||||
raise IndexError
|
||||
except (KeyError, IndexError):
|
||||
_LOGGER.info("No videos found on page %s. Exiting.", page)
|
||||
break
|
||||
|
||||
self._parse_downloaded_items(result, camera, path)
|
||||
self._parse_downloaded_items(result, camera, path, debug)
|
||||
|
||||
def _parse_downloaded_items(self, result, camera, path):
|
||||
def _parse_downloaded_items(self, result, camera, path, debug):
|
||||
"""Parse downloaded videos."""
|
||||
for item in result:
|
||||
try:
|
||||
created_at = item['created_at']
|
||||
camera_name = item['camera_name']
|
||||
camera_name = item['device_name']
|
||||
is_deleted = item['deleted']
|
||||
address = item['address']
|
||||
address = item['media']
|
||||
except KeyError:
|
||||
_LOGGER.info("Missing clip information, skipping...")
|
||||
continue
|
||||
@@ -310,13 +313,17 @@ class Blink():
|
||||
filename = "{}_{}.mp4".format(camera_name, created_at)
|
||||
filename = os.path.join(path, filename)
|
||||
|
||||
if os.path.isfile(filename):
|
||||
_LOGGER.info("%s already exists, skipping...", filename)
|
||||
continue
|
||||
if not debug:
|
||||
if os.path.isfile(filename):
|
||||
_LOGGER.info("%s already exists, skipping...", filename)
|
||||
continue
|
||||
|
||||
response = api.http_get(self, url=clip_address,
|
||||
stream=True, json=False)
|
||||
with open(filename, 'wb') as vidfile:
|
||||
copyfileobj(response.raw, vidfile)
|
||||
response = api.http_get(self, url=clip_address,
|
||||
stream=True, json=False)
|
||||
with open(filename, 'wb') as vidfile:
|
||||
copyfileobj(response.raw, vidfile)
|
||||
|
||||
_LOGGER.info("Downloaded video to %s", filename)
|
||||
_LOGGER.info("Downloaded video to %s", filename)
|
||||
else:
|
||||
_LOGGER.info("Camera: %s, Timestamp: %s, Address: %s",
|
||||
camera_name, created_at, address)
|
||||
|
||||
@@ -164,21 +164,21 @@ class BlinkSyncModule():
|
||||
"""Check if new videos since last refresh."""
|
||||
resp = api.request_videos(self.blink,
|
||||
time=self.blink.last_refresh,
|
||||
page=0)
|
||||
page=1)
|
||||
|
||||
for camera in self.cameras.keys():
|
||||
self.motion[camera] = False
|
||||
|
||||
try:
|
||||
info = resp['videos']
|
||||
info = resp['media']
|
||||
except (KeyError, TypeError):
|
||||
_LOGGER.warning("Could not check for motion. Response: %s", resp)
|
||||
return False
|
||||
|
||||
for entry in info:
|
||||
try:
|
||||
name = entry['camera_name']
|
||||
clip = entry['address']
|
||||
name = entry['device_name']
|
||||
clip = entry['media']
|
||||
timestamp = entry['created_at']
|
||||
self.motion[name] = True
|
||||
self.last_record[name] = {'clip': clip, 'time': timestamp}
|
||||
|
||||
@@ -121,12 +121,12 @@ class TestBlinkFunctions(unittest.TestCase):
|
||||
blinkpy._LOGGER.setLevel(logging.DEBUG)
|
||||
generic_entry = {
|
||||
'created_at': '1970',
|
||||
'camera_name': 'foo',
|
||||
'device_name': 'foo',
|
||||
'deleted': True,
|
||||
'address': '/bar.mp4'
|
||||
'media': '/bar.mp4'
|
||||
}
|
||||
result = [generic_entry]
|
||||
mock_req.return_value = {'videos': result}
|
||||
mock_req.return_value = {'media': result}
|
||||
blink.last_refresh = 0
|
||||
formatted_date = get_time(blink.last_refresh)
|
||||
expected_log = [
|
||||
@@ -147,12 +147,12 @@ class TestBlinkFunctions(unittest.TestCase):
|
||||
blinkpy._LOGGER.setLevel(logging.DEBUG)
|
||||
generic_entry = {
|
||||
'created_at': '1970',
|
||||
'camera_name': 'foo',
|
||||
'device_name': 'foo',
|
||||
'deleted': True,
|
||||
'address': '/bar.mp4'
|
||||
'media': '/bar.mp4'
|
||||
}
|
||||
result = [generic_entry]
|
||||
mock_req.return_value = {'videos': result}
|
||||
mock_req.return_value = {'media': result}
|
||||
blink.last_refresh = 0
|
||||
formatted_date = get_time(blink.last_refresh)
|
||||
expected_log = [
|
||||
|
||||
@@ -62,9 +62,9 @@ class TestBlinkSyncModule(unittest.TestCase):
|
||||
def test_check_new_videos(self, mock_resp):
|
||||
"""Test recent video response."""
|
||||
mock_resp.return_value = {
|
||||
'videos': [{
|
||||
'camera_name': 'foo',
|
||||
'address': '/foo/bar.mp4',
|
||||
'media': [{
|
||||
'device_name': 'foo',
|
||||
'media': '/foo/bar.mp4',
|
||||
'created_at': '1970-01-01T00:00:00+0:00'
|
||||
}]
|
||||
}
|
||||
@@ -76,7 +76,7 @@ class TestBlinkSyncModule(unittest.TestCase):
|
||||
{'clip': '/foo/bar.mp4',
|
||||
'time': '1970-01-01T00:00:00+0:00'})
|
||||
self.assertEqual(sync_module.motion, {'foo': True})
|
||||
mock_resp.return_value = {'videos': []}
|
||||
mock_resp.return_value = {'media': []}
|
||||
self.assertTrue(sync_module.check_new_videos())
|
||||
self.assertEqual(sync_module.motion, {'foo': False})
|
||||
self.assertEqual(sync_module.last_record['foo'],
|
||||
|
||||
Reference in New Issue
Block a user