pkoch-switchboard 0.1.1a

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 +73 -0
  3. data/Rakefile +30 -0
  4. data/bin/switchboard +34 -0
  5. data/examples/echo_bot.rb +7 -0
  6. data/lib/switchboard.rb +1 -0
  7. data/lib/switchboard/client.rb +105 -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 +41 -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 +53 -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 +307 -0
  54. data/lib/switchboard/ext/delegate.rb +21 -0
  55. data/lib/switchboard/ext/instance_exec.rb +18 -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 +8 -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 +16 -0
  70. metadata +147 -0
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ == 0.1.0 2009-07-08
2
+
3
+ * Initial RubyForge release (Seth)
data/README.markdown ADDED
@@ -0,0 +1,73 @@
1
+ # Switchboard
2
+
3
+ Switchboard is both a toolkit for assembling XMPP clients as well as a set of
4
+ command-line tools for interacting with XMPP servers.
5
+
6
+ ## Docs
7
+
8
+ * [switchboard : XMPP :: curl :
9
+ HTTP](http://mojodna.net/2009/07/16/switchboard-curl-for-xmpp.html) -
10
+ command-line usage
11
+ * [Switchboard as a
12
+ Framework](http://mojodna.net/2009/07/19/switchboard-as-a-framework.html)
13
+ * [Subscribing to Wordpress.com with
14
+ Switchboard](http://mojodna.net/2009/07/21/subscribing-to-wordpress-com-with-switchboard.html)
15
+
16
+ ## Mailing List
17
+
18
+ [Switchboard Google Group](http://groups.google.com/group/switchboard)
19
+
20
+ ## Getting Started
21
+
22
+ Install it:
23
+
24
+ $ sudo gem install switchboard
25
+
26
+ Install optional dependencies for additional functionality.
27
+
28
+ OAuth PubSub support:
29
+
30
+ $ sudo gem install oauth
31
+
32
+ User Location (XEP-0080) support via Fire Eagle:
33
+
34
+ $ sudo gem install mojodna-fire-hydrant -s http://gems.github.com
35
+
36
+ _Note: you will need to set up a PubSub subscription to your location via Fire
37
+ Eagle for this to work._
38
+
39
+ User Tune (XEP-0118) support via iTunes (on Mac OS X):
40
+
41
+ $ sudo gem install rb-appscript
42
+
43
+ Configure it:
44
+
45
+ $ switchboard config jid jid@example.com
46
+ $ switchboard config password pa55word
47
+
48
+ _Settings will be stored in `$HOME/.switchboardrc`_
49
+
50
+ Run it:
51
+
52
+ $ switchboard <command> <args>
53
+ $ switchboard roster list
54
+ $ switchboard roster add fireeagle.com
55
+ $ ...
56
+
57
+ Subscribe to a node using OAuth, overriding default settings:
58
+
59
+ $ switchboard --jid subscriber@example.com --password pa55word \
60
+ pubsub --oauth \
61
+ --oauth-consumer-key <consumer key> \
62
+ --oauth-consumer-secret <consumer secret> \
63
+ --oauth-token <token> \
64
+ --oauth-token-secret <token secret> \
65
+ --server fireeagle.com \
66
+ --node "/api/0.1/user/<token>" \
67
+ subscribe
68
+
69
+ Publish iTunes' current track using User Tune (XEP-0118):
70
+
71
+ $ switchboard --resource switchtunes pep tune
72
+
73
+ _You can do this using a JID that is already online._
data/Rakefile ADDED
@@ -0,0 +1,30 @@
1
+ require File.join("lib", "switchboard", "version")
2
+
3
+ desc "Generate the gemspec"
4
+ task :gemspec do
5
+ gemspec =<<-EOF
6
+ # this file is automatically generated
7
+ Gem::Specification.new do |s|
8
+ s.name = "switchboard"
9
+ s.version = "#{Switchboard::VERSION * "."}"
10
+ s.summary = "XMPP toolkit."
11
+ s.description = "A toolkit for assembling XMPP clients and interacting with XMPP servers."
12
+ s.authors = ["Seth Fitzsimmons", "Paulo Köch"]
13
+ s.email = ["seth@mojodna.net", "paulo.koch@gmail.com"]
14
+
15
+ s.files = #{Dir.glob("**/*").select { |f| File.file?(f) }.inspect}
16
+ s.executables = ["switchboard"]
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency("xmpp4r", [">= 0.5"])
20
+ end
21
+ EOF
22
+
23
+ open("switchboard.gemspec", "w") do |f|
24
+ f << gemspec
25
+ end
26
+
27
+ puts "gemspec successfully created."
28
+ end
29
+
30
+ task :default => :gemspec
data/bin/switchboard ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby -rubygems
2
+ require 'switchboard'
3
+ require 'switchboard/commands'
4
+ require 'optparse'
5
+
6
+ ARGV.clone.options do |opts|
7
+ # opts.banner = "Usage: example.rb [options]"
8
+
9
+ command = Switchboard::Commands::Default
10
+ command.options(opts)
11
+
12
+ cmd = []
13
+ argv = []
14
+
15
+ # force optparse into being a command parser
16
+ opts.order! do |arg|
17
+ cmd << arg
18
+
19
+ if c = Switchboard::COMMANDS[cmd * "_"]
20
+ command = c
21
+ command.options(opts)
22
+ elsif c = Switchboard::COMMANDS["_" + cmd * "_"]
23
+ command = c
24
+ else
25
+ # unrecognized, unclaimed argument; keep as ARGV
26
+ argv << arg
27
+ end
28
+ end
29
+
30
+ # correct ARGV to match unrecognized, unclaimed arguments
31
+ ARGV.reject! { |v| !argv.include?(v) }
32
+
33
+ command
34
+ end.run!
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby -rubygems
2
+
3
+ require 'switchboard'
4
+
5
+ switchboard = Switchboard::Client.new
6
+ switchboard.plug!(AutoAcceptJack, EchoJack, NotifyJack)
7
+ switchboard.run!
@@ -0,0 +1 @@
1
+ require 'switchboard/switchboard'
@@ -0,0 +1,105 @@
1
+ module Switchboard
2
+ class Client < Core
3
+ attr_reader :client, :roster, :jid
4
+
5
+ def initialize(settings = Switchboard::Settings.new, spin = true)
6
+ super(settings, spin)
7
+
8
+ # create a new JID (one should always be provided, even if it's just the
9
+ # domain component)
10
+ @jid = Jabber::JID.new(settings["jid"])
11
+
12
+ # override the resource if one was provided
13
+ @jid.resource = settings["resource"] if settings["resource"]
14
+
15
+ # instantiate the client
16
+ @client = Jabber::Client.new(@jid)
17
+
18
+ on_stream_connected do
19
+ register_roster_callbacks
20
+
21
+ # tell others that we're online
22
+ presence
23
+
24
+ defer :roster_loaded do
25
+ # wait for the roster to load
26
+ roster.wait_for_roster
27
+
28
+ # roster has now been loaded
29
+ on(:roster_loaded)
30
+ end
31
+ end
32
+ end
33
+
34
+ hook \
35
+ :roster_presence, :roster_query, :roster_subscription,
36
+ :roster_subscription_request, :roster_loaded, :roster_update
37
+
38
+ protected
39
+
40
+ def auth!
41
+ if (jid.node.nil? || settings["anonymous"]) && client.supports_anonymous?
42
+ # no node (user) component in the JID, be anonymous
43
+
44
+ client.auth_anonymous
45
+ else
46
+ client.auth(settings["password"])
47
+ end
48
+ @roster = Jabber::Roster::Helper.new(client)
49
+ rescue Jabber::ClientAuthenticationFailure => e
50
+ puts "Could not authenticate as #{settings["jid"]}"
51
+ shutdown(false)
52
+ exit 1
53
+ end
54
+
55
+ def connect!
56
+ client.connect
57
+ auth!
58
+ end
59
+
60
+ def disconnect!
61
+ presence(:unavailable)
62
+ super
63
+ end
64
+
65
+ def presence(status = nil, to = nil)
66
+ presence = Jabber::Presence.new(nil, status)
67
+ presence.to = to
68
+ client.send(presence)
69
+ end
70
+
71
+ def register_roster_callbacks
72
+ # presence from someone on my roster
73
+ roster.add_presence_callback do |item, old_presence, new_presence|
74
+ on(:roster_presence, item, old_presence, new_presence)
75
+ end
76
+
77
+ # roster query completed (rarely used)
78
+ roster.add_query_callback do |query|
79
+ on(:roster_query, query)
80
+ end
81
+
82
+ # roster subscription
83
+ roster.add_subscription_callback do |item, presence|
84
+ # confirmation that we were able to subscribe to someone else
85
+ on(:roster_subscription, item, presence)
86
+ end
87
+
88
+ roster.add_subscription_request_callback do |item, presence|
89
+ # someone wants to subscribe to me!
90
+ on(:roster_subscription_request, item, presence)
91
+ end
92
+
93
+ # roster was updated (rarely used)
94
+ roster.add_update_callback do |old_item, new_item|
95
+ # roster has been updated; don't care
96
+ # puts "update: #{old_item.inspect}, #{new_item.inspect}"
97
+ on(:roster_update, old_item, new_item)
98
+ end
99
+ end
100
+
101
+ def stream
102
+ client
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,10 @@
1
+ class String
2
+ def red; colorize(self, "\e[1m\e[31m"); end
3
+ def green; colorize(self, "\e[1m\e[32m"); end
4
+ def dark_green; colorize(self, "\e[32m"); end
5
+ def yellow; colorize(self, "\e[1m\e[33m"); end
6
+ def blue; colorize(self, "\e[1m\e[34m"); end
7
+ def dark_blue; colorize(self, "\e[34m"); end
8
+ def purple; colorize(self, "\e[1m\e[35m"); end
9
+ def colorize(text, color_code) "#{color_code}#{text}\e[0m" end
10
+ end
@@ -0,0 +1,12 @@
1
+ require 'switchboard/commands/command'
2
+ require 'switchboard/commands/config'
3
+ require 'switchboard/commands/default'
4
+ require 'switchboard/commands/disco'
5
+ require 'switchboard/commands/grep'
6
+ require 'switchboard/commands/help'
7
+ require 'switchboard/commands/last'
8
+ require 'switchboard/commands/pep'
9
+ require 'switchboard/commands/pubsub'
10
+ require 'switchboard/commands/register'
11
+ require 'switchboard/commands/roster'
12
+ require 'switchboard/commands/unregister'
@@ -0,0 +1,85 @@
1
+ module Switchboard
2
+ COMMANDS = {}
3
+
4
+ def self.commands(command = nil)
5
+ if command
6
+ COMMANDS.select { |k,v| k =~ /^#{command.to_command_name("_")}_/ }
7
+ else
8
+ COMMANDS.reject { |k,v| k =~ /_/ }
9
+ end
10
+ end
11
+
12
+ def self.hide_command(command)
13
+ COMMANDS["_#{command.to_command_name("_")}"] = unregister_command(command)
14
+ end
15
+
16
+ def self.register_command(command)
17
+ COMMANDS[command.to_command_name("_")] = command
18
+ end
19
+
20
+ def self.unregister_command(command)
21
+ COMMANDS.delete(command.to_command_name("_"))
22
+ end
23
+
24
+
25
+ module Commands
26
+ end
27
+
28
+ class Command
29
+ def self.description(description = nil)
30
+ @description = description if description
31
+ @description
32
+ end
33
+
34
+ def self.help
35
+ "No help is available for this command (#{self.to_command_name})."
36
+ end
37
+
38
+ # TODO consider accepting a block in subclasses
39
+ def self.options(opts)
40
+ @options = opts
41
+ @options.banner = "Usage: #{opts.program_name} [options] #{self.to_command_name} [options] [args]"
42
+ @options
43
+ end
44
+
45
+ def self.run!
46
+ puts self.options(OptionParser.new).help
47
+ commands = Switchboard.commands(self)
48
+
49
+ if commands.any?
50
+ puts
51
+ puts "Available commands:"
52
+ commands.each do |name, command|
53
+ puts " #{command.to_command.ljust(15)}#{command.description}"
54
+ command.options(OptionParser.new).summarize do |line|
55
+ puts " " * 16 + line
56
+ end
57
+ end
58
+ puts
59
+ puts "See '#{@options.program_name} help COMMAND' for more information on a specific command."
60
+ end
61
+ end
62
+
63
+ def self.to_command
64
+ self.name.gsub("Switchboard::Commands::", "").split("::").last.downcase
65
+ end
66
+
67
+ def self.to_command_name(delimiter = " ")
68
+ self.name.gsub("Switchboard::Commands::", "").split("::").map { |c| c.downcase } * delimiter
69
+ end
70
+
71
+ private
72
+
73
+ def self.hide!
74
+ Switchboard.hide_command(self)
75
+ end
76
+
77
+ def self.inherited(klass)
78
+ Switchboard.register_command(klass) if klass.name =~ /^Switchboard::Commands/
79
+ end
80
+
81
+ def self.unregister!
82
+ Switchboard.unregister_command(self)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1 @@
1
+ require 'switchboard/commands/config/config'
@@ -0,0 +1,20 @@
1
+ module Switchboard
2
+ module Commands
3
+ class Config < Switchboard::Command
4
+ description "Get and set global options"
5
+
6
+ def self.run!
7
+ settings = Switchboard::Settings.new
8
+ if ARGV.empty?
9
+ super
10
+ elsif ARGV.length == 1
11
+ puts settings.get(ARGV.shift)
12
+ elsif ARGV.length == 2
13
+ settings.set!(ARGV.shift, ARGV.shift)
14
+ else
15
+ puts "error: More than one value for the key #{ARGV.shift}: #{ARGV * " "}"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,41 @@
1
+ module Switchboard
2
+ module Commands
3
+ class Default < Switchboard::Command
4
+ unregister!
5
+
6
+ def self.options(opts)
7
+ super(opts)
8
+
9
+ opts.banner = "Usage: #{opts.program_name} [options] COMMAND [options] [args]"
10
+
11
+ opts.on("-a", "--anonymous", "Connect anonymously.") { OPTIONS["anonymous"] = true }
12
+ # opts.on("-d", "--daemon", "Make server run as a daemon.") { OPTIONS["detach"] = true }
13
+ opts.on("-j", "--jid=jid", String, "Specifies the JID to use.") { |v| OPTIONS["jid"] = v }
14
+ opts.on("-r", "--resource=resource", String, "Specifies the resource to use.") { |v| OPTIONS["resource"] = v }
15
+ opts.on("-p", "--password=password", String, "Specifies the password to use.") { |v| OPTIONS["password"] = v }
16
+ # opts.on("-p", "--pidfile=path", String,
17
+ # "Specifies a pidfile to use.") { |v| OPTIONS[:pidfile] = v }
18
+ # opts.on("-v", "--[no-]verbose", "Run verbosely") { |v| OPTIONS[:verbose] = v }
19
+
20
+ opts.separator ""
21
+
22
+ opts.on_tail("-h", "--help", "Show this help message.") { puts opts; exit }
23
+ opts.on_tail("--version", "Show version.") { puts "switchboard version #{Switchboard::VERSION * "."}"; exit }
24
+ end
25
+
26
+ def self.run!
27
+ puts self.options(OptionParser.new).help
28
+ puts
29
+ puts "Available commands:"
30
+ Switchboard.commands.each do |name, command|
31
+ puts " #{command.to_command.ljust(15)}#{command.description}"
32
+ command.options(OptionParser.new).summarize do |line|
33
+ puts " " * 16 + line
34
+ end
35
+ end
36
+ puts
37
+ puts "See '#{@options.program_name} help COMMAND' for more information on a specific command."
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ require 'switchboard/commands/disco/disco'
2
+ require 'switchboard/commands/disco/items'
3
+ require 'switchboard/commands/disco/info'