ucengine 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.
- 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
|