jacs 0.2 → 0.3

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.
@@ -8,6 +8,30 @@ A super-simple way to establish a client-server system using Jabber/XMPP. The pr
8
8
 
9
9
  gem install jacs
10
10
 
11
+ === Example
12
+
13
+ Server code would look like:
14
+
15
+ require 'rubygems'
16
+ require 'jacs'
17
+
18
+ class JabberServer < ActionJabber::Base
19
+ route '/users' do
20
+ return ['John Smith', 'Jane Doe']
21
+ end
22
+ end
23
+ server = ActionJabber::Server.new('username@host', 'password', JabberServer)
24
+ server.run!
25
+
26
+ Client code would look like:
27
+
28
+ require 'rubygems'
29
+ require 'jacs'
30
+
31
+ class JabberClient < ActiveJabber::Base; end
32
+ client = JabberClient.new('username@host', 'password')
33
+ users = client.users!
34
+
11
35
  === Copyright
12
36
 
13
37
  Copyright (c) 2010 Dirk Gadsden. See LICENSE for details.
@@ -2,9 +2,12 @@ module ActionJabber
2
2
  class Base
3
3
  class << self
4
4
  @@routes = []
5
+ # Used in the controller definition to create routes.
6
+ # route '/users' do; end
5
7
  def route(path, opts = {}, &block)
6
8
  @@routes << [path, opts, block]
7
9
  end
10
+ # Called by the backend to route a request and return a response. Calling this manually is not recommended.
8
11
  def route!(request)
9
12
  @@request = request
10
13
  @@routes.each do |route|
@@ -14,19 +17,19 @@ module ActionJabber
14
17
  end
15
18
  end
16
19
  end
20
+ # Returns the current request.
17
21
  def request
18
22
  @@request
19
23
  end
20
- def reset!
21
- @@request = nil
22
- end
23
24
  end
24
25
  end
25
26
  class Server
27
+ # Sets up the server. The @controller@ argument is expected to be a class, not an instance.
26
28
  def initialize(username, password, controller)
27
29
  @jabber = Jabber::Simple.new(username, password)
28
30
  @controller = controller # Should be a class.
29
31
  end
32
+ # Initiates the loop to check for new messages.
30
33
  def run!
31
34
  while @jabber.connected?
32
35
  @jabber.received_messages do |message|
@@ -53,6 +56,7 @@ module ActionJabber
53
56
  end
54
57
  end
55
58
  end
59
+ # Handles actually sending response data to the client.
56
60
  def respond_to(request, opts = {})
57
61
  from = request.from
58
62
  status = opts[:status] or 200
@@ -67,6 +71,7 @@ module ActionJabber
67
71
  class Request
68
72
  attr_reader :hash, :format, :from, :path, :args
69
73
 
74
+ # Sets up the request object.
70
75
  def initialize(hash, from, path, args)
71
76
  @hash = hash
72
77
  @from = from
@@ -1,5 +1,6 @@
1
1
  module ActiveJabber
2
2
  class Base
3
+ # Returns memoizes and returns a Jabber object, will try to reconnect if disconnected.
3
4
  def jabber
4
5
  if @jabber
5
6
  if @jabber.connected?
@@ -16,19 +17,18 @@ module ActiveJabber
16
17
  @username = username
17
18
  @password = password
18
19
  end
20
+ # Used to initiate the smart chaining logic.
19
21
  def method_missing(method, *args)
20
22
  request_parts = []
21
23
  Base::Request.new(self, nil, request_parts).send(method, *args)
22
24
  end
25
+ # Sends a request to the client, path should be formatted like "/users" and @opts@ may include a @:args@ (a string) and @:timeout@ (in seconds) keys.
23
26
  def request(path, opts)
24
27
  hash = self.generate_hash
25
28
  message = hash + ':' + path.gsub(/\?$/, '')
26
29
  if opts[:args]
27
30
  message += ('?' + opts[:args])
28
31
  end
29
- unless opts[:timeout]
30
- opts[:timeout] = 5.0
31
- end
32
32
 
33
33
  self.jabber.deliver(Jabber::JID.new('accounts@madelike.com'), message)
34
34
  start = Time.now
@@ -50,6 +50,7 @@ module ActiveJabber
50
50
  return {:status => 408, :data => '', :latency => (Time.now - start)} # Request timeout
51
51
  end
52
52
  end
53
+ # Creates a random hash used to uniquely identify each method.
53
54
  def generate_hash
54
55
  ActiveSupport::SecureRandom.hex(8) # Generates 16 character hexdecimal string.
55
56
  end
@@ -64,6 +65,7 @@ module ActiveJabber
64
65
  @parts << ('/' + part.to_s)
65
66
  end
66
67
  end
68
+ # Determines if this is a known format.
67
69
  def parse_format(method)
68
70
  if method.to_s == 'json' or method.to_s == 'json?'
69
71
  :json
@@ -71,34 +73,32 @@ module ActiveJabber
71
73
  :text
72
74
  end
73
75
  end
76
+ # The chainable magic happens here.
74
77
  def method_missing(method, *args)
75
78
  if args.length > 0 or self.parse_format(method) or method.to_s.ends_with? '!'
76
79
  format = self.parse_format(method)
77
80
  opts = {
78
81
  :format => (format or :text),
79
- :args => ''
82
+ :args => '',
83
+ :timeout => 5.0
80
84
  }
81
- if (args.second.is_a? Hash or args.second.nil?) and format == :json
82
- if args.first
83
- opts[:args] = (args.first.is_a?(String) ? args.first : args.first.to_json)
85
+ if args.length > 1
86
+ # TODO: Logic to handle other ways of transforming data into a sendable format.
87
+ if args.first.respond_to? :to_s
88
+ opts[:args] = args.first.to_s
84
89
  end
85
- if args.second
90
+ if args.second.is_a? Hash
86
91
  opts.merge! args.second
87
92
  end
88
93
  elsif args.first.is_a? Hash
89
94
  opts.merge! args.first
90
- elsif args.first.respond_to? :to_s
91
- opts[:args] = args.first.to_s
92
- if args.second.is_a? Hash
93
- opts.merge! args.second
94
- end
95
95
  end
96
+ # TODO: Support more formats.
96
97
  if format == :json
97
98
  @parts << '.json'
98
99
  else
99
- @parts << ('/' + method.to_s.gsub(/!$/, ''))
100
+ @parts << ('/' + method.to_s.gsub(/[?!]$/, ''))
100
101
  end
101
-
102
102
  @base.request(@parts.join(''), opts)
103
103
  else
104
104
  Request.new(@base, method, @parts)
metadata CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- version: "0.2"
7
+ - 3
8
+ version: "0.3"
9
9
  platform: ruby
10
10
  authors:
11
11
  - Dirk Gadsden