switchboard 0.1.0

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.
Files changed (70) hide show
  1. data/History.txt +3 -0
  2. data/README.markdown +59 -0
  3. data/Rakefile +30 -0
  4. data/bin/switchboard +35 -0
  5. data/examples/echo_bot.rb +7 -0
  6. data/lib/switchboard.rb +1 -0
  7. data/lib/switchboard/client.rb +92 -0
  8. data/lib/switchboard/colors.rb +10 -0
  9. data/lib/switchboard/commands.rb +12 -0
  10. data/lib/switchboard/commands/command.rb +85 -0
  11. data/lib/switchboard/commands/config.rb +1 -0
  12. data/lib/switchboard/commands/config/config.rb +20 -0
  13. data/lib/switchboard/commands/default.rb +40 -0
  14. data/lib/switchboard/commands/disco.rb +3 -0
  15. data/lib/switchboard/commands/disco/disco.rb +13 -0
  16. data/lib/switchboard/commands/disco/info.rb +39 -0
  17. data/lib/switchboard/commands/disco/items.rb +30 -0
  18. data/lib/switchboard/commands/grep.rb +23 -0
  19. data/lib/switchboard/commands/help.rb +1 -0
  20. data/lib/switchboard/commands/help/help.rb +15 -0
  21. data/lib/switchboard/commands/last.rb +1 -0
  22. data/lib/switchboard/commands/last/last.rb +34 -0
  23. data/lib/switchboard/commands/pep.rb +3 -0
  24. data/lib/switchboard/commands/pep/location.rb +97 -0
  25. data/lib/switchboard/commands/pep/pep.rb +7 -0
  26. data/lib/switchboard/commands/pep/tune.rb +85 -0
  27. data/lib/switchboard/commands/pubsub.rb +16 -0
  28. data/lib/switchboard/commands/pubsub/affiliations.rb +34 -0
  29. data/lib/switchboard/commands/pubsub/config.rb +42 -0
  30. data/lib/switchboard/commands/pubsub/create.rb +41 -0
  31. data/lib/switchboard/commands/pubsub/delete.rb +32 -0
  32. data/lib/switchboard/commands/pubsub/info.rb +48 -0
  33. data/lib/switchboard/commands/pubsub/items.rb +40 -0
  34. data/lib/switchboard/commands/pubsub/listen.rb +20 -0
  35. data/lib/switchboard/commands/pubsub/nodes.rb +37 -0
  36. data/lib/switchboard/commands/pubsub/options.rb +40 -0
  37. data/lib/switchboard/commands/pubsub/publish.rb +44 -0
  38. data/lib/switchboard/commands/pubsub/pubsub.rb +25 -0
  39. data/lib/switchboard/commands/pubsub/purge.rb +32 -0
  40. data/lib/switchboard/commands/pubsub/retract.rb +38 -0
  41. data/lib/switchboard/commands/pubsub/subscribe.rb +34 -0
  42. data/lib/switchboard/commands/pubsub/subscriptions.rb +35 -0
  43. data/lib/switchboard/commands/pubsub/unsubscribe.rb +30 -0
  44. data/lib/switchboard/commands/register.rb +40 -0
  45. data/lib/switchboard/commands/roster.rb +5 -0
  46. data/lib/switchboard/commands/roster/add.rb +27 -0
  47. data/lib/switchboard/commands/roster/list.rb +26 -0
  48. data/lib/switchboard/commands/roster/online.rb +28 -0
  49. data/lib/switchboard/commands/roster/remove.rb +25 -0
  50. data/lib/switchboard/commands/roster/roster.rb +7 -0
  51. data/lib/switchboard/commands/unregister.rb +21 -0
  52. data/lib/switchboard/component.rb +36 -0
  53. data/lib/switchboard/core.rb +311 -0
  54. data/lib/switchboard/ext/delegate.rb +21 -0
  55. data/lib/switchboard/ext/instance_exec.rb +16 -0
  56. data/lib/switchboard/helpers/oauth_pubsub.rb +44 -0
  57. data/lib/switchboard/helpers/pubsub.rb +28 -0
  58. data/lib/switchboard/jacks.rb +7 -0
  59. data/lib/switchboard/jacks/auto_accept.rb +16 -0
  60. data/lib/switchboard/jacks/debug.rb +17 -0
  61. data/lib/switchboard/jacks/echo.rb +7 -0
  62. data/lib/switchboard/jacks/notify.rb +15 -0
  63. data/lib/switchboard/jacks/oauth_pubsub.rb +23 -0
  64. data/lib/switchboard/jacks/pubsub.rb +21 -0
  65. data/lib/switchboard/jacks/roster_debug.rb +23 -0
  66. data/lib/switchboard/settings.rb +49 -0
  67. data/lib/switchboard/switchboard.rb +12 -0
  68. data/lib/switchboard/version.rb +3 -0
  69. data/switchboard.gemspec +15 -0
  70. metadata +136 -0
