hope 0.1.0-java
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/Gemfile +11 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/bin/hope-web +16 -0
- data/hope.gemspec +34 -0
- data/lib/hope.rb +103 -0
- data/lib/hope/core_ext/object.rb +78 -0
- data/lib/hope/engine.rb +189 -0
- data/lib/hope/event_type.rb +22 -0
- data/lib/hope/jars/antlr-runtime-3.2.jar +0 -0
- data/lib/hope/jars/cglib-nodep-2.2.jar +0 -0
- data/lib/hope/jars/commons-logging-1.1.1.jar +0 -0
- data/lib/hope/jars/esper-4.3.0.jar +0 -0
- data/lib/hope/jars/log4j-1.2.16.jar +0 -0
- data/lib/hope/jars/msgpack-0.6.0-devel.jar +0 -0
- data/lib/hope/listener/base.rb +40 -0
- data/lib/hope/server.rb +43 -0
- data/lib/hope/server/app.rb +40 -0
- data/lib/hope/server/public/css/Aristo/images/bg_fallback.png +0 -0
- data/lib/hope/server/public/css/Aristo/images/icon_sprite.png +0 -0
- data/lib/hope/server/public/css/Aristo/images/progress_bar.gif +0 -0
- data/lib/hope/server/public/css/Aristo/images/slider_handles.png +0 -0
- data/lib/hope/server/public/css/Aristo/images/ui-icons_222222_256x240.png +0 -0
- data/lib/hope/server/public/css/Aristo/images/ui-icons_454545_256x240.png +0 -0
- data/lib/hope/server/public/css/Aristo/jquery-ui-1.8.7.custom.css +703 -0
- data/lib/hope/server/public/css/hope.css +235 -0
- data/lib/hope/server/public/favicon.ico +0 -0
- data/lib/hope/server/public/hope.js +995 -0
- data/lib/hope/server/public/js/backbone-0.3.3.js +1011 -0
- data/lib/hope/server/public/js/backbone-0.5.1.js +1149 -0
- data/lib/hope/server/public/js/hope.js +993 -0
- data/lib/hope/server/public/js/inflection.js +656 -0
- data/lib/hope/server/public/js/jquery-1.6.1.js +8936 -0
- data/lib/hope/server/public/js/jquery-ui-1.8.14.custom.min.js +789 -0
- data/lib/hope/server/public/js/underscore-1.1.6.js +807 -0
- data/lib/hope/server/resources/engine.rb +60 -0
- data/lib/hope/server/resources/source.rb +22 -0
- data/lib/hope/server/resources/statement.rb +62 -0
- data/lib/hope/server/views/app.erb +24 -0
- data/lib/hope/source.rb +20 -0
- data/lib/hope/source/base.rb +30 -0
- data/lib/hope/source/sub.rb +24 -0
- data/lib/hope/source/twitter.rb +123 -0
- data/lib/hope/statement.rb +73 -0
- data/lib/hope/version.rb +3 -0
- metadata +241 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
module Hope
|
2
|
+
module Server
|
3
|
+
module Resources
|
4
|
+
module Engine
|
5
|
+
|
6
|
+
def self.registered app
|
7
|
+
app.get "/engines/:engine_id" do
|
8
|
+
content_type :json
|
9
|
+
engine.to_json
|
10
|
+
end
|
11
|
+
|
12
|
+
app.get "/engines" do
|
13
|
+
content_type :json
|
14
|
+
Hope.engines.values.map { |e| e.serializable_hash }.to_json
|
15
|
+
end
|
16
|
+
|
17
|
+
app.put "/engines/:id" do
|
18
|
+
engine_id = params[:id]
|
19
|
+
respond_with(Hope::Engine.get(engine_id) || Hope::Engine.new(engine_id))
|
20
|
+
end
|
21
|
+
|
22
|
+
app.delete "/engines/:id" do
|
23
|
+
e = Hope::Engine.get(params[:id])
|
24
|
+
e.destroy unless e.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
app.post "/engines" do
|
28
|
+
engine_id = params[:engine_id] || params[:id] || body["name"]
|
29
|
+
if Hope::Engine.get(engine_id)
|
30
|
+
error_with("Engine #{engine_id} already exists")
|
31
|
+
else
|
32
|
+
respond_with Hope::Engine.new(engine_id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
app.post "/engines/:id/stop" do
|
37
|
+
engine.stop
|
38
|
+
respond_with engine
|
39
|
+
end
|
40
|
+
|
41
|
+
app.post "/engines/:id/start" do
|
42
|
+
engine.start
|
43
|
+
respond_with engine
|
44
|
+
end
|
45
|
+
|
46
|
+
app.post "/engines/:engine_id/subscribe/:src_name" do
|
47
|
+
engine.subscribe params[:src_name]
|
48
|
+
respond_with engine
|
49
|
+
end
|
50
|
+
|
51
|
+
app.post "/engines/:engine_id/unsubscribe/:src_name" do
|
52
|
+
engine.unsubscribe params[:src_name]
|
53
|
+
respond_with engine
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Hope
|
2
|
+
module Server
|
3
|
+
module Resources
|
4
|
+
module Source
|
5
|
+
|
6
|
+
def self.registered app
|
7
|
+
|
8
|
+
app.get "/sources" do
|
9
|
+
respond_with Hope::Source.sources.values.map(&:serializable_hash)
|
10
|
+
end
|
11
|
+
|
12
|
+
app.post "/sources" do
|
13
|
+
source_type = body["type"]
|
14
|
+
source_class = Hope::Source.const_get(source_type)
|
15
|
+
src = source_class.new(body["name"], body["opts"])
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Hope
|
2
|
+
module Server
|
3
|
+
module Resources
|
4
|
+
module Statement
|
5
|
+
|
6
|
+
def self.registered app
|
7
|
+
|
8
|
+
# Statements
|
9
|
+
|
10
|
+
app.get "/engines/:engine_id/statements" do
|
11
|
+
respond_with engine.serializable_hash[:statements]
|
12
|
+
end
|
13
|
+
|
14
|
+
app.get "/engines/:engine_id/statements/:id" do
|
15
|
+
respond_with statement
|
16
|
+
end
|
17
|
+
|
18
|
+
app.post "/engines/:engine_id/statements" do
|
19
|
+
statement_id = body["id"] || body["statement_id"]
|
20
|
+
st = engine.add_epl(body["epl"], body["statement_id"])
|
21
|
+
st.add_listener(Hope::Listener::Base.new(body["id"])) if body["listener"]
|
22
|
+
begin
|
23
|
+
respond_with(st, 201)
|
24
|
+
rescue => err
|
25
|
+
error_with(err, 406)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
app.put "/engines/:engine_id/statements/:id" do
|
30
|
+
error_with("You can't update an existing statement", 405)
|
31
|
+
end
|
32
|
+
|
33
|
+
app.delete "/engines/:engine_id/statements/:id" do
|
34
|
+
statement.destroy
|
35
|
+
status 205
|
36
|
+
end
|
37
|
+
|
38
|
+
app.post "/engines/:engine_id/statements/:statement_id/stop" do
|
39
|
+
statement.stop unless statement.stopped?
|
40
|
+
respond_with statement
|
41
|
+
end
|
42
|
+
|
43
|
+
app.post "/engines/:engine_id/statements/:statement_id/start" do
|
44
|
+
statement.start
|
45
|
+
respond_with statement
|
46
|
+
end
|
47
|
+
|
48
|
+
# Listeners
|
49
|
+
|
50
|
+
app.get "/engines/:engine_id/statements/:statement_id/listeners" do
|
51
|
+
statement.get_listeners.map { |l| { :name => l.name } }
|
52
|
+
end
|
53
|
+
|
54
|
+
app.post "/engines/:engine_id/statements/:statement_id/listeners" do
|
55
|
+
statement.add_listener Hope::Listener::Base.new(body["name"])
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Hope Server v<%= Hope::VERSION %></title>
|
4
|
+
|
5
|
+
<link rel='stylesheet' href='css/hope.css' type='text/css' media="screen">
|
6
|
+
<link rel='stylesheet' href='css/Aristo/jquery-ui-1.8.7.custom.css' type='text/css' media="screen">
|
7
|
+
<script type="text/javascript" src="js/jquery-1.6.1.js"></script>
|
8
|
+
<script type="text/javascript" src="js/jquery-ui-1.8.14.custom.min.js"></script>
|
9
|
+
<script type="text/javascript" src="js/underscore-1.1.6.js"></script>
|
10
|
+
<script type="text/javascript" src="js/backbone-0.5.1.js"></script>
|
11
|
+
<script type="text/javascript" src="js/inflection.js"></script>
|
12
|
+
<script type="text/javascript" src="js/hope.js"></script>
|
13
|
+
<script type="text/javascript">
|
14
|
+
$(function() {
|
15
|
+
window.hope = Hope.init("hope");
|
16
|
+
})
|
17
|
+
</script>
|
18
|
+
</head>
|
19
|
+
|
20
|
+
<body>
|
21
|
+
<div id="hope" style="display:none"></div>
|
22
|
+
<div id="loading">loading...</div>
|
23
|
+
</body>
|
24
|
+
</html>
|
data/lib/hope/source.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Hope
|
2
|
+
class Source::Base
|
3
|
+
|
4
|
+
attr_reader :name, :options
|
5
|
+
|
6
|
+
def self.event_types
|
7
|
+
[]
|
8
|
+
end
|
9
|
+
|
10
|
+
# Misc
|
11
|
+
def serializable_hash
|
12
|
+
{
|
13
|
+
:id => @name,
|
14
|
+
:name => @name,
|
15
|
+
:type => self.class.name,
|
16
|
+
:options => @options,
|
17
|
+
:received => @received
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_json
|
22
|
+
serializable_hash.to_json
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse m
|
26
|
+
JSON.parse m
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Hope
|
2
|
+
class Source::Sub < Hope::Source::Base
|
3
|
+
|
4
|
+
|
5
|
+
attr_reader :received
|
6
|
+
|
7
|
+
def initialize name, opts={}
|
8
|
+
@name = name
|
9
|
+
@socket = opts["socket"] || "ipc://hope"
|
10
|
+
@event_type = opts["event_type"]
|
11
|
+
@received = { :success => 0, :errors => 0, :latest_error => "" }
|
12
|
+
@sub = Hope.ctx.connect ZMQ::SUB, @socket, self
|
13
|
+
@sub.subscribe name
|
14
|
+
Hope::Source.register self
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_readable(socket, messages)
|
18
|
+
@received[:success] += 1
|
19
|
+
src, evt = messages.map &:copy_out_string
|
20
|
+
Hope.pub.send_msg src, { "data" => evt, "type" => @event_type }.to_json
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'twitter/json_stream'
|
2
|
+
require "logger"
|
3
|
+
require "json"
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
module Hope
|
9
|
+
class Source::Twitter < Hope::Source::Base
|
10
|
+
|
11
|
+
class TwitterUser < Hope::EventType
|
12
|
+
def self.properties
|
13
|
+
{
|
14
|
+
"protected" => "bool",
|
15
|
+
"default_profile" => "bool",
|
16
|
+
"contributors_enabled" => "bool",
|
17
|
+
"profile_text_color" => "string",
|
18
|
+
"name" => "string",
|
19
|
+
"default_profile_image" => "bool",
|
20
|
+
"profile_sidebar_fill_color" => "string",
|
21
|
+
"id_str" => "string",
|
22
|
+
"profile_background_tile" => "bool",
|
23
|
+
"utc_offset" => "string",
|
24
|
+
"friends_count" => "int",
|
25
|
+
"profile_image_url" => "string",
|
26
|
+
"is_translator" => "bool",
|
27
|
+
"following" => "bool",
|
28
|
+
"description" => "string",
|
29
|
+
"location" => "string",
|
30
|
+
"follow_request_sent" => "string",
|
31
|
+
"verified" => "bool",
|
32
|
+
"profile_link_color" => "string",
|
33
|
+
"followers_count" => "int",
|
34
|
+
"screen_name" => "string",
|
35
|
+
"profile_sidebar_border_color" => "string",
|
36
|
+
"url" => "string",
|
37
|
+
"show_all_inline_media" => "bool",
|
38
|
+
"geo_enabled" => "bool",
|
39
|
+
"time_zone" => "string",
|
40
|
+
"id" => "long",
|
41
|
+
"notifications" => "bool",
|
42
|
+
"profile_use_background_image" => "bool",
|
43
|
+
"favourites_count" => "int",
|
44
|
+
"created_at" => "string",
|
45
|
+
"listed_count" => "int",
|
46
|
+
"profile_background_image_url_https" => "string",
|
47
|
+
"profile_background_color" => "string",
|
48
|
+
"lang" => "string",
|
49
|
+
"statuses_count" => "int",
|
50
|
+
"profile_background_image_url" => "string",
|
51
|
+
"profile_image_url_https" => "string"
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Tweet < Hope::EventType
|
57
|
+
def self.properties
|
58
|
+
{
|
59
|
+
"place" => "string",
|
60
|
+
"user" => "TwitterUser",
|
61
|
+
"in_reply_to_user_id" => "long",
|
62
|
+
"retweet_count" => "int",
|
63
|
+
"id_str" => "string",
|
64
|
+
"geo" => "string",
|
65
|
+
"favorited" => "bool",
|
66
|
+
"text" => "string",
|
67
|
+
"in_reply_to_status_id_str" => "string",
|
68
|
+
"in_reply_to_screen_name" => "string",
|
69
|
+
"in_reply_to_user_id_str" => "string",
|
70
|
+
"coordinates" => "string",
|
71
|
+
"truncated" => "bool",
|
72
|
+
"contributors" => "string",
|
73
|
+
"retweeted" => "bool",
|
74
|
+
"id" => "long",
|
75
|
+
"source" => "string",
|
76
|
+
"created_at" => "string",
|
77
|
+
"in_reply_to_status_id" => "long"
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.event_types
|
83
|
+
[ TwitterUser, Tweet ]
|
84
|
+
end
|
85
|
+
|
86
|
+
def initialize(name, opts={})
|
87
|
+
|
88
|
+
@logger = Logger.new("tmp/#{name}.json")
|
89
|
+
|
90
|
+
EM::PeriodicTimer.new(1) do
|
91
|
+
puts "#{@received[:success]} tweets Received from Twitter::#{name}"
|
92
|
+
end
|
93
|
+
|
94
|
+
@name = name
|
95
|
+
@received = { :success => 0, :errors => 0, :latest_error => "" }
|
96
|
+
@options = {}.merge(opts)
|
97
|
+
|
98
|
+
stream = Twitter::JSONStream.connect(
|
99
|
+
:path => "/1/statuses/filter.json?track=#{@options["track"]}",
|
100
|
+
:auth => "#{@options["login"]}:#{@options["password"]}"
|
101
|
+
)
|
102
|
+
|
103
|
+
stream.each_item do |item|
|
104
|
+
# @logger.info(item)
|
105
|
+
@received[:success] += 1
|
106
|
+
tweet = JSON.parse item
|
107
|
+
Hope.pub.send_msg name, { "data" => tweet, "type" => "Tweet" }.to_json
|
108
|
+
end
|
109
|
+
|
110
|
+
stream.on_error do |message|
|
111
|
+
@received[:errors] += 1
|
112
|
+
puts "Error: #{message}"
|
113
|
+
end
|
114
|
+
|
115
|
+
stream.on_max_reconnects do |timeout, retries|
|
116
|
+
@received[:latest_error] = "Max reconnect: #{timeout} || retried #{retries} times..."
|
117
|
+
end
|
118
|
+
|
119
|
+
Hope::Source.register self
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Hope
|
4
|
+
|
5
|
+
class Statement
|
6
|
+
|
7
|
+
java_import com.espertech.esper.client.EPStatementState
|
8
|
+
|
9
|
+
%w{ STARTED FAILED DESTROYED STOPPED }.each do |c|
|
10
|
+
const_set(c, EPStatementState.valueOf(c))
|
11
|
+
end
|
12
|
+
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
attr_reader :ep_statement
|
16
|
+
|
17
|
+
def_delegator :@ep_statement, :stop, :stop
|
18
|
+
def_delegator :@ep_statement, :start, :start
|
19
|
+
def_delegator :@ep_statement, :destroy, :destroy
|
20
|
+
|
21
|
+
def_delegator :@ep_statement, :getName, :name
|
22
|
+
def_delegator :@ep_statement, :getEventType, :event_type
|
23
|
+
def_delegator :@ep_statement, :getText, :text
|
24
|
+
def_delegator :@ep_statement, :getState, :state
|
25
|
+
def_delegator :@ep_statement, :getUserObject, :user
|
26
|
+
def_delegator :@ep_statement, :getAnnotations, :annotations
|
27
|
+
def_delegator :@ep_statement, :getServiceIsolated, :service_isolated
|
28
|
+
|
29
|
+
def_delegator :@ep_statement, :isPattern, :pattern?
|
30
|
+
|
31
|
+
def_delegator :@ep_statement, :isStarted, :started?
|
32
|
+
def_delegator :@ep_statement, :isStopped, :stopped?
|
33
|
+
def_delegator :@ep_statement, :isDestroyed, :destroyed?
|
34
|
+
|
35
|
+
def_delegator :@ep_statement, :addListener, :add_listener
|
36
|
+
def_delegator :@ep_statement, :getUpdateListeners, :get_listeners
|
37
|
+
def_delegator :@ep_statement, :removeListener, :remove_listener
|
38
|
+
def_delegator :@ep_statement, :removeAllListeners, :remove_all_listeners
|
39
|
+
|
40
|
+
|
41
|
+
def to_s
|
42
|
+
"[#{name}:#{event_type}] (#{state}) : #{text}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def initialize ep_statement
|
46
|
+
@ep_statement = ep_statement
|
47
|
+
end
|
48
|
+
|
49
|
+
def updated_at
|
50
|
+
Time.at(@ep_statement.getTimeLastStateChange / 1000)
|
51
|
+
end
|
52
|
+
|
53
|
+
def serializable_hash
|
54
|
+
{
|
55
|
+
:id => name,
|
56
|
+
:name => name,
|
57
|
+
:text => text,
|
58
|
+
:updated_at => updated_at,
|
59
|
+
:state => state.to_s,
|
60
|
+
:is_pattern => pattern?,
|
61
|
+
:event_type => event_type.getName,
|
62
|
+
:is_destroyed => destroyed?,
|
63
|
+
:listeners => get_listeners.map { |l| l.serializable_hash }
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def to_json
|
68
|
+
serializable_hash.to_json
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|