-
Notifications
You must be signed in to change notification settings - Fork 1
/
ringdownload.py
106 lines (84 loc) · 2.57 KB
/
ringdownload.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# https://github.com/tchellomello/python-ring-doorbell
import json
import getpass
import os
from pathlib import Path
from pprint import pprint
from ring_doorbell import Ring, Auth
from oauthlib.oauth2 import MissingTokenError
cache_file = Path("test_token.cache")
# grab info on this many videos at a time
CHUNK_SIZE = 50
def _format_filename(event):
if not isinstance(event, dict):
return
if event["answered"]:
answered_status = "answered"
else:
answered_status = "not_answered"
filename = "{}_{}_{}_{}".format(
event["created_at"], event["kind"], answered_status, event["id"]
)
filename = filename.replace(" ", "_").replace(":", ".") + ".mp4"
return filename
def download(deck):
count = 0
all_events = deck.history(limit=100)
total = len(all_events);
last_eid = all_events[-1]['id']
while True:
next_events = deck.history(older_than=last_eid, limit=CHUNK_SIZE)
if next_events:
next_last_eid = next_events[-1]['id'];
if next_last_eid == last_eid:
break;
else:
total += len(next_events);
last_eid = next_last_eid;
else:
break;
print ('Total number of events is at least %s' % (total))
eid = None
while True:
events = deck.history(older_than=eid, limit=CHUNK_SIZE)
for event in events:
eid = event['id']
if eid < last_eid:
return
filename = _format_filename(event)
fq_filename = 'videos/{}'.format(filename)
if not os.path.isfile(fq_filename):
try:
deck.recording_download(eid, filename=fq_filename)
except Exception as inst:
print('The file ' + fq_filename + ' could not be downloaded.')
else:
print('The file ' + fq_filename + ' already exists.')
count += 1
print ('%s %s:%s' % (count, eid, filename))
def token_updated(token):
cache_file.write_text(json.dumps(token))
def otp_callback():
auth_code = input("2FA code: ")
return auth_code
def main():
if cache_file.is_file():
auth = Auth("MyProject/1.0", json.loads(cache_file.read_text()), token_updated)
else:
username = input("Username: ")
password = getpass.getpass("Password: ")
auth = Auth("MyProject/1.0", None, token_updated)
try:
auth.fetch_token(username, password)
except MissingTokenError:
auth.fetch_token(username, password, otp_callback())
ring = Ring(auth)
ring.update_data()
devices = ring.devices()
pprint(devices)
# play with the API to figure out which camera you want
deck = devices['doorbots'][0]
download(deck)
print ('\nDONE.')
if __name__ == "__main__":
main()