@@ -0,0 +1,30 @@
1
+ require 'xmpp4r/discovery'
2
+
3
+ module Switchboard
4
+ module Commands
5
+ class Disco
6
+ class Items < Switchboard::Command
7
+ description "Item discovery"
8
+
9
+ def self.run!
10
+ switchboard = Switchboard::Client.new do
11
+ helper = Jabber::Discovery::Helper.new(client)
12
+ resp = helper.get_items_for(settings["disco.target"], settings["disco.node"])
13
+
14
+ if resp.items.any?
15
+ puts "Item Discovery for #{settings["disco.target"]}#{settings["disco.node"] ? " (#{settings["disco.node"]})" : ""}"
16
+ resp.items.each do |item|
17
+ name = "#{item.iname}#{item.node ? " (#{item.node})" : ""}"
18
+ puts " " + [item.jid, name].reject { |x| x == "" } * ": "
19
+ end
20
+ else
21
+ puts "No items were discoverable for #{settings["disco.target"]}."
22
+ end
23
+ end
24
+
25
+ switchboard.run!
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ module Switchboard
2
+ module Commands
3
+ class Grep < Switchboard::Command
4
+ description "Search for an XPath expression"
5
+
6
+ def self.run!
7
+ expr = ARGV.pop
8
+
9
+ switchboard = Switchboard::Client.new
10
+ switchboard.plug!(AutoAcceptJack, NotifyJack)
11
+
12
+ switchboard.on_stanza do |stanza|
13
+ # TODO doesn't handle default namespaces properly
14
+ REXML::XPath.each(stanza, expr) do |el|
15
+ puts el.to_s
16
+ end
17
+ end
18
+
19
+ switchboard.run!
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1 @@
1
+ require 'switchboard/commands/help/help'
@@ -0,0 +1,15 @@
1
+ module Switchboard
2
+ module Commands
3
+ class Help < Switchboard::Command
4
+ hide!
5
+
6
+ def self.run!
7
+ if ARGV.any?
8
+ puts Switchboard::COMMANDS[ARGV * "_"].help
9
+ else
10
+ Switchboard::Commands::Default.run!
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1 @@
1
+ require 'switchboard/commands/last/last'
@@ -0,0 +1,34 @@
1
+ require 'xmpp4r/last'
2
+
3
+ module Switchboard
4
+ module Commands
5
+ class Last < Switchboard::Command
6
+ description "Last Activity (XEP-0012)"
7
+
8
+ def self.options(opts)
9
+ super(opts)
10
+ opts.on("--target=target", String, "Specifies the target to query.") { |v| OPTIONS["last.target"] = v }
11
+ end
12
+
13
+ def self.run!
14
+ switchboard = Switchboard::Client.new do
15
+ helper = Jabber::LastActivity::Helper.new(client)
16
+ resp = helper.get_last_activity_from(jid = Jabber::JID.new(settings["last.target"]))
17
+
18
+ status = " (#{resp.status})" if resp.status
19
+ status ||= ""
20
+
21
+ if jid.resource
22
+ puts "#{jid} idle: #{resp.seconds} seconds" << status
23
+ elsif jid.node
24
+ puts "#{jid} last disconnected: " << (Time.new - resp.seconds).to_s << status
25
+ else
26
+ puts "#{jid} uptime: #{resp.seconds} seconds" << status
27
+ end
28
+ end
29
+
30
+ switchboard.run!
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ require 'switchboard/commands/pep/pep'
2
+ require 'switchboard/commands/pep/location'
3
+ require 'switchboard/commands/pep/tune'
@@ -0,0 +1,97 @@
1
+ require 'xmpp4r/location'
2
+
3
+ module Switchboard
4
+ module Commands
5
+ class PEP
6
+ class Location < Switchboard::Command
7
+ description "Broadcasting UserLocation (XEP-0080)"
8
+
9
+ def self.run!
10
+ begin
11
+ require 'fire_hydrant'
12
+ rescue LoadError => e
13
+ lib = e.message.split("--").last.strip
14
+ puts "#{lib} is required for this command to work."
15
+ exit 1
16
+ end
17
+
18
+ # TODO check for at least one Fire Eagle subscription, otherwise this
19
+ # will never broadcast anything.
20
+
21
+ switchboard = Switchboard::Client.new
22
+ switchboard.plug!(AutoAcceptJack, FireEagleJack)
23
+
24
+ switchboard.on_startup do
25
+ @location_helper = Jabber::UserLocation::Helper.new(client, nil)
26
+ end
27
+
28
+ switchboard.on_location_update do |user|
29
+ name = user.locations.first
30
+ timestamp = user.locations.first.located_at
31
+
32
+ area, postalcode, locality, region, country = nil
33
+
34
+ user.locations.each do |loc|
35
+ level = loc.level_name
36
+ normal_name = loc.normal_name
37
+ case level
38
+ when "exact"
39
+ street = normal_name
40
+ when "postal"
41
+ postalcode = normal_name
42
+ when "neighborhood"
43
+ area = normal_name
44
+ when "city"
45
+ locality = normal_name
46
+ when "state"
47
+ region = normal_name
48
+ when "country"
49
+ country = normal_name
50
+ end
51
+ puts "level: #{level}"
52
+ end
53
+
54
+ puts "Current location: #{name}."
55
+
56
+ geom = user.locations[0].geom
57
+ if geom.is_a?(GeoRuby::SimpleFeatures::Envelope)
58
+ pt = geom.center
59
+ accuracy = geom.upper_corner.spherical_distance(geom.lower_corner) / 2
60
+ else
61
+ pt = geom
62
+ accuracy = 0
63
+ end
64
+
65
+ location = Jabber::UserLocation::Location.new \
66
+ "accuracy" => accuracy,
67
+ "area" => area,
68
+ "country" => country,
69
+ "description" => name,
70
+ "lat" => pt.lat,
71
+ "locality" => locality,
72
+ "lon" => pt.lon,
73
+ "postalcode" => postalcode,
74
+ "region" => region,
75
+ "street" => street,
76
+ "timestamp" => timestamp
77
+
78
+ # parsing thread is still running, so the send needs to be deferred
79
+ defer :location_sent do
80
+ @location_helper.current_location(location)
81
+ end
82
+ end
83
+
84
+ switchboard.on_shutdown do
85
+ begin
86
+ @location_helper.stop_publishing
87
+ rescue Jabber::ServerError => e
88
+ puts e
89
+ end
90
+ end
91
+
92
+ switchboard.run!
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,7 @@
1
+ module Switchboard
2
+ module Commands
3
+ class PEP < Switchboard::Command
4
+ description "PEP (XEP-0163) manipulation"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,85 @@
1
+ require 'xmpp4r/tune'
2
+
3
+ module Switchboard
4
+ module Commands
5
+ class PEP
6
+ class Tune < Switchboard::Command
7
+ description "Broadcasting UserTune (XEP-0118)"
8
+
9
+ def self.run!
10
+ begin
11
+ require 'appscript'
12
+ rescue LoadError => e
13
+ lib = e.message.split("--").last.strip
14
+ puts "#{lib} is required for this command to work."
15
+ exit 1
16
+ end
17
+
18
+ switchboard = Switchboard::Client.new do
19
+ @tune_helper = Jabber::UserTune::Helper.new(client, nil)
20
+
21
+ itunes = Appscript.app('iTunes')
22
+ old_track_info = nil
23
+ last_state = :paused
24
+
25
+ while !shutdown?
26
+ track = itunes.current_track.get
27
+ state = itunes.player_state.get
28
+
29
+ if track && state == :playing
30
+
31
+ artist = track.artist.get
32
+ name = track.name.get
33
+ source = track.album.get
34
+ track_info = [artist, name, source]
35
+
36
+ if track_info != old_track_info
37
+ duration = track.duration.get.to_i
38
+ track = track.track_number.get.to_s
39
+
40
+ puts "Now playing: #{name} by #{artist}"
41
+ tune = Jabber::UserTune::Tune.new \
42
+ artist,
43
+ name,
44
+ duration,
45
+ track,
46
+ source
47
+
48
+ begin
49
+ @tune_helper.now_playing(tune)
50
+ rescue Jabber::ServerError => e
51
+ puts e
52
+ end
53
+ end
54
+
55
+ elsif state != last_state
56
+ track_info = nil
57
+ begin
58
+ @tune_helper.stop_playing
59
+ rescue Jabber::ServerError => e
60
+ puts e
61
+ end
62
+ end
63
+
64
+ old_track_info = track_info
65
+ last_state = state
66
+ sleep 1
67
+ end
68
+ end
69
+
70
+ switchboard.on_shutdown do
71
+ begin
72
+ @tune_helper.stop_playing
73
+ rescue Jabber::ServerError => e
74
+ puts e
75
+ end
76
+ end
77
+
78
+ switchboard.plug!(AutoAcceptJack)
79
+
80
+ switchboard.run!
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,16 @@
1
+ require 'switchboard/commands/pubsub/pubsub'
2
+ require 'switchboard/commands/pubsub/affiliations'
3
+ require 'switchboard/commands/pubsub/config'
4
+ require 'switchboard/commands/pubsub/create'
5
+ require 'switchboard/commands/pubsub/delete'
6
+ require 'switchboard/commands/pubsub/info'
7
+ require 'switchboard/commands/pubsub/items'
8
+ require 'switchboard/commands/pubsub/listen'
9
+ require 'switchboard/commands/pubsub/nodes'
10
+ require 'switchboard/commands/pubsub/options'
11
+ require 'switchboard/commands/pubsub/publish'
12
+ require 'switchboard/commands/pubsub/purge'
13
+ require 'switchboard/commands/pubsub/retract'
14
+ require 'switchboard/commands/pubsub/subscribe'
15
+ require 'switchboard/commands/pubsub/subscriptions'
16
+ require 'switchboard/commands/pubsub/unsubscribe'
@@ -0,0 +1,34 @@
1
+ module Switchboard
2
+ module Commands
3
+ class PubSub
4
+ class Affiliations < Switchboard::Command
5
+ description "Lists pubsub affiliations"
6
+
7
+ def self.run!
8
+ switchboard = Switchboard::Client.new do
9
+ defer :affiliations_received do
10
+ pubsub.get_affiliations(OPTIONS["pubsub.node"])
11
+ end
12
+
13
+ def affiliations_received(affiliations)
14
+ if affiliations
15
+ affiliations.each do |node, affiliation|
16
+ puts [node, affiliation] * " => "
17
+ end
18
+ else
19
+ puts "No affiliations."
20
+ end
21
+ end
22
+ end
23
+
24
+ if defined?(OAuth) && OPTIONS["oauth"]
25
+ switchboard.plug!(OAuthPubSubJack)
26
+ else
27
+ switchboard.plug!(PubSubJack)
28
+ end
29
+ switchboard.run!
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,42 @@
1
+ module Switchboard
2
+ module Commands
3
+ class PubSub
4
+ class Config < Switchboard::Command
5
+ description "Gets the configuration for a pubsub node"
6
+
7
+ def self.run!
8
+ switchboard = Switchboard::Client.new do
9
+ defer :configuration_retrieved do
10
+ if ARGV.length == 2
11
+ key, value = ARGV
12
+ puts "Setting '#{key}' to '#{value}'"
13
+ config = Jabber::PubSub::NodeConfig.new(OPTIONS["pubsub.node"], key => value)
14
+ set_config_for(OPTIONS["pubsub.node"], config)
15
+ end
16
+
17
+ get_config_from(OPTIONS["pubsub.node"])
18
+ end
19
+
20
+ def configuration_retrieved(config)
21
+ if config
22
+ puts "Configuration for node '#{config.node}':"
23
+ config.options.each do |k,v|
24
+ puts " " + [k, v] * ": "
25
+ end
26
+ else
27
+ puts "Could not load configuration for node '#{OPTIONS["pubsub.node"]}'."
28
+ end
29
+ end
30
+ end
31
+
32
+ if defined?(OAuth) && OPTIONS["oauth"]
33
+ switchboard.plug!(OAuthPubSubJack)
34
+ else
35
+ switchboard.plug!(PubSubJack)
36
+ end
37
+ switchboard.run!
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,41 @@
1
+ module Switchboard
2
+ module Commands
3
+ class PubSub
4
+ class Create < Switchboard::Command
5
+ description "Creates a pubsub node"
6
+
7
+ def self.options(opts)
8
+ super(opts)
9
+ opts.on("--collection", "Specifies that a 'collection' node should be created.") { |v| OPTIONS["pubsub.create.node_type"] = "collection" }
10
+ end
11
+
12
+ def self.run!
13
+ switchboard = Switchboard::Client.new do
14
+ defer :node_created do
15
+ if OPTIONS["pubsub.create.node_type"] == "collection"
16
+ create_collection_node(OPTIONS["pubsub.node"], nil)
17
+ else
18
+ create_node(OPTIONS["pubsub.node"], nil)
19
+ end
20
+ end
21
+
22
+ def node_created(name)
23
+ if name
24
+ puts "Node '#{name}' was created."
25
+ else
26
+ puts "An auto-named node was created."
27
+ end
28
+ end
29
+ end
30
+
31
+ if defined?(OAuth) && OPTIONS["oauth"]
32
+ switchboard.plug!(OAuthPubSubJack)
33
+ else
34
+ switchboard.plug!(PubSubJack)
35
+ end
36
+ switchboard.run!
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end