Skip to content
This repository was archived by the owner on Jul 30, 2021. It is now read-only.

Commit c168bdd

Browse files
authored
Merge pull request #82 from tchellomello/version_0.1.5
Version 0.1.5
2 parents f8df1db + 6bc4e26 commit c168bdd

File tree

5 files changed

+109
-32
lines changed

5 files changed

+109
-32
lines changed

pyarlo/base_station.py

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from pyarlo.const import (
99
ACTION_BODY, SUBSCRIBE_ENDPOINT, UNSUBSCRIBE_ENDPOINT,
1010
FIXED_MODES, NOTIFY_ENDPOINT, RESOURCES)
11+
from pyarlo.utils import assert_is_dict
12+
1113
_LOGGER = logging.getLogger(__name__)
1214

1315
REFRESH_RATE = 15
@@ -40,6 +42,8 @@ def __init__(self, name, attrs, session_token, arlo_session,
4042
self.__events = []
4143
self.__event_handle = None
4244

45+
self._attrs = assert_is_dict(self._attrs)
46+
4347
def __repr__(self):
4448
"""Representation string of object."""
4549
return "<{0}: {1}>".format(self.__class__.__name__, self.name)
@@ -208,52 +212,72 @@ def __run_action(
208212
@property
209213
def device_id(self):
210214
"""Return device_id."""
211-
return self._attrs.get('deviceId')
215+
if self._attrs is not None:
216+
return self._attrs.get('deviceId')
217+
return None
212218

213219
@property
214220
def device_type(self):
215221
"""Return device_type."""
216-
return self._attrs.get('deviceType')
222+
if self._attrs is not None:
223+
return self._attrs.get('deviceType')
224+
return None
217225

218226
@property
219227
def model_id(self):
220228
"""Return model_id."""
221-
return self._attrs.get('modelId')
229+
if self._attrs is not None:
230+
return self._attrs.get('modelId')
231+
return None
222232

223233
@property
224234
def hw_version(self):
225235
"""Return hardware version."""
226-
return self._attrs.get('properties').get('hwVersion')
236+
if self._attrs is not None:
237+
return self._attrs.get('properties').get('hwVersion')
238+
return None
227239

228240
@property
229241
def timezone(self):
230242
"""Return timezone."""
231-
return self._attrs.get('properties').get('olsonTimeZone')
243+
if self._attrs is not None:
244+
return self._attrs.get('properties').get('olsonTimeZone')
245+
return None
232246

233247
@property
234248
def unique_id(self):
235249
"""Return unique_id."""
236-
return self._attrs.get('uniqueId')
250+
if self._attrs is not None:
251+
return self._attrs.get('uniqueId')
252+
return None
237253

238254
@property
239255
def serial_number(self):
240256
"""Return serial number."""
241-
return self._attrs.get('properties').get('serialNumber')
257+
if self._attrs is not None:
258+
return self._attrs.get('properties').get('serialNumber')
259+
return None
242260

243261
@property
244262
def user_id(self):
245263
"""Return userID."""
246-
return self._attrs.get('userId')
264+
if self._attrs is not None:
265+
return self._attrs.get('userId')
266+
return None
247267

248268
@property
249269
def user_role(self):
250270
"""Return userRole."""
251-
return self._attrs.get('userRole')
271+
if self._attrs is not None:
272+
return self._attrs.get('userRole')
273+
return None
252274

253275
@property
254276
def xcloud_id(self):
255277
"""Return X-Cloud-ID attribute."""
256-
return self._attrs.get('xCloudId')
278+
if self._attrs is not None:
279+
return self._attrs.get('xCloudId')
280+
return None
257281

258282
@property
259283
def last_refresh(self):
@@ -469,6 +493,7 @@ def update(self):
469493
if current_time >= (last_refresh + self._refresh_rate):
470494
self.get_cameras_properties()
471495
self._attrs = self._session.refresh_attributes(self.name)
496+
self._attrs = assert_is_dict(self._attrs)
472497
_LOGGER.debug("Called base station update of camera properties: "
473498
"Scan Interval: %s, New Properties: %s",
474499
self._refresh_rate, self.camera_properties)

pyarlo/camera.py

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
SNAPSHOTS_ENDPOINT, SNAPSHOTS_BODY, PRELOAD_DAYS)
77
from pyarlo.media import ArloMediaLibrary
88
from pyarlo.utils import http_get
9+
from pyarlo.utils import assert_is_dict
910

1011
_LOGGER = logging.getLogger(__name__)
1112

@@ -28,6 +29,9 @@ def __init__(self, name, attrs, arlo_session,
2829
self._cached_videos = None
2930
self._min_days_vdo_cache = min_days_vdo_cache
3031

32+
# make sure self._attrs is a dict
33+
self._attrs = assert_is_dict(self._attrs)
34+
3135
def __repr__(self):
3236
"""Representation string of object."""
3337
return "<{0}: {1}>".format(self.__class__.__name__, self.name)
@@ -56,7 +60,9 @@ def min_days_vdo_cache(self, value):
5660
@property
5761
def device_id(self):
5862
"""Return device_id."""
59-
return self._attrs.get('deviceId')
63+
if self._attrs is not None:
64+
return self._attrs.get('deviceId')
65+
return None
6066

6167
@property
6268
def serial_number(self):
@@ -66,42 +72,58 @@ def serial_number(self):
6672
@property
6773
def device_type(self):
6874
"""Return device_type."""
69-
return self._attrs.get('deviceType')
75+
if self._attrs is not None:
76+
return self._attrs.get('deviceType')
77+
return None
7078

7179
@property
7280
def model_id(self):
7381
"""Return model_id."""
74-
return self._attrs.get('modelId')
82+
if self._attrs is not None:
83+
return self._attrs.get('modelId')
84+
return None
7585

7686
@property
7787
def hw_version(self):
7888
"""Return hardware version."""
79-
return self._attrs.get('properties').get('hwVersion')
89+
if self._attrs is not None:
90+
return self._attrs.get('properties').get('hwVersion')
91+
return None
8092

8193
@property
8294
def parent_id(self):
8395
"""Return camera parentID."""
84-
return self._attrs.get('parentId')
96+
if self._attrs is not None:
97+
return self._attrs.get('parentId')
98+
return None
8599

86100
@property
87101
def timezone(self):
88102
"""Return timezone."""
89-
return self._attrs.get('properties').get('olsonTimeZone')
103+
if self._attrs is not None:
104+
return self._attrs.get('properties').get('olsonTimeZone')
105+
return None
90106

91107
@property
92108
def unique_id(self):
93109
"""Return unique_id."""
94-
return self._attrs.get('uniqueId')
110+
if self._attrs is not None:
111+
return self._attrs.get('uniqueId')
112+
return None
95113

96114
@property
97115
def user_id(self):
98116
"""Return userID."""
99-
return self._attrs.get('userId')
117+
if self._attrs is not None:
118+
return self._attrs.get('userId')
119+
return None
100120

101121
@property
102122
def unseen_videos(self):
103123
"""Return number of unseen videos."""
104-
return self._attrs.get('mediaObjectCount')
124+
if self._attrs is not None:
125+
return self._attrs.get('mediaObjectCount')
126+
return None
105127

106128
def unseen_videos_reset(self):
107129
"""Reset the unseen videos counter."""
@@ -112,12 +134,16 @@ def unseen_videos_reset(self):
112134
@property
113135
def user_role(self):
114136
"""Return userRole."""
115-
return self._attrs.get('userRole')
137+
if self._attrs is not None:
138+
return self._attrs.get('userRole')
139+
return None
116140

117141
@property
118142
def last_image(self):
119143
"""Return last image captured by camera."""
120-
return http_get(self._attrs.get('presignedLastImageUrl'))
144+
if self._attrs is not None:
145+
return http_get(self._attrs.get('presignedLastImageUrl'))
146+
return None
121147

122148
@property
123149
def last_image_from_cache(self):
@@ -182,15 +208,17 @@ def play_last_video(self):
182208
@property
183209
def xcloud_id(self):
184210
"""Return X-Cloud-ID attribute."""
185-
return self._attrs.get('xCloudId')
211+
if self._attrs is not None:
212+
return self._attrs.get('xCloudId')
213+
return None
186214

187215
@property
188216
def base_station(self):
189217
"""Return the base_station assigned for the given camera."""
190218
try:
191219
return list(filter(lambda x: x.device_id == self.parent_id,
192220
self._session.base_stations))[0]
193-
except IndexError:
221+
except (IndexError, AttributeError):
194222
return None
195223

196224
def _get_camera_properties(self):
@@ -379,6 +407,7 @@ def schedule_snapshot(self):
379407
def update(self):
380408
"""Update object properties."""
381409
self._attrs = self._session.refresh_attributes(self.name)
410+
self._attrs = assert_is_dict(self._attrs)
382411

383412
# force base_state to update properties
384413
if self.base_station:

pyarlo/media.py

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
from datetime import datetime
55
from datetime import timedelta
66
from pyarlo.const import LIBRARY_ENDPOINT, PRELOAD_DAYS
7-
from pyarlo.utils import http_get, http_stream, to_datetime, pretty_timestamp
7+
from pyarlo.utils import (
8+
http_get, http_stream, to_datetime, pretty_timestamp,
9+
assert_is_dict)
810

911
_LOGGER = logging.getLogger(__name__)
1012

@@ -96,6 +98,7 @@ def __init__(self, attrs, camera, arlo_session):
9698
:param arlo_session: Arlo shared session
9799
"""
98100
self._attrs = attrs
101+
self._attrs = assert_is_dict(self._attrs)
99102
self._camera = camera
100103
self._session = arlo_session
101104

@@ -115,12 +118,16 @@ def _name(self):
115118
@property
116119
def id(self):
117120
"""Return object id."""
118-
return self._attrs.get('name')
121+
if self._attrs is not None:
122+
return self._attrs.get('name')
123+
return None
119124

120125
@property
121126
def created_at(self):
122127
"""Return timestamp."""
123-
return self._attrs.get('localCreatedDate')
128+
if self._attrs is not None:
129+
return self._attrs.get('localCreatedDate')
130+
return None
124131

125132
def created_at_pretty(self, date_format=None):
126133
"""Return pretty timestamp."""
@@ -143,7 +150,9 @@ def datetime(self):
143150
@property
144151
def content_type(self):
145152
"""Return content_type."""
146-
return self._attrs.get('contentType')
153+
if self._attrs is not None:
154+
return self._attrs.get('contentType')
155+
return None
147156

148157
@property
149158
def camera(self):
@@ -153,22 +162,30 @@ def camera(self):
153162
@property
154163
def media_duration_seconds(self):
155164
"""Return media duration in seconds."""
156-
return self._attrs.get('mediaDurationSecond')
165+
if self._attrs is not None:
166+
return self._attrs.get('mediaDurationSecond')
167+
return None
157168

158169
@property
159170
def triggered_by(self):
160171
"""Return the reason why video was recorded."""
161-
return self._attrs.get('reason')
172+
if self._attrs is not None:
173+
return self._attrs.get('reason')
174+
return None
162175

163176
@property
164177
def thumbnail_url(self):
165178
"""Return thumbnail url."""
166-
return self._attrs.get('presignedThumbnailUrl')
179+
if self._attrs is not None:
180+
return self._attrs.get('presignedThumbnailUrl')
181+
return None
167182

168183
@property
169184
def video_url(self):
170185
"""Return video content url."""
171-
return self._attrs.get('presignedContentUrl')
186+
if self._attrs is not None:
187+
return self._attrs.get('presignedContentUrl')
188+
return None
172189

173190
def download_thumbnail(self, filename=None):
174191
"""Download JPEG thumbnail.

pyarlo/utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,10 @@ def http_stream(url, chunk=4096):
4343
yield data
4444

4545

46+
def assert_is_dict(var):
47+
"""Assert variable is from the type dictionary."""
48+
if var is None or not isinstance(var, dict):
49+
return {}
50+
return var
51+
4652
# vim:sw=4:ts=4:et:

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
setup(
66
name='pyarlo',
77
packages=['pyarlo'],
8-
version='0.1.4',
8+
version='0.1.5',
99
description='Python Arlo is a library written in Python 2.7/3x ' +
1010
'that exposes the Netgear Arlo cameras as Python objects.',
1111
author='Marcelo Moreira de Mello',

0 commit comments

Comments
 (0)