remotedroid 0.4.1 → 0.5.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd7b7c4614e48123ecdc155abc68d996445d62d997df99dc65fe2969b9260c79
4
- data.tar.gz: a4de25cf022d6bdaacc221f9b986a0244e1ea8b5faad38f151713825417b004c
3
+ metadata.gz: ffd9a9a0c4d6d86dcf23408d9345c0a57bef2b6a516b8effcce7dc4b2b8bb0d3
4
+ data.tar.gz: e752e40ee31bf64505e84dc7c2e49a45f61185d3e2573dfb1f4b73526c8a5cb5
5
5
  SHA512:
6
- metadata.gz: 0467d4f2441f460e6428ba1457637643fc707ec1f6c4aeb66e15f7d8cc75f2fec4284915d3b5f0bd3ea1b7fc9818305ed4a54b00fc07913ec5d01746b73d1ad4
7
- data.tar.gz: 385c2c1d6b7a78954eadf6c01d03382cfe16986ac27c218fc1a8ac01e2350d814df6de0909bd0c084e1e36cc53398cd974bc9c49537dc24f51ea9d98621f5067
6
+ metadata.gz: '090b89b8e66c0b6368015741e4db9b9344f6714c96f393efaa40a0a019f467fd04b078a716ae2a9ca2af6e687ea328eccbf67e1d87eee0a278281b34d72e0394'
7
+ data.tar.gz: ed2ca4e908800cb5f88c34d5352cde163168959d994bf82c66a3f90b0e5bc187ccc6b73c9afcf24cd6fbe00fb52a668c3b2d5b29a09410f7ac7eb9614c401a79
@@ -1,4 +1 @@
1
- ?���,���l
2
- �"�=r�Kg�PD��^j�4md�Ε=ψ����!�p+�,q��No8&Bѕ�Q�x;�eAx���z��+���L=tUP�_���֑ʇOi.�� mBG��|�~Ey
3
- y������Y/�]���3!]�����]�m��8�ۛ�a�P��D���u���g�] ������~*Y����)���̊��J���E��_y��%�G���h �.g��Vs�XF�QU����G,�Ƣ�hQ~) �c\��l���f5��W�פ�o�!Ղ P W/��Y�"���w�����i�d2�v������\��U6 �5�!�F\{eл�u�W�#hT��Y���<zk�W�D
4
- p�p\�o'+��.�j(��J
1
+ bB2�۰)�x��6=˕8aؖ��G ��$o!�ӏ�y��I��r��-���Ɂ�^X%9G��Ǚʑ��8�U�/�=Q�xZ햠څ[[�iQmN^��Pw ��N�|��A,o��a}�^W��� ]��l\�����@.PQ6�CߗU;��Ri��'�c�� �%��b8'�pt JL��WpL�ʬe
data.tar.gz.sig CHANGED
Binary file
@@ -8,20 +8,48 @@ require 'app-routes'
8
8
  require 'sps-sub'
9
9
  require 'ruby-macrodroid'
10
10
 
11
+ # PASTE_START
11
12
 
12
13
  # Here's what's available so far:
13
14
  #
14
15
  # # Triggers
15
16
  #
17
+ # ## Battery/Power
18
+ #
19
+ # * Power button toggle
20
+ #
21
+ # ## Connectivity
22
+ #
23
+ # ### Wifi State Change
24
+ #
25
+ # * Connected to Network
26
+ #
27
+ # ## Device Events
28
+ #
29
+ # * screen on
30
+ #
16
31
  # ## Sensors
17
- #
32
+ #
33
+ # * Activity Recognition
18
34
  # * proximity (near)
19
35
  # * shake device
20
36
  #
37
+ # ## User Input
38
+ #
39
+ # * Swipe Screen
40
+ #
21
41
  # ------------------------------------
22
42
  #
23
43
  # # Actions
24
44
  #
45
+ # ## Camera/Photo
46
+ #
47
+ # * Take Picture
48
+ #
49
+ # ## Connectivity
50
+ #
51
+ # * Enable HotSpot
52
+ #
25
53
  # ## Date/Time
26
54
  #
27
55
  # * Say Current Time
@@ -36,6 +64,10 @@ require 'ruby-macrodroid'
36
64
  #
37
65
  # * Share Location
38
66
  #
