ruby_home 0.1.5 → 0.1.7
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.
- checksums.yaml +4 -4
- data/README.md +64 -5
- data/bin/rubyhome +4 -4
- data/lib/ruby_home/accessory_info.rb +45 -30
- data/lib/ruby_home/factories/characteristic_factory.rb +27 -19
- data/lib/ruby_home/factories/default_values/float_value.rb +1 -1
- data/lib/ruby_home/factories/service_factory.rb +89 -0
- data/lib/ruby_home/factories/templates/characteristic_template.rb +6 -2
- data/lib/ruby_home/hap/accessory.rb +24 -3
- data/lib/ruby_home/hap/accessory_collection.rb +38 -0
- data/lib/ruby_home/hap/characteristic.rb +25 -19
- data/lib/ruby_home/hap/crypto/session_key.rb +31 -0
- data/lib/ruby_home/hap/ev_response.rb +64 -0
- data/lib/ruby_home/{http → hap}/hap_request.rb +12 -5
- data/lib/ruby_home/{http → hap}/hap_response.rb +7 -4
- data/lib/ruby_home/hap/server.rb +81 -0
- data/lib/ruby_home/hap/service.rb +11 -15
- data/lib/ruby_home/http/application.rb +17 -22
- data/lib/ruby_home/http/controllers/application_controller.rb +8 -4
- data/lib/ruby_home/http/controllers/characteristics_controller.rb +19 -4
- data/lib/ruby_home/http/controllers/pair_verifies_controller.rb +3 -5
- data/lib/ruby_home/http/serializers/object_serializer.rb +1 -1
- data/lib/ruby_home/http/services/socket_notifier.rb +40 -0
- data/lib/ruby_home/http/services/start_srp_service.rb +36 -34
- data/lib/ruby_home/http/services/verify_srp_service.rb +55 -53
- data/lib/ruby_home/identifier_cache.rb +22 -49
- data/lib/ruby_home/persistable.rb +36 -0
- data/lib/ruby_home/version.rb +1 -1
- data/lib/ruby_home.rb +14 -5
- data/rubyhome.gemspec +3 -3
- metadata +35 -38
- data/lib/ruby_home/factories/accessory_factory.rb +0 -73
- data/lib/ruby_home/http/hap_server.rb +0 -60
- data/lib/ruby_home/rack/handler/hap_server.rb +0 -21
- data/lib/ruby_home/yaml_record.rb +0 -440
@@ -1,440 +0,0 @@
|
|
1
|
-
# Original code https://github.com/nicotaing/yaml_record
|
2
|
-
|
3
|
-
require 'active_support'
|
4
|
-
require 'active_support/callbacks'
|
5
|
-
require 'active_support/core_ext/hash'
|
6
|
-
require 'securerandom'
|
7
|
-
require 'yaml'
|
8
|
-
|
9
|
-
module YamlRecord
|
10
|
-
module Adapters
|
11
|
-
class LocalStore
|
12
|
-
|
13
|
-
# Returns YAML File as ruby collection
|
14
|
-
#
|
15
|
-
# === Example:
|
16
|
-
#
|
17
|
-
# @adapter.read("foo") => [{...}, {...}]
|
18
|
-
#
|
19
|
-
def read(source)
|
20
|
-
return false unless File.exists?(source)
|
21
|
-
|
22
|
-
YAML.load_file(source)
|
23
|
-
end
|
24
|
-
|
25
|
-
# Writes ruby collection as YAML File
|
26
|
-
#
|
27
|
-
# === Example:
|
28
|
-
#
|
29
|
-
# @adapter.write("foo", [{...}, {...}]) => "<yaml data>"
|
30
|
-
#
|
31
|
-
def write(source, collection)
|
32
|
-
File.open(source, 'w') {|f| f.write(collection.to_yaml) }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
class Base
|
38
|
-
attr_accessor :attributes, :is_created, :is_destroyed
|
39
|
-
|
40
|
-
include ActiveSupport::Callbacks
|
41
|
-
define_callbacks :before_save, :after_save, :before_destroy, :after_destroy, :before_validation, :before_create, :after_create
|
42
|
-
|
43
|
-
set_callback :before_create, :before, :set_id!
|
44
|
-
|
45
|
-
# Constructs a new YamlRecord instance based on specified attribute hash
|
46
|
-
#
|
47
|
-
# === Example:
|
48
|
-
#
|
49
|
-
# class Post < YamlRecord::Base; properties :foo; end
|
50
|
-
#
|
51
|
-
# Post.new(:foo => "bar")
|
52
|
-
#
|
53
|
-
def initialize(attr_hash={})
|
54
|
-
attr_hash.symbolize_keys!
|
55
|
-
attr_hash.reverse_merge!(self.class.properties.inject({}) { |result, key| result[key] = nil; result })
|
56
|
-
|
57
|
-
self.attributes ||= {}
|
58
|
-
self.is_created = attr_hash.delete(:persisted) || false
|
59
|
-
attr_hash.each do |k,v|
|
60
|
-
self.send("#{k}=", v) # self.attributes[:media] = "foo"
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# Accesses given attribute from YamlRecord instance
|
65
|
-
#
|
66
|
-
# === Example:
|
67
|
-
#
|
68
|
-
# @post[:foo] => "bar"
|
69
|
-
#
|
70
|
-
def [](attribute)
|
71
|
-
self.attributes[attribute]
|
72
|
-
end
|
73
|
-
|
74
|
-
# Assign given attribute from YamlRecord instance with specified value
|
75
|
-
#
|
76
|
-
# === Example:
|
77
|
-
#
|
78
|
-
# @post[:foo] = "baz"
|
79
|
-
#
|
80
|
-
def []=(attribute, value)
|
81
|
-
self.attributes[attribute] = value
|
82
|
-
end
|
83
|
-
|
84
|
-
# Saved YamlRecord instance to file
|
85
|
-
# Executes save and create callbacks
|
86
|
-
# Returns true if record saved; false otherwise
|
87
|
-
#
|
88
|
-
# === Example:
|
89
|
-
#
|
90
|
-
# @post.save => true
|
91
|
-
#
|
92
|
-
def save
|
93
|
-
run_callbacks(:before_save)
|
94
|
-
run_callbacks(:before_create) unless self.is_created
|
95
|
-
|
96
|
-
existing_items = self.class.all
|
97
|
-
if self.new_record?
|
98
|
-
existing_items << self
|
99
|
-
else # update existing record
|
100
|
-
updated_item = existing_items.find { |item| item.id == self.id }
|
101
|
-
return false unless updated_item
|
102
|
-
updated_item.attributes = self.attributes
|
103
|
-
end
|
104
|
-
|
105
|
-
raw_data = existing_items ? existing_items.map { |item| item.persisted_attributes } : []
|
106
|
-
self.class.write_contents(raw_data) if self.valid?
|
107
|
-
|
108
|
-
run_callbacks(:after_create) unless self.is_created
|
109
|
-
run_callbacks(:after_save)
|
110
|
-
true
|
111
|
-
rescue IOError
|
112
|
-
false
|
113
|
-
end
|
114
|
-
|
115
|
-
# Update YamlRecord instance with specified attributes
|
116
|
-
# Returns true if record updated; false otherwise
|
117
|
-
#
|
118
|
-
# === Example:
|
119
|
-
#
|
120
|
-
# @post.update_attributes(:foo => "baz", :miso => "awesome") => true
|
121
|
-
#
|
122
|
-
def update_attributes(updated_attrs={})
|
123
|
-
updated_attrs.each { |k,v| self.send("#{k}=", v) }
|
124
|
-
self.save
|
125
|
-
end
|
126
|
-
|
127
|
-
# Returns array of instance attributes names; An attribute is a value stored for this record (persisted or not)
|
128
|
-
#
|
129
|
-
# === Example:
|
130
|
-
#
|
131
|
-
# @post.column_names => ["foo", "miso"]
|
132
|
-
#
|
133
|
-
def column_names
|
134
|
-
self.attributes.keys.map(&:to_s)
|
135
|
-
end
|
136
|
-
|
137
|
-
# Returns hash of attributes to be persisted to file.
|
138
|
-
# A persisted attribute is a value stored in the file (specified with the properties declaration)
|
139
|
-
#
|
140
|
-
# === Example:
|
141
|
-
#
|
142
|
-
# class Post < YamlRecord::Base; properties :foo, :miso; end
|
143
|
-
# @post = Post.create(:foo => "bar", :miso => "great")
|
144
|
-
# @post.persisted_attributes => { :id => "a1b2c3", :foo => "bar", :miso => "great" }
|
145
|
-
#
|
146
|
-
def persisted_attributes
|
147
|
-
self.attributes.slice(*self.class.properties).reject { |k, v| v.nil? }
|
148
|
-
end
|
149
|
-
|
150
|
-
# Returns true if YamlRecord instance hasn't persisted; false otherwise
|
151
|
-
#
|
152
|
-
# === Example:
|
153
|
-
#
|
154
|
-
# @post = Post.new(:foo => "bar", :miso => "great")
|
155
|
-
# @post.new_record? => true
|
156
|
-
# @post.save => true
|
157
|
-
# @post.new_record? => false
|
158
|
-
#
|
159
|
-
def new_record?
|
160
|
-
!self.is_created
|
161
|
-
end
|
162
|
-
|
163
|
-
# Returns true if YamlRecord instance has been destroyed; false otherwise
|
164
|
-
#
|
165
|
-
# === Example:
|
166
|
-
#
|
167
|
-
# @post = Post.new(:foo => "bar", :miso => "great")
|
168
|
-
# @post.destroyed? => false
|
169
|
-
# @post.save
|
170
|
-
# @post.destroy => true
|
171
|
-
# @post.destroyed? => true
|
172
|
-
#
|
173
|
-
def destroyed?
|
174
|
-
self.is_destroyed
|
175
|
-
end
|
176
|
-
|
177
|
-
# Remove a persisted YamlRecord object
|
178
|
-
# Returns true if destroyed; false otherwise
|
179
|
-
#
|
180
|
-
# === Example:
|
181
|
-
#
|
182
|
-
# @post = Post.create(:foo => "bar", :miso => "great")
|
183
|
-
# Post.all.size => 1
|
184
|
-
# @post.destroy => true
|
185
|
-
# Post.all.size => 0
|
186
|
-
#
|
187
|
-
def destroy
|
188
|
-
run_callbacks(:before_destroy)
|
189
|
-
new_data = self.class.all.reject { |item| item.persisted_attributes == self.persisted_attributes }.map { |item| item.persisted_attributes }
|
190
|
-
self.class.write_contents(new_data)
|
191
|
-
self.is_destroyed = true
|
192
|
-
run_callbacks(:after_destroy)
|
193
|
-
true
|
194
|
-
rescue IOError
|
195
|
-
false
|
196
|
-
end
|
197
|
-
|
198
|
-
# Execute validations for instance
|
199
|
-
# Returns true if record is valid; false otherwise
|
200
|
-
# TODO Implement validation
|
201
|
-
#
|
202
|
-
# === Example:
|
203
|
-
#
|
204
|
-
# @post.valid? => true
|
205
|
-
#
|
206
|
-
def valid?
|
207
|
-
true
|
208
|
-
end
|
209
|
-
|
210
|
-
# Returns errors messages if record isn't valid; empty array otherwise
|
211
|
-
# TODO Implement validation
|
212
|
-
#
|
213
|
-
# === Example:
|
214
|
-
#
|
215
|
-
# @post.errors => ["Foo can't be blank"]
|
216
|
-
#
|
217
|
-
def errors
|
218
|
-
[]
|
219
|
-
end
|
220
|
-
|
221
|
-
# Returns YamlRecord Instance
|
222
|
-
# Complies with ActiveModel api
|
223
|
-
#
|
224
|
-
# === Example:
|
225
|
-
#
|
226
|
-
# @post.to_model => @post
|
227
|
-
#
|
228
|
-
def to_model
|
229
|
-
self
|
230
|
-
end
|
231
|
-
|
232
|
-
# Returns the instance of a record as a parameter
|
233
|
-
# By default return an id
|
234
|
-
#
|
235
|
-
# === Example:
|
236
|
-
#
|
237
|
-
# @post.to_param => <id>
|
238
|
-
#
|
239
|
-
def to_param
|
240
|
-
self.id
|
241
|
-
end
|
242
|
-
|
243
|
-
# Reload YamlRecord instance attributes from file
|
244
|
-
#
|
245
|
-
# === Example:
|
246
|
-
#
|
247
|
-
# @post = Post.create(:foo => "bar", :miso => "great")
|
248
|
-
# @post.foo = "bazz"
|
249
|
-
# @post.reload
|
250
|
-
# @post.foo => "bar"
|
251
|
-
#
|
252
|
-
def reload
|
253
|
-
record = self.class.find(self.id)
|
254
|
-
self.attributes = record.attributes
|
255
|
-
record
|
256
|
-
end
|
257
|
-
|
258
|
-
# Find YamlRecord instance given attribute name and expected value
|
259
|
-
# Supports checking inclusion for array based values
|
260
|
-
# Returns instance if found; false otherwise
|
261
|
-
#
|
262
|
-
# === Example:
|
263
|
-
#
|
264
|
-
# Post.find_by_attribute(:foo, "bar") => @post
|
265
|
-
# Post.find_by_attribute(:some_list, "item") => @post
|
266
|
-
#
|
267
|
-
def self.find_by_attribute(attribute, expected_value)
|
268
|
-
self.all.find do |record|
|
269
|
-
value = record.send(attribute) if record.respond_to?(attribute)
|
270
|
-
value.is_a?(Array) ?
|
271
|
-
value.include?(expected_value) :
|
272
|
-
value == expected_value
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
class << self;
|
277
|
-
|
278
|
-
# Find YamlRecord instance given id
|
279
|
-
# Returns instance if found; false otherwise
|
280
|
-
#
|
281
|
-
# === Example:
|
282
|
-
#
|
283
|
-
# Post.find_by_id("a1b2c3") => @post
|
284
|
-
#
|
285
|
-
def find_by_id(value)
|
286
|
-
self.find_by_attribute(:id, value)
|
287
|
-
end
|
288
|
-
alias :find :find_by_id
|
289
|
-
end
|
290
|
-
|
291
|
-
# Returns collection of all YamlRecord instances
|
292
|
-
# Caches results during request
|
293
|
-
#
|
294
|
-
# === Example:
|
295
|
-
#
|
296
|
-
# Post.all => [@post1, @post2, ...]
|
297
|
-
# Post.all(true) => (...force reload...)
|
298
|
-
#
|
299
|
-
def self.all
|
300
|
-
raw_items = self.adapter.read(self.source) || []
|
301
|
-
raw_items.map { |item| self.new(item.merge(:persisted => true)) }
|
302
|
-
end
|
303
|
-
|
304
|
-
# Find last YamlRecord instance given a limit
|
305
|
-
# Returns an array of instances if found; empty otherwise
|
306
|
-
#
|
307
|
-
# === Example:
|
308
|
-
#
|
309
|
-
# Post.last => @post6
|
310
|
-
# Post.last(3) => [@p4, @p5, @p6]
|
311
|
-
#
|
312
|
-
def self.last(limit=1)
|
313
|
-
limit == 1 ? self.all.last : self.all.last(limit)
|
314
|
-
end
|
315
|
-
|
316
|
-
# Find first YamlRecord instance given a limit
|
317
|
-
# Returns an array of instances if found; empty otherwise
|
318
|
-
#
|
319
|
-
# === Example:
|
320
|
-
#
|
321
|
-
# Post.first => @post
|
322
|
-
# Post.first(3) => [@p1, @p2, @p3]
|
323
|
-
#
|
324
|
-
def self.first(limit=1)
|
325
|
-
limit == 1 ? self.all.first : self.all.first(limit)
|
326
|
-
end
|
327
|
-
|
328
|
-
# Initializes YamlRecord instance given an attribute hash and saves afterwards
|
329
|
-
# Returns instance if successfully saved; false otherwise
|
330
|
-
#
|
331
|
-
# === Example:
|
332
|
-
#
|
333
|
-
# Post.create(:foo => "bar", :miso => "great") => @post
|
334
|
-
#
|
335
|
-
def self.create(attributes={})
|
336
|
-
@fs = self.new(attributes)
|
337
|
-
if @fs.save == true
|
338
|
-
@fs.is_created = true
|
339
|
-
@fs
|
340
|
-
else
|
341
|
-
false
|
342
|
-
end
|
343
|
-
end
|
344
|
-
|
345
|
-
# Declares persisted attributes for YamlRecord class
|
346
|
-
#
|
347
|
-
# === Example:
|
348
|
-
#
|
349
|
-
# class Post < YamlRecord::Base; properties :foo, :miso; end
|
350
|
-
# Post.create(:foo => "bar", :miso => "great") => @post
|
351
|
-
#
|
352
|
-
def self.properties(*names)
|
353
|
-
@_properties ||= []
|
354
|
-
if names.size == 0 # getter
|
355
|
-
@_properties
|
356
|
-
elsif names.size > 0 # setter
|
357
|
-
names = names | [:id]
|
358
|
-
setup_properties!(*names)
|
359
|
-
@_properties += names
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
# Declares or retrieves adapter for Yaml storage
|
364
|
-
# Returns an instance of an adapter
|
365
|
-
#
|
366
|
-
# === Example:
|
367
|
-
#
|
368
|
-
# class Post < YamlRecord::Base
|
369
|
-
# adapter :redis, @redis # => YamlRecord::Adapters::RedisAdapter
|
370
|
-
# end
|
371
|
-
#
|
372
|
-
def self.adapter(kind=nil, *options)
|
373
|
-
kind.nil? ? @_adapter_kind ||= :local : @_adapter_kind = kind
|
374
|
-
@_adapter ||= eval("YamlRecord::Adapters::#{@_adapter_kind.to_s.capitalize}Store").new(*options)
|
375
|
-
end
|
376
|
-
|
377
|
-
# Declares source file for YamlRecord class
|
378
|
-
#
|
379
|
-
# === Example:
|
380
|
-
#
|
381
|
-
# class Post < YamlRecord::Base
|
382
|
-
# source "path/to/yaml/file"
|
383
|
-
# end
|
384
|
-
#
|
385
|
-
def self.source(file=nil)
|
386
|
-
file ? @file = (file.to_s) : @file
|
387
|
-
end
|
388
|
-
|
389
|
-
# Overrides equality to match if matching ids
|
390
|
-
#
|
391
|
-
def ==(comparison_record)
|
392
|
-
self.id == comparison_record.id
|
393
|
-
end
|
394
|
-
|
395
|
-
protected
|
396
|
-
|
397
|
-
# Validates each persisted attributes
|
398
|
-
# TODO Implement validation
|
399
|
-
#
|
400
|
-
def self.validates_each(*args, &block)
|
401
|
-
true
|
402
|
-
end
|
403
|
-
|
404
|
-
# Write raw yaml data to file
|
405
|
-
# Protected method, not called during usage
|
406
|
-
#
|
407
|
-
# === Example:
|
408
|
-
#
|
409
|
-
# Post.write_content([{ :foo => "bar"}, { :foo => "baz"}, ...]) # writes to source file
|
410
|
-
#
|
411
|
-
def self.write_contents(raw_data)
|
412
|
-
self.adapter.write(self.source, raw_data)
|
413
|
-
@records = nil
|
414
|
-
end
|
415
|
-
|
416
|
-
# Creates reader and writer methods for each persisted attribute
|
417
|
-
# Protected method, not called during usage
|
418
|
-
#
|
419
|
-
# === Example:
|
420
|
-
#
|
421
|
-
# Post.setup_properties!(:foo)
|
422
|
-
# @post.foo = "baz"
|
423
|
-
# @post.foo => "baz"
|
424
|
-
#
|
425
|
-
def self.setup_properties!(*names)
|
426
|
-
names.each do |name|
|
427
|
-
define_method(name) { self[name.to_sym] }
|
428
|
-
define_method("#{name}=") { |val| self[name.to_sym] = val }
|
429
|
-
end
|
430
|
-
end
|
431
|
-
|
432
|
-
# Assign YamlRecord a unique id if not set
|
433
|
-
# Invoke before create of an instance
|
434
|
-
# Protected method, not called during usage
|
435
|
-
#
|
436
|
-
def set_id!
|
437
|
-
self.id = SecureRandom.hex(15)
|
438
|
-
end
|
439
|
-
end
|
440
|
-
end
|