ucengine 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +165 -0
- data/README.rdoc +7 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/doc/UCEngine.html +769 -0
- data/doc/UCEngine/Debug.html +179 -0
- data/doc/created.rid +2 -0
- data/doc/images/brick.png +0 -0
- data/doc/images/brick_link.png +0 -0
- data/doc/images/bug.png +0 -0
- data/doc/images/bullet_black.png +0 -0
- data/doc/images/bullet_toggle_minus.png +0 -0
- data/doc/images/bullet_toggle_plus.png +0 -0
- data/doc/images/date.png +0 -0
- data/doc/images/find.png +0 -0
- data/doc/images/loadingAnimation.gif +0 -0
- data/doc/images/macFFBgHack.png +0 -0
- data/doc/images/package.png +0 -0
- data/doc/images/page_green.png +0 -0
- data/doc/images/page_white_text.png +0 -0
- data/doc/images/page_white_width.png +0 -0
- data/doc/images/plugin.png +0 -0
- data/doc/images/ruby.png +0 -0
- data/doc/images/tag_green.png +0 -0
- data/doc/images/wrench.png +0 -0
- data/doc/images/wrench_orange.png +0 -0
- data/doc/images/zoom.png +0 -0
- data/doc/index.html +71 -0
- data/doc/js/darkfish.js +116 -0
- data/doc/js/jquery.js +32 -0
- data/doc/js/quicksearch.js +114 -0
- data/doc/js/thickbox-compressed.js +10 -0
- data/doc/lib/ucengine_rb.html +58 -0
- data/doc/rdoc.css +706 -0
- data/lib/ucengine.rb +192 -0
- data/test/helper.rb +10 -0
- data/test/test_ucengine.rb +7 -0
- data/ucengine.rb.gemspec +57 -0
- metadata +130 -0
data/lib/ucengine.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'cgi'
|
5
|
+
|
6
|
+
# ucengine.rb implements the UCEngine API, it can currently handle
|
7
|
+
# publish/subscribe to any event stream.
|
8
|
+
#
|
9
|
+
# Author:: Victor Goya (victor.goya@af83.com)
|
10
|
+
# Copyright:: Copyright (c) 2010 AF83
|
11
|
+
# License:: LGPL
|
12
|
+
# Website:: http://ucengine.org/
|
13
|
+
|
14
|
+
# This class is the main and only class in ucengine.rb, it handles
|
15
|
+
# connections and request to the UCEngine server.
|
16
|
+
#
|
17
|
+
# uce = UCEngine.new("localhost", 4567)
|
18
|
+
# uce.connect("bibi", :password => 'abcd') do |uce|
|
19
|
+
# uce.subscribe(["af83"], :type => 'chat.message.new', :search => 'HTML5') do |event|
|
20
|
+
# uce.push(:location => [event['org'], event['meeting']]
|
21
|
+
# :from => 'bot',
|
22
|
+
# :type => 'chat.message.new',
|
23
|
+
# :metadata => {"text" => "Hey, you were talking about HTML5"})
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
class UCEngine
|
27
|
+
|
28
|
+
# Print every request and everything above.
|
29
|
+
DEBUG = 0
|
30
|
+
# Print everything that seems fishy.
|
31
|
+
WARNING = 1
|
32
|
+
# Print regular errors, usually HTTP errors.
|
33
|
+
ERROR = 2
|
34
|
+
# Only print critical errors (bad hostname or port, etc).
|
35
|
+
CRITICAL = 3
|
36
|
+
# Don't print anything (default).
|
37
|
+
QUIET = 4
|
38
|
+
|
39
|
+
# Create a new UCEngine object. 'host' is the hostname of the UCEngine server
|
40
|
+
# and 'port' is to TCP port to connect to. Note that this method doesn't create
|
41
|
+
# a new connection, see the #connect method.
|
42
|
+
# An additional 'debug' parameter set the debug level of the library, all the
|
43
|
+
# debug information are written in the error output.
|
44
|
+
def initialize(host, port, debug = UCEngine::QUIET)
|
45
|
+
@host = host
|
46
|
+
@port = port
|
47
|
+
@http = Net::HTTP.new(host, port)
|
48
|
+
@threads = []
|
49
|
+
@debug = debug
|
50
|
+
debug(UCEngine::DEBUG, "Initialisation complete for #{host}:#{port}.")
|
51
|
+
end
|
52
|
+
|
53
|
+
# Connect to the UCEngine server with the User ID 'uid' and the its credential.
|
54
|
+
#
|
55
|
+
#
|
56
|
+
# uce = UCEngine.new("localhost", 4567)
|
57
|
+
# uce.connect("bibi", :password => 'abcd') do |uce|
|
58
|
+
# ... your code goes here
|
59
|
+
# end
|
60
|
+
#
|
61
|
+
# It is currently possible to use :token or :password as authentification method.
|
62
|
+
def connect(uid, credential)
|
63
|
+
@uid = uid
|
64
|
+
response = put("/presence/#{@uid}", {:auth => 'token', :credential => credential[:token]})
|
65
|
+
@sid = response['result']
|
66
|
+
debug(UCEngine::DEBUG, "Authentification complete for #{@uid}/#{@sid}.")
|
67
|
+
yield self
|
68
|
+
@threads.each do |thread|
|
69
|
+
thread.join
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Subscribe to an event stream. The 'location' parameter is where you're expecting
|
74
|
+
# the events to come:
|
75
|
+
# * ["organisation", "meeting"]: events from a specific meeting.
|
76
|
+
# * ["organisation"]: events from all meetings of the organisation and for the organisation itself.
|
77
|
+
# * []: all events.
|
78
|
+
#
|
79
|
+
# The function takes extra parameters:
|
80
|
+
# :type => the type of event (ex. 'chat.message.new', 'internal.user.add', etc).
|
81
|
+
# :from => the origin of the message, the value is an uid.
|
82
|
+
# :parent => the id of the the parent event.
|
83
|
+
# :search => list of keywords that match the metadata of the returned events
|
84
|
+
#
|
85
|
+
#
|
86
|
+
# uce.subscribe(["af83"], :type => 'internal.meeting.add', :search => 'HTML5') do |event|
|
87
|
+
# puts "A new meeting about HTML5 was created"
|
88
|
+
# end
|
89
|
+
def subscribe(location, params = {})
|
90
|
+
debug(UCEngine::DEBUG, "Subscribe to #{location} with #{params}.")
|
91
|
+
@threads << Thread.new do
|
92
|
+
Net::HTTP.start(@host, @port) do |http|
|
93
|
+
params[:_async] = "lp"
|
94
|
+
params[:start] = 0 if !params[:start]
|
95
|
+
while true
|
96
|
+
begin
|
97
|
+
events = get("/event/#{location.join("/")}", params, http)['result']
|
98
|
+
rescue Timeout::Error
|
99
|
+
debug(UCEngine::WARNING, "Subscribe timeout ... retry")
|
100
|
+
retry
|
101
|
+
rescue EOFError
|
102
|
+
debug(UCEngine::WARNING, "Subscribe closed ... retry")
|
103
|
+
sleep 10
|
104
|
+
retry
|
105
|
+
end
|
106
|
+
events.each do |event|
|
107
|
+
yield event
|
108
|
+
end
|
109
|
+
params[:start] = events[-1]['datetime'] + 1
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Publish an event. Publishing an event require a few mandatories parameters:
|
116
|
+
# [:location] As described in the subscribe method: ["organisation", "meeting"] publish the event in a specific meeting, ["organisation"] publish the event in the organisation and []: publish the event in the server root.
|
117
|
+
# [:type] The type of event to send, the format of this type is usually 'namespace.object.action', for example: 'chat.message.new', 'twitter.tweet.new', 'internal.user.update'
|
118
|
+
# [:parent] The id of the parent, this parameter is useful to build event hierarchy.
|
119
|
+
# [:metadata] A hash of freely defined values to append to the event.
|
120
|
+
#
|
121
|
+
# uce.publish(:location => ["af83", "WebWorkersCamp"],
|
122
|
+
# :type => 'presentation.slide.add'
|
123
|
+
# :metadata => {:url => 'http://myserver/slides/03.png',
|
124
|
+
# :index => 3})
|
125
|
+
def publish(event)
|
126
|
+
debug(UCEngine::DEBUG, "Publish to #{event[:location]}, type: #{event[:type]}, parent: #{event[:parent]}, metadata: #{event[:metadata]}")
|
127
|
+
params = Hash.new
|
128
|
+
params[:type] = event[:type]
|
129
|
+
params[:parent] = event[:parent] if event[:parent]
|
130
|
+
if event[:metadata]
|
131
|
+
event[:metadata].each_key do |key|
|
132
|
+
params["metadata[#{key}]"] = event[:metadata][key]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
put("/event/#{event[:location].join("/")}", params)
|
136
|
+
end
|
137
|
+
|
138
|
+
# Return the current timestamp from the server. The timestamp is expressed in milliseconds
|
139
|
+
# from Epoch (january 1st 1970).
|
140
|
+
# This function can be useful if you need to search for events from _now_.
|
141
|
+
#
|
142
|
+
# uce.time -> 1240394032
|
143
|
+
#
|
144
|
+
def time
|
145
|
+
time = get("/time", Hash.new)['result'].to_i
|
146
|
+
debug(UCEngine::DEBUG, "Fecth timestamp from UCEngine: #{time}")
|
147
|
+
return time
|
148
|
+
end
|
149
|
+
|
150
|
+
protected
|
151
|
+
|
152
|
+
# Encode parameters
|
153
|
+
def UCEngine.encode(params)
|
154
|
+
params.collect { |k,v| "#{k}=#{CGI::escape(v.to_s)}" }.join('&')
|
155
|
+
end
|
156
|
+
|
157
|
+
# Print debug messages
|
158
|
+
def debug(level, message)
|
159
|
+
$stderr.write("#{message}\n\n") if level >= @debug
|
160
|
+
end
|
161
|
+
|
162
|
+
# Handle GET requests
|
163
|
+
def get(path, params, http = @http)
|
164
|
+
params[:uid] = @uid if @uid
|
165
|
+
params[:sid] = @sid if @sid
|
166
|
+
result = JSON.parse(http.get("/api/0.1/#{path}?#{UCEngine.encode(params)}").body)
|
167
|
+
debug(UCEngine::DEBUG, "Request: GET /api/0.1/#{path}?#{UCEngine.encode(params)}\nResult: #{result}")
|
168
|
+
return result
|
169
|
+
end
|
170
|
+
|
171
|
+
# Handle POST requests
|
172
|
+
def post(path, params, http = @http)
|
173
|
+
params[:uid] = @uid if @uid
|
174
|
+
params[:sid] = @sid if @sid
|
175
|
+
result = JSON.parse(http.post("/api/0.1/#{path}", UCEngine.encode(params)).body)
|
176
|
+
debug(UCEngine::DEBUG, "Request: POST /api/0.1/#{path}?#{UCEngine.encode(params)}\nResult: #{result}")
|
177
|
+
return result
|
178
|
+
end
|
179
|
+
|
180
|
+
# Handle PUT requests
|
181
|
+
def put(path, params)
|
182
|
+
params['_method'] = "PUT"
|
183
|
+
post(path, params)
|
184
|
+
end
|
185
|
+
|
186
|
+
# Handle DELETE requests
|
187
|
+
def delete(path, params)
|
188
|
+
params['_method'] = "DELETE"
|
189
|
+
post(path, params)
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
data/test/helper.rb
ADDED
data/ucengine.rb.gemspec
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{ucengine.rb}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["AF83"]
|
12
|
+
s.date = %q{2010-11-23}
|
13
|
+
s.description = %q{ucengine.rb is a Ruby library to consume the UCEngine API}
|
14
|
+
s.email = %q{victor.goya@af83.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/ucengine.rb",
|
27
|
+
"test/helper.rb",
|
28
|
+
"test/test_ucengine.rb.rb",
|
29
|
+
"ucengine.rb.gemspec"
|
30
|
+
]
|
31
|
+
s.homepage = %q{http://github.com/AF83/ucengine.rb}
|
32
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
33
|
+
s.require_paths = ["lib"]
|
34
|
+
s.rubygems_version = %q{1.3.7}
|
35
|
+
s.summary = %q{Ruby library for UCEngine}
|
36
|
+
s.test_files = [
|
37
|
+
"test/helper.rb",
|
38
|
+
"test/test_ucengine.rb.rb"
|
39
|
+
]
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
43
|
+
s.specification_version = 3
|
44
|
+
|
45
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
46
|
+
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
47
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
48
|
+
else
|
49
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
50
|
+
s.add_dependency(%q<json>, [">= 0"])
|
51
|
+
end
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
54
|
+
s.add_dependency(%q<json>, [">= 0"])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ucengine
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- AF83
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-12-01 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: thoughtbot-shoulda
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :development
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: json
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
46
|
+
description: ucengine.rb is a Ruby library to consume the UCEngine API
|
47
|
+
email: victor.goya@af83.com
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
extra_rdoc_files:
|
53
|
+
- LICENSE
|
54
|
+
- README.rdoc
|
55
|
+
files:
|
56
|
+
- .document
|
57
|
+
- .gitignore
|
58
|
+
- LICENSE
|
59
|
+
- README.rdoc
|
60
|
+
- Rakefile
|
61
|
+
- VERSION
|
62
|
+
- doc/UCEngine.html
|
63
|
+
- doc/UCEngine/Debug.html
|
64
|
+
- doc/created.rid
|
65
|
+
- doc/images/brick.png
|
66
|
+
- doc/images/brick_link.png
|
67
|
+
- doc/images/bug.png
|
68
|
+
- doc/images/bullet_black.png
|
69
|
+
- doc/images/bullet_toggle_minus.png
|
70
|
+
- doc/images/bullet_toggle_plus.png
|
71
|
+
- doc/images/date.png
|
72
|
+
- doc/images/find.png
|
73
|
+
- doc/images/loadingAnimation.gif
|
74
|
+
- doc/images/macFFBgHack.png
|
75
|
+
- doc/images/package.png
|
76
|
+
- doc/images/page_green.png
|
77
|
+
- doc/images/page_white_text.png
|
78
|
+
- doc/images/page_white_width.png
|
79
|
+
- doc/images/plugin.png
|
80
|
+
- doc/images/ruby.png
|
81
|
+
- doc/images/tag_green.png
|
82
|
+
- doc/images/wrench.png
|
83
|
+
- doc/images/wrench_orange.png
|
84
|
+
- doc/images/zoom.png
|
85
|
+
- doc/index.html
|
86
|
+
- doc/js/darkfish.js
|
87
|
+
- doc/js/jquery.js
|
88
|
+
- doc/js/quicksearch.js
|
89
|
+
- doc/js/thickbox-compressed.js
|
90
|
+
- doc/lib/ucengine_rb.html
|
91
|
+
- doc/rdoc.css
|
92
|
+
- lib/ucengine.rb
|
93
|
+
- test/helper.rb
|
94
|
+
- test/test_ucengine.rb
|
95
|
+
- ucengine.rb.gemspec
|
96
|
+
has_rdoc: true
|
97
|
+
homepage: http://github.com/AF83/ucengine.rb
|
98
|
+
licenses: []
|
99
|
+
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options:
|
102
|
+
- --charset=UTF-8
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
version: "0"
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
segments:
|
119
|
+
- 0
|
120
|
+
version: "0"
|
121
|
+
requirements: []
|
122
|
+
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 1.3.7
|
125
|
+
signing_key:
|
126
|
+
specification_version: 3
|
127
|
+
summary: Ruby library for UCEngine
|
128
|
+
test_files:
|
129
|
+
- test/helper.rb
|
130
|
+
- test/test_ucengine.rb
|