67
+ # ## MacroDroid specific
68
+ #
69
+ # * Disable Macro
70
+ #
39
71
  # ## Media
40
72
  #
41
73
  # * Play sound (Doda)
@@ -46,6 +78,7 @@ require 'ruby-macrodroid'
46
78
  #
47
79
  # ## Screen
48
80
  #
81
+ # * Keep Device Awake
49
82
  # * Screen On
50
83
  #
51
84
 
@@ -137,7 +170,33 @@ a:
137
170
  Else
138
171
  Screen Off
139
172
  End If
140
-
173
+
174
+ m: Hotspot
175
+ v: enable: false
176
+ t: WebHook
177
+ a:
178
+ If enable = True
179
+ Enable Hotspot
180
+ Else
181
+ Disable Hotspot
182
+ End If
183
+
184
+ m: Take Picture
185
+ t: webhook
186
+ a:
187
+ Take Picture
188
+ Rear Facing
189
+ a: wait 2 seconds
190
+ a: webhook
191
+
192
+ m: stay awake
193
+ t: webhook
194
+ a: stay awake
195
+
196
+ m: stay awake off
197
+ t: webhook
198
+ a: stay awake off
199
+
141
200
  m: Share location
142
201
  t:
143
202
  WebHook
@@ -150,7 +209,16 @@ a:
150
209
  HTTP GET
151
210
  identifier: location
152
211
  coords: [lv=coords]
212
+ cell: [cell_id]
213
+ ssid: [ssid]
214
+ alt: [last_loc_alt]
215
+ time: [last_loc_age_timestamp]
216
+ mph: [last_loc_speed_mph]
217
+ kph: [last_loc_speed_kmh]
218
+ device: [device_model]
219
+ battery: [battery]
153
220
  type: query
221
+
154
222
 
155
223
  m: query
156
224
  t: WebHook
@@ -207,559 +275,103 @@ a:
207
275
  m: Power connected
208
276
  t: Power Connected: Any
209
277
  a: webhook
210
-
211
-
212
- EOF
213
278
 
