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