ruby_home 0.1.5 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +64 -5
  3. data/bin/rubyhome +4 -4
  4. data/lib/ruby_home/accessory_info.rb +45 -30
  5. data/lib/ruby_home/factories/characteristic_factory.rb +27 -19
  6. data/lib/ruby_home/factories/default_values/float_value.rb +1 -1
  7. data/lib/ruby_home/factories/service_factory.rb +89 -0
  8. data/lib/ruby_home/factories/templates/characteristic_template.rb +6 -2
  9. data/lib/ruby_home/hap/accessory.rb +24 -3
  10. data/lib/ruby_home/hap/accessory_collection.rb +38 -0
  11. data/lib/ruby_home/hap/characteristic.rb +25 -19
  12. data/lib/ruby_home/hap/crypto/session_key.rb +31 -0
  13. data/lib/ruby_home/hap/ev_response.rb +64 -0
  14. data/lib/ruby_home/{http → hap}/hap_request.rb +12 -5
  15. data/lib/ruby_home/{http → hap}/hap_response.rb +7 -4
  16. data/lib/ruby_home/hap/server.rb +81 -0
  17. data/lib/ruby_home/hap/service.rb +11 -15
  18. data/lib/ruby_home/http/application.rb +17 -22
  19. data/lib/ruby_home/http/controllers/application_controller.rb +8 -4
  20. data/lib/ruby_home/http/controllers/characteristics_controller.rb +19 -4
  21. data/lib/ruby_home/http/controllers/pair_verifies_controller.rb +3 -5
  22. data/lib/ruby_home/http/serializers/object_serializer.rb +1 -1
  23. data/lib/ruby_home/http/services/socket_notifier.rb +40 -0
  24. data/lib/ruby_home/http/services/start_srp_service.rb +36 -34
  25. data/lib/ruby_home/http/services/verify_srp_service.rb +55 -53
  26. data/lib/ruby_home/identifier_cache.rb +22 -49
  27. data/lib/ruby_home/persistable.rb +36 -0
  28. data/lib/ruby_home/version.rb +1 -1
  29. data/lib/ruby_home.rb +14 -5
  30. data/rubyhome.gemspec +3 -3
  31. metadata +35 -38
  32. data/lib/ruby_home/factories/accessory_factory.rb +0 -73
  33. data/lib/ruby_home/http/hap_server.rb +0 -60
  34. data/lib/ruby_home/rack/handler/hap_server.rb +0 -21
  35. 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