214
- =begin
215
- m: Screen
216
- v: on: true
217
- t: WebHook
218
- a:
219
- If on = true
220
- Screen On
221
- Else
222
- Screen Off
223
- End If
224
-
225
- =end
226
-
227
- module RemoteDroid
228
-
229
- class Model
230
- include AppRoutes
231
-
232
- def initialize(obj=nil, root: 'device1', debug: false)
233
-
234
- super()
235
- @root, @debug = root, debug
236
- @location = nil
237
-
238
- if obj then
239
-
240
- s = obj.strip
241
-
242
- puts 's: ' + s.inspect if @debug
243
-
244
- if s[0] == '<' or s.lines[1][0..1] == ' ' then
245
-
246
- puts 'before easydom' if @debug
247
-
248
- s2 = if s.lines[1][0..1] == ' ' then
249
-
250
- lines = s.lines.map do |line|
251
- line.sub(/(\w+) +is +(\w+)$/) {|x| "#{$1} {switch: #{$2}}" }
252
- end
253
-
254
- lines.join
255
-
256
- else
257
- s
258
- end
259
-
260
- @ed = EasyDom.new(s2)
261
- else
262
- build(s, root: root)
263
- end
264
-
265
- end
266
-
267
- end
268
-
269
- def build(raw_requests, root: @root)
270
-
271
- @ed = EasyDom.new(debug: false, root: root)
272
- raw_requests.lines.each {|line| request(line) }
273
-
274
- end
275
-
276
-
277
- def get_thing(h)
278
-
279
- h[:thing].gsub!(/ /,'_')
280
-
281
- if not h.has_key? :location then
282
- location = false
283
- h[:location] = find_path(h[:thing])
284
- else
285
- location = true
286
- end
287
-
288
- puts 'h: ' + h.inspect if @debug
289
-
290
- a = []
291
- a += h[:location].split(/ /)
292
- a << h[:thing]
293
- status = a.inject(@ed) {|r,x| r.send(x)}.send(h[:action])
294
-
295
- if location then
296
- "The %s %s is %s." % [h[:location], h[:thing], status]
297
- else
298
- "%s is %s." % [h[:thing].capitalize, status]
299
- end
300
-
301
- end
302
-
303
- # Object Property (op)
304
- # Helpful for accessing properites in dot notation
305
- # e.g. op.livingroom.light.switch = 'off'
306
- #
307
- def op()
308
- @ed
309
- end
310
-
311
- def query(s)
312
- @ed.e.element(s)
313
- end
314
-
315
- # request accepts a string in plain english
316
- # e.g. request 'switch the livingroom light on'
317
- #
318
- def request(s)
319
-
320
- params = {request: s}
321
- requests(params)
322
- h = find_request(s)
323
-
324
- method(h.first[-1]).call(h).gsub(/_/,' ')
325
-
326
- end
327
-
328
- def set_thing(h)
329
-
330
- h[:thing].gsub!(/ /,'_')
331
- h[:location] = find_path(h[:thing]) unless h.has_key? :location
332
-
333
- a = []
334
- a += h[:location].split(/ /)
335
- a << h[:thing]
336
-
337
- a.inject(@ed) {|r,x| r.send(x)}.send(h[:action], h[:value])
338
-
339
- end
340
-
341
- def to_sliml(level: 0)
342
-
343
- s = @ed.to_sliml
344
-
345
- return s if level.to_i > 0
346
-
347
- lines = s.lines.map do |line|
348
-
349
- line.sub(/\{[^\}]+\}/) do |x|
350
-
351
- a = x.scan(/\w+: +[^ ]+/)
352
- if a.length == 1 and x[/switch:/] then
353
-
354
- val = x[/(?<=switch: ) *["']([^"']+)/,1]
355
- 'is ' + val
356
- else
357
- x
358
- end
359
-
360
- end
361
- end
362
-
363
- lines.join
364
-
365
- end
366
-
367
- def to_xml(options=nil)
368
- @ed.xml(pretty: true).gsub(' style=\'\'','')
369
- end
370
-
371
- alias xml to_xml
372
-
373
- # to_xml() is the preferred method
374
-
375
- protected
376
-
377
- def requests(params)
378
-
379
- # e.g. switch the livingroom gas_fire off
380
- #
381
- get /(?:switch|turn) the ([^ ]+) +([^ ]+) +(on|off)$/ do |location, device, onoff|
382
- {type: :set_thing, action: 'switch=', location: location, thing: device, value: onoff}
383
- end
384
-
385
- # e.g. switch the gas _fire off
386
- #
387
- get /(?:switch|turn) the ([^ ]+) +(on|off)$/ do |device, onoff|
388
- {type: :set_thing, action: 'switch=', thing: device, value: onoff}
389
- end
390
-
391
- # e.g. is the livingroom gas_fire on?
392
- #
393
- get /is the ([^ ]+) +([^ ]+) +(?:on|off)\??$/ do |location, device|
394
- {type: :get_thing, action: 'switch', location: location, thing: device}
395
- end
396
-
397
- # e.g. enable airplane mode
398
- #
399
- get /((?:dis|en)able) ([^$]+)$/ do |state, service|
400
- {type: :set_thing, action: 'switch=', thing: service, value: state + 'd'}
401
- end
402
-
403
- # e.g. switch airplane mode off
404
- #
405
- get /switch (.*) (on|off)/ do |service, rawstate|
406
-
407
- state = rawstate == 'on' ? 'enabled' : 'disabled'
408
- {type: :set_thing, action: 'switch=', thing: service, value: state}
409
-
410
- end
411
-
412
- # e.g. is airplane mode enabed?
413
- #
414
- get /is (.*) +(?:(?:dis|en)abled)\??$/ do |service|
415
- {type: :get_thing, action: 'switch', thing: service.gsub(/ /,'_')}
416
- end
417
-
418
- # e.g. is the gas_fire on?
419
- #
420
- get /is the ([^ ]+) +(?:on|off)\??$/ do |device|
421
- location = find_path(device)
422
- {type: :get_thing, action: 'switch', location: location, thing: device}
423
- end
424
-
425
- # e.g. fetch the livingroom temperature reading
426
- #
427
- get /fetch the ([^ ]+) +([^ ]+) +(?:reading)$/ do |location, device|
428
- {type: :get_thing, action: 'reading', location: location, thing: device}
429
- end
430
-
431
- # e.g. fetch the temperature reading
432
- #
433
- get /fetch the ([^ ]+) +(?:reading)$/ do |device|
434
- location = find_path(device)
435
- {type: :get_thing, action: 'reading', location: location, thing: device}
436
- end
279
+ m: screen on off
280
+ t: screen on
281
+ a: webhook
437
282
 
438
- end
439
-
440
- private
441
-
442
- def find_path(s)
443
- puts 'find_path s: ' + s.inspect if @debug
444
- found = query('//'+ s)
445
- return unless found
446
- a = found.backtrack.to_xpath.split('/')
447
- a[1..-2].join(' ')
448
- end
449
-
450
- alias find_request run_route
283
+ m: Power Button Toggle3
284
+ t: Power Button Toggle (3)
285
+ a: webhook
451
286
 
452
- end
287
+ m: Power Button Toggle4
288
+ t: Power Button Toggle (4)
289
+ a: webhook
453
290
 
454
- class Controller
455
-
456
- attr_reader :model, :control
457
- attr_accessor :title, :macros, :store
291
+ m: Power Button Toggle5
292
+ t: Power Button Toggle (5)
293
+ a: webhook
458
294
 
459
- def initialize(mcs, model=MODEL, deviceid: nil, debug: false)
460
-
461
- @debug = debug
462
- @syslog = []
463
-
464
- @control = Control.new(deviceid)
465
- @macros = mcs.macros
466
-
467
- if model then
468
- @model = Model.new(model)
469
- end
470
-
471
- @store = {}
472
- @query = Query.new(self)
295
+ m: Connected to network
296
+ t:
297
+ Connected to network
298
+ Any Network
299
+ a: wait 2 seconds
300
+ a:
301
+ webhook
302
+ ssid: [ssid]
303
+
304
+ m: In Vehicle
305
+ t:
306
+ Activity - In Vehicle
307
+ Confidence >= 50%
308
+ a: webhook
309
+
310
+ m: On Bicycle
311
+ t:
312
+ Activity - On Bicycle
313
+ Confidence >= 50%
314
+ a: webhook
473
315
 
474
- end
475
-
476
- def export(s)
477
- @macros = MacroDroid.new(s).macros
478
- end
479
-
480
- def invoke(name, options={})
481
-
482
- if @control.respond_to? name.to_sym then
483
- @control.method(name.to_sym).call(options)
484
- else
485
- @control.http_exec name.to_sym, options
486
- end
487
- end
316
+ m: Running
317
+ t:
318
+ Activity - Running
319
+ Confidence >= 50%
320
+ a: webhook
488
321
 
489
- # Object Property (op)
490
- # Helpful for accessing properites in dot notation
491
- # e.g. op.livingroom.light.switch = 'off'
492
- #
493
- def op()
494
- @model.op
495
- end
496
-
497
- def query(id=nil)
498
-
499
- return @query unless id
500
-
501
- @store[id] = nil
322
+ m: Walking
323
+ t:
324
+ Activity - Walking
325
+ Confidence >= 50%
326
+ a: webhook
502
327
 
503
- sys = %i(accelerometer_rotation)
504
-
505
- global = [:airplane_mode_on, :bluetooth_on, :cell_on, :device_name, \
506
- :usb_mass_storage_enabled, :wifi_on]
507
-
508
- secure = %i(bluetooth_name flashlight_enabled)
328
+ m: Still
329
+ t:
330
+ Activity - Still
331
+ Confidence >= 83%
332
+ a: webhook
509
333
 
510
-
511
- # send http request via macrodroid.com API
512
-
513
- if id.downcase.to_sym == :location then
514
- @control.http_exec id
515
- elsif sys.include? id
516
- @control.http_exec :'query-setting-system', {qvar: id}
517
- elsif global.include? id
518
- @control.http_exec :'query-setting-global', {qvar: id}
519
- elsif secure.include? id
520
- @control.http_exec :'query-setting-secure', {qvar: id}
521
- else
522
- @control.http_exec :query, {qvar: id}
523
- end
524
-
525
- # wait for the local variable to be updated
526
- # timeout after 5 seoncds
527
- t = Time.now
528
-
529
- begin
530
- sleep 1
531
- end until @store[id] or Time.now > t + 5
532
-
533
- return {warning: 'HTTP response timeout'} if Time.now > t+5
534
-
535
- return @store[id]
334
+ m: Swipe top left across
335
+ t:
336
+ Swipe Screen
337
+ Top Left - Across
338
+ a: webhook
536
339
 
537
-
538
- end
539
-
540
- def request(s)
541
- @model.request s
542
- end
543
-
544
-
545
- def trigger(name, detail={time: Time.now})
546
-
547
- macros = @macros.select do |macro|
548
-
549
- puts 'macro: ' + macro.inspect if @debug
340
+ m: Swipe top left diagonal
341
+ t:
342
+ Swipe Screen
343
+ Top Left - Diagonal
344
+ a: webhook
550
345
 
551
- # fetch the associated properties from the model if possible and
552
- # merge them into the detail.
553
- #
554
- valid_trigger = macro.match?(name, detail, @model.op)
555
-
556
- puts 'valid_trigger: ' + valid_trigger.inspect if @debug
557
-
558
- if valid_trigger then
559
- @syslog << [Time.now, :trigger, name]
560
- @syslog << [Time.now, :macro, macro.title]
561
- end
562
-
563
- valid_trigger
564
-
565
- end
566
-
567
- puts 'macros: ' + macros.inspect if @debug
568
-
569
- macros.flat_map(&:run)
570
- end
571
-
572
- alias trigger_fired trigger
573
-
574
- def update(id, val)
575
- key = id == :location ? id : val.keys.first.to_sym
576
- @store[key] = val
577
- end
578
-
346
+ m: Swipe top left down
347
+ t:
348
+ Swipe Screen
349
+ Top Left - Down
350
+ a: webhook
579
351
 
580
- end
352
+ m: Swipe top right across
353
+ t:
354
+ Swipe Screen
355
+ Top Right - Across
356
+ a: webhook
581
357
 
582
- class Service
583
- def initialize(callback)
584
- @callback = callback
585
- end
586
- end
587
-
588
- class Bluetooth
589
- def enable()
590
- end
591
- end
592
-
593
- class Toast < Service
594
-
595
- def invoke()
596
- @callback.call :toast
597
- end
598
-
599
- end
600
-
601
- class Torch < Service
602
-
603
- def toggle()
604
- @callback.http_exec :torch
605
- end
606
-
607
- end
608
-
609
- class ControlHelper
610
-
611
- def initialize(callback)
612
- @callback
613
- end
614
- end
358
+ m: Swipe top right diagonal
359
+ t:
360
+ Swipe Screen
361
+ Top Right - Diagonal
362
+ a: webhook
615
363
 
616
- class Control
617
-
618
- def initialize(dev=nil, deviceid: dev, remote_url: nil, debug: false)
619
-
620
- @deviceid, @remote_url, @debug = deviceid, remote_url, debug
621
- @torch = Torch.new(self)
622
- end
623
-
624
- def bluetooth()
625
- @bluetooth
626
- end
627
-
628
- def camera_flash_light(options={})
629
- http_exec 'camera-flash-light', options
630
- end
631
-
632
- def http_exec(command, options={})
633
-
634
- url = "https://trigger.macrodroid.com/%s/%s" % [@deviceid, command]
635
-
636
- if options and options.any? then
637
- h = options
638
- url += '?' + \
639
- URI.escape(h.map {|key,value| "%s=%s" % [key, value]}.join('&'))
640
- end
641
-
642
- s = open(url).read
643
-
644
- end
645
-
646
- def location(options={})
647
- http_exec 'location'
648
- end
649
-
650
- def say_current_time(options={})
651
- http_exec 'say-current-time'
652
- end
653
-
654
- alias say_time say_current_time
655
-
656
- def screen(state=nil)
657
-
658
- if state then
659
- http_exec 'screen', {on: state == :on}
660
- else
661
-
662
- def self.on()
663
- http_exec 'screen', {on: true}
664
- end
665
-
666
- def self.off()
667
- http_exec 'screen', {on: false}
668
- end
669
-
670
- self
671
-
672
- end
673
- end
674
-
675
- def share_location(options={})
676
- http_exec 'share-location'
677
- end
678
-
679
- def speak_text(obj)
680
-
681
- options = case obj
682
- when String
683
- {text: obj}
684
- when Hash
685
- obj
686
- end
687
-
688
- http_exec 'speak-text', options
689
- end
690
-
691
- alias say speak_text
692
-
693
- def toast(options={})
694
- http_exec :toast, options
695
- end
696
-
697
- def torch(options={})
698
- http_exec :torch
699
- end
700
-
701
- def vibrate(options={})
702
- http_exec :vibrate
703
- end
364
+ m: Swipe top right down
365
+ t:
366
+ Swipe Screen
367
+ Top Right - Down
368
+ a: webhook
704
369
 
705
370
 
706
- def write(s)
707
-
708
- MacroDroid.new(RD_MACROS, deviceid: @deviceid,
709
- remote_url: @remote_url, debug: @debug).export s
710
-
711
- end
712
-
713
- alias export write
714
-
715
- def method_missing2(method_name, *args)
716
- http_exec(method_name, args.first)
717
- end
718
-
719
- end
720
-
721
- class Query
722
-
723
- def initialize(callback)
724
- @callback = callback
725
- end
726
-
727
- def airplane_mode_enabled?()
728
- q(:airplane_mode_on).to_i > 0
729
- end
730
-
731
- def battery()
732
- q(:battery).to_i
733
- end
734
-
735
- def current_brightness()
736
- q(:current_brightness).to_i
737
- end
371
+ EOF
738
372
 
739
- alias brightness current_brightness
740
-
741
- def cell_id()
742
- q(:cell_id)
743
- end
744
-
745
- alias cell_tower cell_id
746
-
747
- def ip()
748
- q(:ip)
749
- end
750
-
751
- def location()
752
- @callback.query(:location)[:coords]
753
- end
754
373
 
755
-
756
- private
757
-
758
- def q(id)
759
- @callback.query(id)[id]
760
- end
761
-
762
- end
374
+ module RemoteDroid
763
375
 
764
376
  class Server
765
377
 
@@ -776,88 +388,7 @@ module RemoteDroid
776
388
  end
777
389
 
778
390
  end
779
-
780
- class Client
781
-
782
- def initialize(host='127.0.0.1')
783
- @drb = OneDrb::Client.new host: host, port: '5777'
784
- end
785
-
786
- def control
787
- @drb.control
788
- end
789
-
790
- def export(s)
791
- @drb.export(s)
792
- end
793
-
794
- def invoke(s, *args)
795
- @drb.invoke(s, *args)
796
- end
797
-
798
- def query(id=nil)
799
-
800
- return @drb.query unless id
801
- t = Time.now
802
- h = @drb.query(id)
803
- h.merge({latency: (Time.now - t).round(3)})
804
-
805
- end
806
-
807
- def update(key, val)
808
- @drb.update key.to_sym, val
809
- end
810
-
811
- def store()
812
- @drb.store
813
- end
814
-
815
- # -- helpful methods -----------------
816
-
817
- def battery()
818
- query.battery
819
- end
820
-
821
- def cell_tower()
822
- query.cell_tower
823
- end
824
-
825
- def location()
826
- query.location
827
- end
828
-
829
- def say(text)
830
- control.say text
831
- end
832
391
 
833
- def say_time()
834
- control.say_time
835
- end
836
-
837
- alias saytime say_time
838
-
839
- def screen(state=nil)
840
- control.screen state
841
- end
842
-
843
- def screen_on()
844
- screen :on
845
- end
846
-
847
- def screen_off()
848
- screen :off
849
- end
850
-
851
- def torch()
852
- control.torch
853
- end
854
-
855
- def vibrate
856
- control.vibrate
857
- end
858
-
859
- end
860
-
861
392
  class TriggerSubscriber < SPSSub
862
393
 
863
394
  def initialize(host: 'sps.home', drb_host: '127.0.0.1')
@@ -913,6 +444,7 @@ module RemoteDroid
913
444
  super(topic: topic) do |msg|
914
445
 
915
446
  json, id = msg.split(/:\s+/,2).reverse
447
+
916
448
  h = JSON.parse(json, symbolize_names: true)
917
449
  id ||= h.keys.first
918
450
  @remote.update id.to_sym, h
@@ -923,3 +455,12 @@ module RemoteDroid
923
455
 
924
456
  end
925
457
  end
458
+
459
+ # PASTE_END
460
+
461
+
462
+ require 'remotedroid/model'
463
+ require 'remotedroid/query'
464
+ require 'remotedroid/control'
465
+ require 'remotedroid/controller'
466
+ require 'remotedroid/client'