jacs 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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