dropcam 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +4 -1
- data/example/basics.rb +3 -6
- data/lib/dropcam/base.rb +26 -3
- data/lib/dropcam/camera.rb +41 -202
- data/lib/dropcam/clip.rb +16 -28
- data/lib/dropcam/clip_archive.rb +24 -0
- data/lib/dropcam/clip_base.rb +35 -0
- data/lib/dropcam/cuepoint.rb +15 -2
- data/lib/dropcam/cuepoint_base.rb +27 -0
- data/lib/dropcam/notification.rb +9 -30
- data/lib/dropcam/notification_base.rb +66 -0
- data/lib/dropcam/screenshot.rb +24 -0
- data/lib/dropcam/session.rb +3 -7
- data/lib/dropcam/setting.rb +4 -12
- data/lib/dropcam/version.rb +1 -1
- data/lib/dropcam.rb +20 -30
- metadata +7 -2
data/README.md
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
RubyGem to access Dropcam account and Camera including direct live stream access
|
4
4
|
|
5
|
+
[](https://codeclimate.com/github/nolanbrown/dropcam)
|
6
|
+
|
7
|
+
|
5
8
|
## Installation
|
6
9
|
|
7
10
|
Add this line to your application's Gemfile:
|
@@ -24,7 +27,7 @@ Or install it yourself as:
|
|
24
27
|
camera = dropcam.cameras.first
|
25
28
|
|
26
29
|
# returns jpg image data of the latest frame captured
|
27
|
-
screenshot = camera.
|
30
|
+
screenshot = camera.screenshot.current
|
28
31
|
|
29
32
|
# write data to disk
|
30
33
|
File.open("#{camera.title}.jpg", 'w') {|f| f.write(screenshot) }
|
data/example/basics.rb
CHANGED
@@ -1,15 +1,12 @@
|
|
1
|
-
#dropcam = Dropcam::Session.new("username","password")
|
2
1
|
lib = File.expand_path('../../lib', __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
|
5
4
|
require 'dropcam'
|
6
5
|
require 'awesome_print'
|
7
6
|
dropcam = Dropcam::Dropcam.new(ENV["DROPCAM_USERNAME"],ENV["DROPCAM_PASSWORD"])
|
7
|
+
ap dropcam.public_cameras
|
8
|
+
|
8
9
|
camera = dropcam.cameras.first
|
9
10
|
ap camera.uuid
|
10
11
|
ap camera.session_token
|
11
|
-
ap camera.
|
12
|
-
ap camera.rtmpdump_stream_command
|
13
|
-
|
14
|
-
settings = camera.settings
|
15
|
-
#ap settings["watermark.enabled"].set(false)
|
12
|
+
ap camera.settings
|
data/lib/dropcam/base.rb
CHANGED
@@ -74,8 +74,19 @@ module Dropcam
|
|
74
74
|
request.add_field("Cookie",cookies.join('; ')) if cookies
|
75
75
|
|
76
76
|
response = http.request(request)
|
77
|
+
|
78
|
+
if response.success?
|
79
|
+
return response
|
80
|
+
elsif response.not_authorized?
|
81
|
+
raise AuthorizationError
|
82
|
+
elsif response.error?
|
83
|
+
message = "Unkown Error"
|
84
|
+
message = JSON.parse(response.body)["status_detail"] if JSON.parse(response.body)["status_detail"]
|
85
|
+
raise UnkownError, message
|
86
|
+
else
|
87
|
+
raise CameraNotFoundError
|
88
|
+
end
|
77
89
|
|
78
|
-
return response
|
79
90
|
end
|
80
91
|
|
81
92
|
def get(path, parameters,cookies, use_nexus=false)
|
@@ -88,7 +99,13 @@ module Dropcam
|
|
88
99
|
request.add_field("Cookie",cookies.join('; ')) if cookies
|
89
100
|
|
90
101
|
response = http.request(request)
|
91
|
-
|
102
|
+
if response.success?
|
103
|
+
return response
|
104
|
+
elsif response.not_authorized?
|
105
|
+
raise AuthorizationError
|
106
|
+
else
|
107
|
+
raise CameraNotFoundError
|
108
|
+
end
|
92
109
|
end
|
93
110
|
|
94
111
|
def delete(path, parameters,cookies, use_nexus=false)
|
@@ -101,7 +118,13 @@ module Dropcam
|
|
101
118
|
request.add_field("Cookie",cookies.join('; ')) if cookies
|
102
119
|
|
103
120
|
response = http.request(request)
|
104
|
-
|
121
|
+
if response.success?
|
122
|
+
return response.body ## returns a zip
|
123
|
+
elsif response.not_authorized?
|
124
|
+
raise AuthorizationError
|
125
|
+
else
|
126
|
+
raise CameraNotFoundError
|
127
|
+
end
|
105
128
|
end
|
106
129
|
|
107
130
|
protected
|
data/lib/dropcam/camera.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
|
-
require 'hpricot'
|
2
|
-
|
3
1
|
require_relative 'base'
|
4
2
|
require_relative 'error'
|
5
3
|
require_relative 'notification'
|
6
|
-
require_relative '
|
7
|
-
require_relative '
|
4
|
+
require_relative 'notification_base'
|
5
|
+
require_relative 'cuepoint_base'
|
8
6
|
require_relative 'clip'
|
7
|
+
require_relative 'clip_base'
|
8
|
+
require_relative 'setting'
|
9
9
|
require_relative 'stream'
|
10
|
+
require_relative 'screenshot'
|
10
11
|
|
11
12
|
module Dropcam
|
12
13
|
class Camera < Base
|
@@ -29,136 +30,60 @@ module Dropcam
|
|
29
30
|
}
|
30
31
|
end
|
31
32
|
|
33
|
+
def settings=(new_settings)
|
34
|
+
@settings = {}
|
35
|
+
return @settings unless new_settings
|
36
|
+
new_settings.each{|key,value|
|
37
|
+
@settings[key] = Setting.new(key, value, self)
|
38
|
+
}
|
39
|
+
@settings
|
40
|
+
end
|
32
41
|
|
33
|
-
def
|
34
|
-
|
35
|
-
params["time"] = timestamp if timestamp
|
42
|
+
def settings(force=false)
|
43
|
+
return @settings unless force == true or @settings.length == 0 # key these cached
|
36
44
|
|
37
|
-
response = get(::
|
38
|
-
|
39
|
-
|
40
|
-
elsif response.not_authorized?
|
41
|
-
raise AuthorizationError
|
42
|
-
else
|
43
|
-
raise CameraNotFoundError
|
44
|
-
end
|
45
|
+
response = get(::DROPCAMS_GET_PROPERTIES, {"uuid"=>@uuid}, @cookies)
|
46
|
+
self.settings = JSON.parse(response.body)["items"][0]
|
47
|
+
@settings
|
45
48
|
end
|
46
49
|
|
47
|
-
def current_image(width=1200)
|
48
|
-
return get_image(width)
|
49
|
-
end
|
50
50
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
return response.body ## returns a zip
|
55
|
-
clips = []
|
56
|
-
all_clips = JSON.parse(response.body)["items"]
|
57
|
-
for clip in all_clips
|
58
|
-
c = Clip.new(self, clip)
|
59
|
-
if c.camera_id == self.id
|
60
|
-
clips.push c
|
61
|
-
end
|
62
|
-
end
|
63
|
-
return clips
|
64
|
-
elsif response.not_authorized?
|
65
|
-
raise AuthorizationError
|
66
|
-
else
|
67
|
-
raise CameraNotFoundError
|
68
|
-
end
|
51
|
+
def screenshot
|
52
|
+
@screenshot = Screenshot.new(self) unless @screenshot
|
53
|
+
@screenshot
|
69
54
|
end
|
70
55
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
response = post(::VIDEOS_REQUEST, params, @cookies)
|
75
|
-
if response.success?
|
76
|
-
clip_info = JSON.parse(response.body)["items"][0]
|
77
|
-
return Clip.new(self, clip_info)
|
78
|
-
elsif response.not_authorized?
|
79
|
-
raise AuthorizationError
|
80
|
-
else
|
81
|
-
raise CameraNotFoundError
|
82
|
-
end
|
56
|
+
def clip
|
57
|
+
@clip_base = ClipBase.new(self) unless @clip_base
|
58
|
+
@clip_base
|
83
59
|
end
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
params = {"uuid"=>@uuid, "width" => width, "cuepoint_id" => cuepoint_id, "num_frames" => number_of_frames, "format" => "TAR_JPG"}
|
88
|
-
response = get(::NEXUS_GET_EVENT_CLIP_PATH, params, @cookies, true)
|
89
|
-
if response.success?
|
90
|
-
return response.body ## returns a zip
|
91
|
-
elsif response.not_authorized?
|
92
|
-
raise AuthorizationError
|
93
|
-
else
|
94
|
-
raise CameraNotFoundError
|
95
|
-
end
|
60
|
+
def cuepoint
|
61
|
+
@cuepoint_base = CuepointBase.new(self) unless @cuepoint_base
|
62
|
+
@cuepoint_base
|
96
63
|
end
|
97
|
-
|
98
|
-
def
|
99
|
-
|
100
|
-
|
101
|
-
if response.success?
|
102
|
-
return response.body ## returns a zip
|
103
|
-
elsif response.not_authorized?
|
104
|
-
raise AuthorizationError
|
105
|
-
else
|
106
|
-
raise CameraNotFoundError
|
107
|
-
end
|
64
|
+
|
65
|
+
def stream
|
66
|
+
@stream = Stream.new(self) unless @stream
|
67
|
+
@stream
|
108
68
|
end
|
109
69
|
|
110
|
-
def
|
111
|
-
|
112
|
-
|
113
|
-
if response.success?
|
114
|
-
cuepoints = []
|
115
|
-
all_cuepoints = JSON.parse(response.body)
|
116
|
-
for cuepoint in all_cuepoints
|
117
|
-
cuepoints.push Cuepoint.new(cuepoint)
|
118
|
-
end
|
119
|
-
|
120
|
-
return cuepoints
|
121
|
-
elsif response.not_authorized?
|
122
|
-
raise AuthorizationError
|
123
|
-
else
|
124
|
-
raise CameraNotFoundError
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def get_cuepoint(start_time)
|
129
|
-
params = {"uuid"=>@uuid, "start_time" => start_time}
|
130
|
-
response = get(::NEXUS_GET_CUEPOINT_PATH, params, @cookies, true)
|
131
|
-
if response.success?
|
132
|
-
return Cuepoint.new(JSON.parse(response.body)[0])
|
133
|
-
elsif response.not_authorized?
|
134
|
-
raise AuthorizationError
|
135
|
-
else
|
136
|
-
raise CameraNotFoundError
|
137
|
-
end
|
70
|
+
def notification
|
71
|
+
@notification = NotifcationBase.new(self) unless @notification
|
72
|
+
@notification
|
138
73
|
end
|
139
74
|
|
75
|
+
|
140
76
|
def update_info
|
141
77
|
response = get(::CAMERAS_GET, {"id"=>@uuid}, @cookies)
|
142
|
-
|
143
|
-
|
144
|
-
elsif response.not_authorized?
|
145
|
-
raise AuthorizationError
|
146
|
-
else
|
147
|
-
raise CameraNotFoundError
|
148
|
-
end
|
78
|
+
self.properties = JSON.parse(response.body)["items"][0]
|
79
|
+
|
149
80
|
end
|
150
81
|
|
151
82
|
|
152
83
|
|
153
84
|
def public=(is_public)
|
154
85
|
response = post(::CAMERAS_UPDATE, {"uuid"=>@uuid, "is_public"=>is_public, "accepted_public_terms_at" => "true"}, @cookies)
|
155
|
-
|
156
|
-
self.properties = JSON.parse(response.body)["items"][0]
|
157
|
-
elsif response.not_authorized?
|
158
|
-
raise AuthorizationError
|
159
|
-
else
|
160
|
-
raise CameraNotFoundError
|
161
|
-
end
|
86
|
+
self.properties = JSON.parse(response.body)["items"][0]
|
162
87
|
end
|
163
88
|
|
164
89
|
def public?
|
@@ -167,97 +92,11 @@ module Dropcam
|
|
167
92
|
|
168
93
|
def set_public_token(token)
|
169
94
|
response = post(::CAMERAS_UPDATE, {"uuid"=>@uuid, "token"=>token}, @cookies)
|
170
|
-
|
171
|
-
|
172
|
-
return true
|
173
|
-
elsif response.not_authorized?
|
174
|
-
raise AuthorizationError
|
175
|
-
else
|
176
|
-
raise CameraNotFoundError
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
def settings=(new_settings)
|
181
|
-
@settings = {}
|
182
|
-
new_settings.each{|key,value|
|
183
|
-
@settings[key] = Setting.new(key, value, self)
|
184
|
-
}
|
185
|
-
@settings
|
95
|
+
self.properties = JSON.parse(response.body)["items"][0]
|
96
|
+
true
|
186
97
|
end
|
187
|
-
|
188
|
-
def settings(force=false)
|
189
|
-
return @settings unless force == true or @settings.length == 0 # key these cached
|
190
|
-
|
191
|
-
response = get(::DROPCAMS_GET_PROPERTIES, {"uuid"=>@uuid}, @cookies)
|
192
|
-
if response.success?
|
193
|
-
self.settings = JSON.parse(response.body)["items"][0]
|
194
|
-
return @settings
|
195
|
-
elsif response.not_authorized?
|
196
|
-
raise AuthorizationError
|
197
|
-
else
|
198
|
-
raise CameraNotFoundError
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
def notification_devices
|
203
|
-
|
204
|
-
response = get(::CAMERA_FIND_NOTIFICATIONS, { "id" => @uuid }, @cookies)
|
205
|
-
if response.success?
|
206
|
-
notifications = []
|
98
|
+
|
207
99
|
|
208
|
-
all_notifications = JSON.parse(response.body)["items"]
|
209
|
-
all_notifications.each{|note|
|
210
|
-
notifications.push Notification.new(self, note["target"])
|
211
|
-
}
|
212
|
-
|
213
|
-
notifications
|
214
|
-
elsif response.not_authorized?
|
215
|
-
raise AuthorizationError
|
216
|
-
else
|
217
|
-
raise CameraNotFoundError
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
## API for Notifications doesn't include email notifcations
|
222
|
-
## The code below parses an HTML Partial to get all notifcation values
|
223
|
-
|
224
|
-
def all_notification_devices
|
225
|
-
request_path = ::CAMERA_HTML_SETTINGS_BASE + @uuid
|
226
|
-
response = get(request_path, {}, @cookies)
|
227
|
-
if response.success?
|
228
|
-
raw_html = response.body
|
229
|
-
doc = Hpricot.parse(raw_html)
|
230
|
-
|
231
|
-
notifications = []
|
232
|
-
doc.search("//div[@class='notification_target']").each { |notification_target|
|
233
|
-
puts notification_target
|
234
|
-
data_id = notification_target.get_attribute("data-id")
|
235
|
-
puts data_id
|
236
|
-
name = notification_target.at("div/span").inner_text
|
237
|
-
|
238
|
-
input = notification_target.at("div/input")
|
239
|
-
|
240
|
-
attributes = input.attributes.to_hash
|
241
|
-
data_type = attributes["data-type"]
|
242
|
-
data_value = attributes["data-value"]
|
243
|
-
checked = attributes.has_key?("checked")
|
244
|
-
|
245
|
-
|
246
|
-
notifications.push(note)
|
247
|
-
}
|
248
|
-
return notifications
|
249
|
-
elsif response.not_authorized?
|
250
|
-
raise AuthorizationError
|
251
|
-
else
|
252
|
-
raise CameraNotFoundError
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
def stream
|
259
|
-
Stream.new self
|
260
|
-
end
|
261
100
|
|
262
101
|
end
|
263
102
|
end
|
data/lib/dropcam/clip.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
+
require_relative 'clip_base'
|
2
|
+
|
1
3
|
module Dropcam
|
2
|
-
class Clip
|
4
|
+
class Clip < ClipBase
|
3
5
|
attr_reader :id, :public_link, :description, :title, :is_error, :start_time, :server, :camera_id, :generated_time
|
4
6
|
attr_reader :filename, :length_in_seconds
|
5
7
|
|
6
8
|
attr_accessor :properties
|
7
9
|
def initialize(camera, properties = nil)
|
8
|
-
|
10
|
+
super(camera)
|
9
11
|
self.properties = properties
|
10
12
|
end
|
11
13
|
|
@@ -15,6 +17,18 @@ module Dropcam
|
|
15
17
|
}
|
16
18
|
@properties = properties
|
17
19
|
end
|
20
|
+
|
21
|
+
# def title=(title)
|
22
|
+
# return false unless @id
|
23
|
+
# response = post(::CLIP_DELETE, { "id" => @id, "title" => title }, @camera.cookies)
|
24
|
+
# true
|
25
|
+
# end
|
26
|
+
|
27
|
+
def destroy
|
28
|
+
return false unless @id
|
29
|
+
response = post(::CLIP_DELETE, { "id" => @id }, @camera.cookies)
|
30
|
+
true
|
31
|
+
end
|
18
32
|
|
19
33
|
def direct_link
|
20
34
|
return "https://#{@server}/#{@filename}"
|
@@ -22,31 +36,5 @@ module Dropcam
|
|
22
36
|
def direct_screenshot_link
|
23
37
|
return "https://#{@server}/s3#{File.basename(@filename, File.extname(@filename))}.jpg"
|
24
38
|
end
|
25
|
-
|
26
|
-
def set_title(title)
|
27
|
-
return false unless @id
|
28
|
-
response = post(::CLIP_DELETE, { "id" => @id, "title" => title }, @cookies)
|
29
|
-
if response.success?
|
30
|
-
return true
|
31
|
-
elsif response.not_authorized?
|
32
|
-
raise AuthorizationError
|
33
|
-
else
|
34
|
-
raise CameraNotFoundError
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
|
39
|
-
def delete
|
40
|
-
return false unless @id
|
41
|
-
response = post(::CLIP_DELETE, { "id" => @id }, @cookies)
|
42
|
-
if response.success?
|
43
|
-
return true
|
44
|
-
elsif response.not_authorized?
|
45
|
-
raise AuthorizationError
|
46
|
-
else
|
47
|
-
raise CameraNotFoundError
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
39
|
end
|
52
40
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module Dropcam
|
4
|
+
class ClipArchive < Base
|
5
|
+
|
6
|
+
def initialize(camera)
|
7
|
+
@camera = camera
|
8
|
+
end
|
9
|
+
|
10
|
+
def image_archive(cuepoint_id, number_of_frames, width)
|
11
|
+
clip_with_format(cuepoint_id, number_of_frames, width, "TAR_JPG")
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_mp4(cuepoint_id, number_of_frames, width)
|
15
|
+
clip_with_format(cuepoint_id, number_of_frames, width, "h264")
|
16
|
+
end
|
17
|
+
private
|
18
|
+
def clip_with_format(cuepoint_id, number_of_frames, width, format)
|
19
|
+
params = { "uuid"=>@camera.uuid, "width" => width, "cuepoint_id" => cuepoint_id, "num_frames" => number_of_frames, "format" => format }
|
20
|
+
response = get(::NEXUS_GET_EVENT_CLIP_PATH, params, @camera.cookies, true)
|
21
|
+
response
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
require_relative 'clip_archive'
|
3
|
+
module Dropcam
|
4
|
+
class ClipBase < Base
|
5
|
+
def initialize(camera)
|
6
|
+
@camera = camera
|
7
|
+
end
|
8
|
+
|
9
|
+
def all
|
10
|
+
response = get(::CLIP_GET_ALL,{},@camera.cookies)
|
11
|
+
clips = []
|
12
|
+
all_clips = JSON.parse(response.body)["items"]
|
13
|
+
for clip in all_clips
|
14
|
+
c = Clip.new(@camera, clip)
|
15
|
+
if c.camera_id == @camera.id
|
16
|
+
clips.push c
|
17
|
+
end
|
18
|
+
end
|
19
|
+
clips
|
20
|
+
end
|
21
|
+
|
22
|
+
def archive
|
23
|
+
ClipArchive.new(@camera)
|
24
|
+
end
|
25
|
+
|
26
|
+
def create(length, start_date, title, description)
|
27
|
+
params = {"uuid"=>@camera.uuid, "length" => length, "start_date" => start_date, "title" => title, "description" => description}
|
28
|
+
response = post(::VIDEOS_REQUEST, params, @camera.cookies)
|
29
|
+
clip_info = JSON.parse(response.body)["items"][0]
|
30
|
+
return Clip.new(@camera, clip_info)
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
data/lib/dropcam/cuepoint.rb
CHANGED
@@ -1,11 +1,24 @@
|
|
1
|
+
require_relative 'cuepoint_base'
|
2
|
+
require_relative 'clip_archive'
|
3
|
+
|
1
4
|
module Dropcam
|
2
|
-
class Cuepoint
|
5
|
+
class Cuepoint < CuepointBase
|
3
6
|
attr_reader :id, :note, :type, :time
|
4
|
-
|
7
|
+
|
8
|
+
def initialize(camera,details)
|
9
|
+
super(camera)
|
5
10
|
@id = details["id"]
|
6
11
|
@note = details["note"]
|
7
12
|
@type = details["type"]
|
8
13
|
@time = details["time"]
|
9
14
|
end
|
15
|
+
|
16
|
+
def mp4(number_of_frames, width)
|
17
|
+
ClipArchive.new(@camera).get_mp4(self.id, number_of_frames, width)
|
18
|
+
end
|
19
|
+
|
20
|
+
def image_archive(number_of_frames, width)
|
21
|
+
ClipArchive.new(@camera).image_archive(self.id, number_of_frames, width)
|
22
|
+
end
|
10
23
|
end
|
11
24
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Dropcam
|
2
|
+
class CuepointBase < Base
|
3
|
+
def initialize(camera)
|
4
|
+
@camera = camera
|
5
|
+
end
|
6
|
+
|
7
|
+
def all(limit=2500)
|
8
|
+
params = {"uuid"=>@camera.uuid, "max_results"=>limit}
|
9
|
+
response = get(::NEXUS_GET_REVERSE_PAGINATED_CUEPOINTS_PATH, params, @camera.cookies, true)
|
10
|
+
cuepoints = []
|
11
|
+
all_cuepoints = JSON.parse(response.body)
|
12
|
+
for cuepoint in all_cuepoints
|
13
|
+
cuepoints.push Cuepoint.new(cuepoint)
|
14
|
+
end
|
15
|
+
cuepoints
|
16
|
+
end
|
17
|
+
|
18
|
+
def cuepoint(start_time)
|
19
|
+
params = {"uuid"=>@camera.uuid, "start_time" => start_time}
|
20
|
+
response = get(::NEXUS_GET_CUEPOINT_PATH, params, @camera.cookies, true)
|
21
|
+
Cuepoint.new(JSON.parse(response.body)[0])
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
|
data/lib/dropcam/notification.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
require_relative 'notification_base'
|
2
|
+
|
1
3
|
module Dropcam
|
2
|
-
class Notification <
|
4
|
+
class Notification < NotificationBase
|
3
5
|
|
4
6
|
attr_accessor :name, :type, :value, :is_enabled, :id
|
5
7
|
|
6
8
|
def initialize(camera, properties={})
|
7
|
-
|
9
|
+
super(camera)
|
8
10
|
@name = properties["name"]
|
9
11
|
@type = properties["type"]
|
10
12
|
@value = properties["value"]
|
@@ -15,7 +17,6 @@ module Dropcam
|
|
15
17
|
def find(name)
|
16
18
|
note = @camera.notification_devices.select{|note|
|
17
19
|
if note.name == name
|
18
|
-
puts "#{note.name} == #{name}"
|
19
20
|
return note
|
20
21
|
end
|
21
22
|
}
|
@@ -25,41 +26,19 @@ module Dropcam
|
|
25
26
|
def create(email)
|
26
27
|
# {"status": 400, "items": [], "status_description": "bad-request", "status_detail": "This notification target already exists"}
|
27
28
|
response = post(::CAMERA_ADD_EMAIL_NOTIFICATION, {"email"=>email}, @camera.cookies)
|
28
|
-
|
29
|
-
|
30
|
-
elsif response.error?
|
31
|
-
raise UnkownError, JSON.parse(response.body)["status_detail"]
|
32
|
-
elsif response.not_authorized?
|
33
|
-
raise AuthorizationError
|
34
|
-
else
|
35
|
-
raise CameraNotFoundError
|
36
|
-
end
|
29
|
+
return Notification.new(@camera, JSON.parse(response.body)["items"][0])
|
30
|
+
|
37
31
|
end
|
38
32
|
|
39
33
|
def set(enable)
|
40
34
|
# email or gcm or apn
|
41
35
|
params = {"id"=>@camera.uuid, "is_enabled"=>enable, "device_token" => @value}
|
42
|
-
puts params
|
43
36
|
response = post(::CAMERA_NOTIFICATION_UPDATE, params, @camera.cookies)
|
44
|
-
|
45
|
-
return true
|
46
|
-
elsif response.not_authorized?
|
47
|
-
raise AuthorizationError
|
48
|
-
else
|
49
|
-
raise CameraNotFoundError
|
50
|
-
end
|
37
|
+
true
|
51
38
|
end
|
52
39
|
|
53
|
-
def delete
|
54
|
-
|
55
|
-
response = post(::CAMERA_DELETE_NOTIFICATION, {"id"=>notifcation_id}, @camera.cookies)
|
56
|
-
if response.success?
|
57
|
-
return true
|
58
|
-
elsif response.not_authorized?
|
59
|
-
raise AuthorizationError
|
60
|
-
else
|
61
|
-
raise CameraNotFoundError
|
62
|
-
end
|
40
|
+
def delete
|
41
|
+
super(@id)
|
63
42
|
end
|
64
43
|
|
65
44
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
module Dropcam
|
3
|
+
class NotificationBase < Base
|
4
|
+
|
5
|
+
attr_accessor :name, :type, :value, :is_enabled, :id
|
6
|
+
|
7
|
+
def initialize(camera)
|
8
|
+
@camera = camera
|
9
|
+
end
|
10
|
+
|
11
|
+
def devices
|
12
|
+
|
13
|
+
response = get(::CAMERA_FIND_NOTIFICATIONS, { "id" => @camera.uuid }, @camera.cookies)
|
14
|
+
notifications = []
|
15
|
+
|
16
|
+
all_notifications = JSON.parse(response.body)["items"]
|
17
|
+
all_notifications.each{|note|
|
18
|
+
notifications.push Notification.new(@camera, note["target"])
|
19
|
+
}
|
20
|
+
|
21
|
+
notifications
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete(notifcation_id)
|
25
|
+
response = post(::CAMERA_DELETE_NOTIFICATION, {"id"=>notifcation_id}, @camera.cookies)
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
## API for Notifications doesn't include email notifcations
|
30
|
+
## The code below parses an HTML Partial to get all notifcation values
|
31
|
+
|
32
|
+
# def all_notification_devices
|
33
|
+
# request_path = ::CAMERA_HTML_SETTINGS_BASE + @uuid
|
34
|
+
# response = get(request_path, {}, @cookies)
|
35
|
+
# if response.success?
|
36
|
+
# raw_html = response.body
|
37
|
+
# doc = Hpricot.parse(raw_html)
|
38
|
+
#
|
39
|
+
# notifications = []
|
40
|
+
# doc.search("//div[@class='notification_target']").each { |notification_target|
|
41
|
+
# puts notification_target
|
42
|
+
# data_id = notification_target.get_attribute("data-id")
|
43
|
+
# puts data_id
|
44
|
+
# name = notification_target.at("div/span").inner_text
|
45
|
+
#
|
46
|
+
# input = notification_target.at("div/input")
|
47
|
+
#
|
48
|
+
# attributes = input.attributes.to_hash
|
49
|
+
# data_type = attributes["data-type"]
|
50
|
+
# data_value = attributes["data-value"]
|
51
|
+
# checked = attributes.has_key?("checked")
|
52
|
+
#
|
53
|
+
#
|
54
|
+
# notifications.push(note)
|
55
|
+
# }
|
56
|
+
# return notifications
|
57
|
+
# elsif response.not_authorized?
|
58
|
+
# raise AuthorizationError
|
59
|
+
# else
|
60
|
+
# raise CameraNotFoundError
|
61
|
+
# end
|
62
|
+
# end
|
63
|
+
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
module Dropcam
|
3
|
+
class Screenshot < Base
|
4
|
+
#
|
5
|
+
attr_accessor :camera
|
6
|
+
def initialize(name)
|
7
|
+
@camera = camera
|
8
|
+
@name = name
|
9
|
+
@current_value = value
|
10
|
+
end
|
11
|
+
|
12
|
+
def current(width=1200)
|
13
|
+
return image_at_time(nil, width)
|
14
|
+
end
|
15
|
+
|
16
|
+
def image_at_time(timestamp, width=1200)
|
17
|
+
params = {"uuid"=>@camera.uuid, "width" => width}
|
18
|
+
params["time"] = timestamp if timestamp
|
19
|
+
response = get(::IMAGE_PATH, params, @camera.cookies, true)
|
20
|
+
return response
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
data/lib/dropcam/session.rb
CHANGED
@@ -15,7 +15,7 @@ module Dropcam
|
|
15
15
|
all_cookies = response.get_fields('set-cookie') # only cookies are set on valid credentials
|
16
16
|
|
17
17
|
## for some reason, dropcam responds with 200 on invalid credentials
|
18
|
-
if
|
18
|
+
if all_cookies
|
19
19
|
|
20
20
|
cookies = []
|
21
21
|
all_cookies.each { | cookie |
|
@@ -35,12 +35,8 @@ module Dropcam
|
|
35
35
|
protected
|
36
36
|
def _session_token
|
37
37
|
response = get(::USERS_GET_SESSION_TOKEN, {}, @cookies)
|
38
|
-
|
39
|
-
|
40
|
-
token = response_json["items"][0]
|
41
|
-
return token
|
42
|
-
end
|
43
|
-
return nil
|
38
|
+
token = JSON.parse(response.body)["items"][0]
|
39
|
+
token
|
44
40
|
end
|
45
41
|
|
46
42
|
end
|
data/lib/dropcam/setting.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Dropcam
|
2
2
|
class Setting < Base
|
3
3
|
#
|
4
|
-
attr_accessor :name
|
4
|
+
attr_accessor :name, :camera
|
5
5
|
def initialize(name, value, camera)
|
6
6
|
@camera = camera
|
7
7
|
@name = name
|
@@ -21,17 +21,9 @@ module Dropcam
|
|
21
21
|
|
22
22
|
def set(value)
|
23
23
|
response = post(::DROPCAMS_SET_PROPERTY, {"uuid"=>@camera.uuid, "key" => @name, "value" => value}, @camera.cookies)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
true
|
28
|
-
elsif response.error?
|
29
|
-
raise UnkownError, JSON.parse(response.body)["status_detail"]
|
30
|
-
elsif response.not_authorized?
|
31
|
-
raise AuthorizationError
|
32
|
-
else
|
33
|
-
raise CameraNotFoundError
|
34
|
-
end
|
24
|
+
@current_value = value
|
25
|
+
@camera.settings = JSON.parse(response.body)["items"][0]
|
26
|
+
true
|
35
27
|
end
|
36
28
|
|
37
29
|
end
|
data/lib/dropcam/version.rb
CHANGED
data/lib/dropcam.rb
CHANGED
@@ -21,45 +21,35 @@ module Dropcam
|
|
21
21
|
|
22
22
|
def get_public_camera(token)
|
23
23
|
response = get(::CAMERAS_GET_BY_PUBLIC_TOKEN, {"token"=>token, "return_deleted"=>true}, @session.cookies)
|
24
|
-
|
25
|
-
|
26
|
-
elsif response.not_authorized?
|
27
|
-
raise AuthorizationError
|
28
|
-
else
|
29
|
-
raise CameraNotFoundError
|
30
|
-
end
|
24
|
+
camera = JSON.parse(response.body)["items"][0]
|
25
|
+
Camera.new(camera["uuid"], camera)
|
31
26
|
end
|
32
27
|
|
33
28
|
def public_cameras
|
34
29
|
response = get(::CAMERAS_GET_PUBLIC, {}, @session.cookies)
|
35
|
-
|
36
|
-
|
37
|
-
response_json = JSON.parse(response.body)
|
38
|
-
owned = response_json["items"][0]["owned"]
|
39
|
-
owned.each{|camera|
|
40
|
-
c = Camera.new(camera["uuid"], camera)
|
41
|
-
c.cookies = @session.cookies
|
42
|
-
c.session_token = @session.session_token
|
43
|
-
cameras.push(c)
|
44
|
-
}
|
45
|
-
end
|
46
|
-
return cameras
|
30
|
+
public_cameras = JSON.parse(response.body)["items"]
|
31
|
+
json_to_camera(public_cameras)
|
47
32
|
end
|
48
33
|
|
49
34
|
def cameras
|
50
35
|
response = get(::CAMERAS_GET_VISIBLE, {"group_cameras" => true}, @session.cookies)
|
36
|
+
response_json = JSON.parse(response.body)
|
37
|
+
owned = response_json["items"][0]["owned"]
|
38
|
+
json_to_camera(owned, true)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
def json_to_camera(json, set_session=true)
|
51
43
|
cameras = []
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
}
|
61
|
-
end
|
62
|
-
return cameras
|
44
|
+
|
45
|
+
json.each{|camera|
|
46
|
+
c = Camera.new(camera["uuid"], camera)
|
47
|
+
c.cookies = @session.cookies if set_session
|
48
|
+
c.session_token = @session.session_token if set_session
|
49
|
+
cameras.push(c)
|
50
|
+
}
|
51
|
+
cameras
|
63
52
|
end
|
53
|
+
|
64
54
|
end
|
65
55
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dropcam
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-13 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Access Dropcam account and cameras
|
15
15
|
email:
|
@@ -33,9 +33,14 @@ files:
|
|
33
33
|
- lib/dropcam/base.rb
|
34
34
|
- lib/dropcam/camera.rb
|
35
35
|
- lib/dropcam/clip.rb
|
36
|
+
- lib/dropcam/clip_archive.rb
|
37
|
+
- lib/dropcam/clip_base.rb
|
36
38
|
- lib/dropcam/cuepoint.rb
|
39
|
+
- lib/dropcam/cuepoint_base.rb
|
37
40
|
- lib/dropcam/error.rb
|
38
41
|
- lib/dropcam/notification.rb
|
42
|
+
- lib/dropcam/notification_base.rb
|
43
|
+
- lib/dropcam/screenshot.rb
|
39
44
|
- lib/dropcam/session.rb
|
40
45
|
- lib/dropcam/setting.rb
|
41
46
|
- lib/dropcam/stream.rb
|