banter 0.8.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.travis.yml +8 -0
- data/Gemfile +2 -0
- data/Rakefile +29 -0
- data/lib/banter/subscriber.rb +18 -0
- data/lib/banter/version.rb +1 -1
- data/lib/banter/web.rb +6 -0
- data/lib/banter/web/application.rb +62 -13
- data/lib/banter/web/helpers.rb +6 -2
- data/lib/banter/web/models/banter_message.rb +45 -5
- data/lib/banter/web/models/banter_worker.rb +5 -0
- data/lib/banter/web/serializers/banter_message_serializer.rb +34 -0
- data/lib/banter/web/serializers/banter_worker_serializer.rb +30 -0
- data/lib/banter/web/serializers/subscriber_serializer.rb +26 -0
- data/spec/banter/subscriber_spec.rb +82 -1
- data/spec/banter/web/application_spec.rb +173 -2
- data/spec/factories/banter_messages.rb +28 -0
- data/spec/spec_helper.rb +0 -1
- data/web/assets/javascripts/banter.js +449 -0
- data/web/assets/javascripts/dashboard_app/app.coffee +4 -0
- data/web/assets/javascripts/dashboard_app/controllers/message_controller.coffee +27 -0
- data/web/assets/javascripts/dashboard_app/controllers/messages_controller.coffee +57 -0
- data/web/assets/javascripts/dashboard_app/controllers/subscribers_controller.coffee +25 -0
- data/web/assets/javascripts/dashboard_app/controllers/worker_controller.coffee +30 -0
- data/web/assets/javascripts/dashboard_app/controllers/workers_list_controller.coffee +28 -0
- data/web/assets/javascripts/dashboard_app/routes.coffee +82 -0
- data/web/assets/javascripts/dashboard_app/services/common_methods_service.coffee +6 -0
- data/web/assets/javascripts/dashboard_app/services/message_methods_service.coffee +18 -0
- data/web/assets/javascripts/dashboard_app/services/messages_service.coffee +17 -0
- data/web/assets/javascripts/dashboard_app/services/subscribers_service.coffee +8 -0
- data/web/assets/javascripts/dashboard_app/services/worker_methods_service.coffee +11 -0
- data/web/assets/javascripts/dashboard_app/services/worker_service.coffee +15 -0
- data/web/assets/javascripts/ng-prettyjson.js +15 -0
- data/web/assets/stylesheets/banter.css +13 -1
- data/web/views/_message.haml +59 -0
- data/web/views/_messages.haml +77 -0
- data/web/views/_subscribers.haml +22 -0
- data/web/views/_worker.haml +52 -0
- data/web/views/_workers_list.haml +35 -0
- data/web/views/index.haml +16 -29
- data/web/views/layout.haml +16 -10
- metadata +28 -7
- data/web/views/message.haml +0 -52
- data/web/views/messages.haml +0 -20
- data/web/views/subscribers.haml +0 -17
- data/web/views/worker.haml +0 -51
@@ -1,10 +1,181 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Banter::Web::Application do
|
4
|
+
let(:response_json) { JSON.parse(last_response.body) }
|
4
5
|
describe 'GET /' do
|
5
6
|
before { get '/' }
|
6
|
-
it '
|
7
|
-
expect(last_response.status).to eq
|
7
|
+
it 'redirects to dashboard' do
|
8
|
+
expect(last_response.status).to eq 302
|
9
|
+
end
|
10
|
+
|
11
|
+
it { expect(last_response.location).to include("/dashboard") }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "GET /dashboard*" do
|
15
|
+
context "GET /dashboard" do
|
16
|
+
before { get '/dashboard' }
|
17
|
+
it "is successful" do
|
18
|
+
expect(last_response.status).to be(200)
|
19
|
+
end
|
20
|
+
it "includes dashboardApp" do
|
21
|
+
expect(last_response.body).to include('dashboardApp')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "GET /dashboard/workers/123" do
|
26
|
+
before { get '/dashboard/workers/123' }
|
27
|
+
it "is successful" do
|
28
|
+
expect(last_response.status).to be(200)
|
29
|
+
end
|
30
|
+
it "includes dashboardApp" do
|
31
|
+
expect(last_response.body).to include('dashboardApp')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "GET /dashboard/wtf" do
|
36
|
+
before { get '/dashboard/wtf' }
|
37
|
+
it "is successful" do
|
38
|
+
expect(last_response.status).to be(200)
|
39
|
+
end
|
40
|
+
it "includes dashboardApp" do
|
41
|
+
expect(last_response.body).to include('dashboardApp')
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "GET /workers.json" do
|
47
|
+
let!(:worker_1) { FactoryGirl.create(:banter_worker) }
|
48
|
+
let!(:worker_2) { FactoryGirl.create(:banter_worker) }
|
49
|
+
let!(:worker_3) { FactoryGirl.create(:banter_worker, :stopped) }
|
50
|
+
let(:workers_json) { response_json['workers'] }
|
51
|
+
|
52
|
+
before { get "/workers.json" }
|
53
|
+
it 'is successful' do
|
54
|
+
expect(last_response.status).to be(200)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "includes only running workers" do
|
58
|
+
expect(workers_json.size).to eq(2)
|
59
|
+
end
|
60
|
+
|
61
|
+
it do
|
62
|
+
worker_ids = workers_json.map { |worker| worker['id'] }
|
63
|
+
expect(worker_ids).to eq([worker_1.id.to_s, worker_2.id.to_s])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "GET /workers/:worker_id.json" do
|
68
|
+
let(:worker_json) { response_json['worker'] }
|
69
|
+
|
70
|
+
def self.it_works
|
71
|
+
before { get "/workers/#{worker.id.to_s}.json" }
|
72
|
+
it 'is successful' do
|
73
|
+
expect(last_response.status).to be 200
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'includes worker data' do
|
77
|
+
expect(worker_json['id']).to eq(worker.id.to_s)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "alive worker" do
|
82
|
+
let(:worker) { FactoryGirl.create(:banter_worker) }
|
83
|
+
it_works
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "dead worker" do
|
87
|
+
let(:worker) { FactoryGirl.create(:banter_worker, :stopped) }
|
88
|
+
it_works
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "GET /messages/:message_id.json" do
|
93
|
+
let(:message_json) { response_json['message'] }
|
94
|
+
let(:message) { FactoryGirl.create(:banter_message) }
|
95
|
+
|
96
|
+
before { get "/messages/#{message.id.to_s}.json" }
|
97
|
+
|
98
|
+
it 'is successful' do
|
99
|
+
expect(last_response.status).to be 200
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'includes message' do
|
103
|
+
expect(message_json['id']).to eq(message.id.to_s)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "GET /messages.json" do
|
108
|
+
let(:messages_json) { response_json['messages'] }
|
109
|
+
let(:worker_id) { nil }
|
110
|
+
|
111
|
+
def includes_messages(*messages)
|
112
|
+
message_ids = messages_json.map { |m| m['id']}
|
113
|
+
expect(message_ids).to eq(messages.map(&:id).map(&:to_s))
|
114
|
+
end
|
115
|
+
|
116
|
+
context "all messages" do
|
117
|
+
let!(:message_1) { FactoryGirl.create(:banter_message) }
|
118
|
+
let!(:message_2) { FactoryGirl.create(:banter_message) }
|
119
|
+
let!(:message_3) { FactoryGirl.create(:banter_message, :errored) }
|
120
|
+
before { get "/messages.json?worker_id=#{worker_id}" }
|
121
|
+
|
122
|
+
it 'is successful' do
|
123
|
+
expect(last_response.status).to be 200
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'includes messages' do
|
127
|
+
includes_messages(message_1, message_2, message_3)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "by worker" do
|
132
|
+
let(:worker) { FactoryGirl.create(:banter_worker) }
|
133
|
+
let(:worker_id) { worker.id }
|
134
|
+
let!(:message_1) { FactoryGirl.create(:banter_message, worker_id: worker.id ) }
|
135
|
+
let!(:message_2) { FactoryGirl.create(:banter_message, worker_id: worker.id) }
|
136
|
+
let!(:message_3) { FactoryGirl.create(:banter_message, :errored, worker_id: worker.id) }
|
137
|
+
let!(:message_4) { FactoryGirl.create(:banter_message) }
|
138
|
+
before { get "/messages.json?worker_id=#{worker_id}" }
|
139
|
+
it 'is successful' do
|
140
|
+
expect(last_response.status).to be 200
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'includes messages' do
|
144
|
+
includes_messages(message_1, message_2, message_3)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context "by subscriber" do
|
149
|
+
let(:subscriber) { 'MyTestClass' }
|
150
|
+
let!(:message_1) { FactoryGirl.create(:banter_message, subscriber_class: subscriber ) }
|
151
|
+
let!(:message_2) { FactoryGirl.create(:banter_message, subscriber_class: subscriber) }
|
152
|
+
let!(:message_3) { FactoryGirl.create(:banter_message, :errored) }
|
153
|
+
let!(:message_4) { FactoryGirl.create(:banter_message, :errored, subscriber_class: subscriber) }
|
154
|
+
before { get "/messages.json?subscriber=#{subscriber}" }
|
155
|
+
it 'is successful' do
|
156
|
+
expect(last_response.status).to be 200
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'includes messages' do
|
160
|
+
includes_messages(message_1, message_2, message_4)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "GET /subscribers.json" do
|
166
|
+
let!(:worker_1) { FactoryGirl.create(:banter_worker, worker_classes: [ 'FooWorker1', 'BarWorker2'])}
|
167
|
+
let!(:worker_2) { FactoryGirl.create(:banter_worker, :stopped, worker_classes: [ 'FooWorker2', 'BarWorker1'])}
|
168
|
+
|
169
|
+
let(:subscribers_json) { response_json['subscribers'] }
|
170
|
+
|
171
|
+
before { get '/subscribers.json'}
|
172
|
+
it 'is successful' do
|
173
|
+
expect(last_response.status).to be 200
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'includes message' do
|
177
|
+
subscribers = subscribers_json.map { |s| s['class_name']}.sort
|
178
|
+
expect(subscribers).to eq(['BarWorker1', 'BarWorker2', 'FooWorker1', 'FooWorker2'])
|
8
179
|
end
|
9
180
|
end
|
10
181
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :banter_message do
|
3
|
+
queue_name "fuQ"
|
4
|
+
subscribed_key "fu.Q"
|
5
|
+
payload_key "fu.Q.again"
|
6
|
+
payload { { a: 1, b: 2 } }
|
7
|
+
context {{ app: 'banter' }}
|
8
|
+
started_at Time.now - 2
|
9
|
+
status BanterMessage::STATUS_STARTED
|
10
|
+
worker_id { FactoryGirl.create(:banter_worker).id }
|
11
|
+
|
12
|
+
trait :successful do
|
13
|
+
status BanterMessage::STATUS_SUCCESS
|
14
|
+
end
|
15
|
+
|
16
|
+
trait :errored do
|
17
|
+
status BanterMessage::STATUS_ERROR
|
18
|
+
end
|
19
|
+
|
20
|
+
trait :validation_failed do
|
21
|
+
status BanterMessage::STATUS_VALIDATION_FAILED
|
22
|
+
end
|
23
|
+
|
24
|
+
trait :done do
|
25
|
+
done_at Time.now
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,449 @@
|
|
1
|
+
/**
|
2
|
+
* @license ng-prettyjson - v0.1.2
|
3
|
+
* (c) 2013 Julien VALERY https://github.com/darul75/ng-prettyjson
|
4
|
+
* License: MIT
|
5
|
+
**/
|
6
|
+
angular.module("ngPrettyJson",[]).directive("prettyJson",["ngPrettyJsonFunctions",function(a){"use strict";var b=angular.isDefined;return{restrict:"AE",scope:{json:"=",prettyJson:"="},replace:!0,template:'<div><button ng-click="edit()" ng-show="edition && !editActivated">Edit</button><button ng-click="edit()" ng-show="edition && editActivated">Cancel</button><button ng-click="update()" ng-show="editActivated && parsable">Update</button><pre id="prettyjson"></pre></div>',link:function(c,d,e){var f={},g="prettyjson",h=null;c.editActivated=!1,c.edition=e.edition;// prefer the "json" attribute over the "prettyJson" one.
|
7
|
+
// the value on the scope might not be defined yet, so look at the markup.
|
8
|
+
var i,j=b(e.json)?"json":"prettyJson",k=function(c){return b(c)?d.find("pre").html(a.syntaxHighlight(c)):d.empty()};i=c.$watch(j,function(a){// BACKWARDS COMPATIBILITY:
|
9
|
+
// if newValue is an object, and we find a `json` property,
|
10
|
+
// then stop watching on `exp`.
|
11
|
+
angular.isObject(a)&&b(a.json)?(i(),c.$watch(j+".json",function(a){k(a),f=a},!0)):(k(a),f=a)},!0);var l=function(){try{c.currentValue=JSON.parse(h.getValue()),c.parsable=!0}catch(a){c.parsable=!1}// trigger update
|
12
|
+
c.$apply(function(){})};c.edit=function(){c.editActivated?(h&&(document.getElementById(g).env=null),k(f)):(h=ace.edit(g),h.on("change",l),h.getSession().setMode("ace/mode/json")),c.editActivated=!c.editActivated},c.update=function(){c.$emit("json-updated",c.newValue)}}}}]).factory("ngPrettyJsonFunctions",function(){// cache some regular expressions
|
13
|
+
var a={entities:/((&)|(<)|(>))/g,json:/"(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|(null))\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g},b=["&","<",">"],c=["number","string","key","boolean","null"],d=function(){var a=arguments.length-2;do a--;while(!arguments[a]);return a},e=function(a){var b;// the final two arguments are the length, and the entire string itself;
|
14
|
+
// we don't care about those.
|
15
|
+
if(arguments.length<7)throw new Error("markup() must be called from String.prototype.replace()");return b=d.apply(null,arguments),'<span class="'+c[b]+'">'+a+"</span>"},f=function(){var a;if(arguments.length<5)throw new Error("makeEntities() must be called from String.prototype.replace()");return a=d.apply(null,arguments),b[a-2]},g=function(b){return angular.isString(b)||(b=JSON.stringify(b,null,2)),angular.isDefined(b)?b.replace(a.entities,f).replace(a.json,e):void 0};return{syntaxHighlight:g,makeEntities:f,markup:e,rx:a}});
|
16
|
+
(function() {
|
17
|
+
window.Banter || (window.Banter = {});
|
18
|
+
|
19
|
+
angular.module('dashboardApp', ['angularMoment', 'ngRoute', 'ngPrettyJson']);
|
20
|
+
|
21
|
+
angular.module('dashboardApp').constant('rootPath', Banter.rootPath);
|
22
|
+
|
23
|
+
}).call(this);
|
24
|
+
(function() {
|
25
|
+
angular.module('dashboardApp').controller('messageController', function($scope, $rootScope, $http, $routeParams, $timeout, message, messagesService, commonMethodsService, messageMethodsService) {
|
26
|
+
var autoUpdate;
|
27
|
+
commonMethodsService.setup($scope);
|
28
|
+
messageMethodsService.setup($scope);
|
29
|
+
$scope.message = message;
|
30
|
+
$rootScope.$on('start-messageController', function() {
|
31
|
+
if (autoUpdate) {
|
32
|
+
return $scope.resumeUpdating();
|
33
|
+
}
|
34
|
+
});
|
35
|
+
$rootScope.$on('stop-messageController', function() {
|
36
|
+
return $scope.pauseUpdating();
|
37
|
+
});
|
38
|
+
$scope.updateMessage = function() {
|
39
|
+
if (autoUpdate) {
|
40
|
+
messagesService.getMessage($scope.message.id).success(function(response) {
|
41
|
+
return $scope.message = response.message;
|
42
|
+
});
|
43
|
+
return $scope.resumeUpdating();
|
44
|
+
}
|
45
|
+
};
|
46
|
+
$scope.pauseUpdating = function() {
|
47
|
+
var autoUpdate;
|
48
|
+
return autoUpdate = false;
|
49
|
+
};
|
50
|
+
$scope.resumeUpdating = function() {
|
51
|
+
var autoUpdate;
|
52
|
+
autoUpdate = true;
|
53
|
+
return $timeout($scope.updateMessage, 5000);
|
54
|
+
};
|
55
|
+
autoUpdate = $scope.isMessageExecuting();
|
56
|
+
if ($scope.isMessageExecuting()) {
|
57
|
+
$scope.resumeUpdating();
|
58
|
+
}
|
59
|
+
});
|
60
|
+
|
61
|
+
}).call(this);
|
62
|
+
(function() {
|
63
|
+
angular.module('dashboardApp').controller('messagesController', function($scope, $rootScope, $http, $routeParams, $timeout, messages, messagesService, commonMethodsService, messageMethodsService, workerMethodsService) {
|
64
|
+
var autoUpdate, fetchMessages, workerId;
|
65
|
+
commonMethodsService.setup($scope);
|
66
|
+
messageMethodsService.setup($scope);
|
67
|
+
workerMethodsService.setup($scope);
|
68
|
+
$scope.messages = messages;
|
69
|
+
$scope.page = 1;
|
70
|
+
$scope.worker = null;
|
71
|
+
workerId = $routeParams.worker_id;
|
72
|
+
$scope.subscriber = $routeParams.subscriber;
|
73
|
+
autoUpdate = true;
|
74
|
+
if (workerId) {
|
75
|
+
workersService.getWorker(workerId).success(function(response) {
|
76
|
+
return $scope.worker = response.worker;
|
77
|
+
});
|
78
|
+
}
|
79
|
+
fetchMessages = function() {
|
80
|
+
return messagesService.getMessages($scope.page, workerId, $scope.subscriber).success(function(response) {
|
81
|
+
$scope.messages = response.messages;
|
82
|
+
return $scope.worker = response.worker;
|
83
|
+
});
|
84
|
+
};
|
85
|
+
$rootScope.$on('start-messagesController', function() {
|
86
|
+
return $scope.resumeUpdating();
|
87
|
+
});
|
88
|
+
$rootScope.$on('stop-messagesController', function() {
|
89
|
+
return $scope.pauseUpdating();
|
90
|
+
});
|
91
|
+
$scope.updateMessages = function(resumeUpdate) {
|
92
|
+
if (resumeUpdate == null) {
|
93
|
+
resumeUpdate = true;
|
94
|
+
}
|
95
|
+
if (autoUpdate) {
|
96
|
+
fetchMessages();
|
97
|
+
return $scope.resumeUpdating();
|
98
|
+
}
|
99
|
+
};
|
100
|
+
$scope.pauseUpdating = function() {
|
101
|
+
return autoUpdate = false;
|
102
|
+
};
|
103
|
+
$scope.resumeUpdating = function() {
|
104
|
+
autoUpdate = true;
|
105
|
+
return $timeout($scope.updateMessages, 5000);
|
106
|
+
};
|
107
|
+
if (autoUpdate) {
|
108
|
+
$scope.resumeUpdating();
|
109
|
+
}
|
110
|
+
$scope.isAutoUpdating = function() {
|
111
|
+
return autoUpdate;
|
112
|
+
};
|
113
|
+
$scope.getNextPage = function() {
|
114
|
+
$scope.page += 1;
|
115
|
+
return fetchMessages();
|
116
|
+
};
|
117
|
+
$scope.getPreviousPage = function() {
|
118
|
+
$scope.page -= 1;
|
119
|
+
if ($scope.page < 1) {
|
120
|
+
$scope.page = 1;
|
121
|
+
}
|
122
|
+
return fetchMessages();
|
123
|
+
};
|
124
|
+
$scope.getFirstPage = function() {
|
125
|
+
$scope.page = 1;
|
126
|
+
return fetchMessages();
|
127
|
+
};
|
128
|
+
});
|
129
|
+
|
130
|
+
}).call(this);
|
131
|
+
(function() {
|
132
|
+
angular.module('dashboardApp').controller('subscribersController', function($scope, $rootScope, subscribers, $timeout, subscribersService) {
|
133
|
+
var autoUpdate;
|
134
|
+
$scope.subscribers = subscribers;
|
135
|
+
$rootScope.$on('start-subscribersController', function() {
|
136
|
+
if (autoUpdate) {
|
137
|
+
return $scope.resumeUpdating();
|
138
|
+
}
|
139
|
+
});
|
140
|
+
$rootScope.$on('stop-subscribersController', function() {
|
141
|
+
return $scope.pauseUpdating();
|
142
|
+
});
|
143
|
+
$scope.updateSubscribers = function() {
|
144
|
+
if (autoUpdate) {
|
145
|
+
subscribersService.getIndex().success(function(response) {
|
146
|
+
return $scope.subscribers = response.subscribers;
|
147
|
+
});
|
148
|
+
return $scope.resumeUpdating();
|
149
|
+
}
|
150
|
+
};
|
151
|
+
$scope.pauseUpdating = function() {
|
152
|
+
var autoUpdate;
|
153
|
+
return autoUpdate = false;
|
154
|
+
};
|
155
|
+
$scope.resumeUpdating = function() {
|
156
|
+
var autoUpdate;
|
157
|
+
autoUpdate = true;
|
158
|
+
return $timeout($scope.updateSubscribers, 10000);
|
159
|
+
};
|
160
|
+
autoUpdate = true;
|
161
|
+
$scope.resumeUpdating();
|
162
|
+
});
|
163
|
+
|
164
|
+
}).call(this);
|
165
|
+
(function() {
|
166
|
+
angular.module('dashboardApp').controller('workerController', function($scope, $rootScope, $http, $routeParams, $timeout, worker, workersService, commonMethodsService, workerMethodsService) {
|
167
|
+
var autoUpdate;
|
168
|
+
commonMethodsService.setup($scope);
|
169
|
+
workerMethodsService.setup($scope);
|
170
|
+
$scope.worker = worker;
|
171
|
+
autoUpdate = false;
|
172
|
+
$rootScope.$on('start-workerController', function() {
|
173
|
+
if (autoUpdate) {
|
174
|
+
return $scope.resumeUpdating();
|
175
|
+
}
|
176
|
+
});
|
177
|
+
$rootScope.$on('stop-workerController', function() {
|
178
|
+
return $scope.pauseUpdating();
|
179
|
+
});
|
180
|
+
$scope.updateWorker = function() {
|
181
|
+
if (autoUpdate) {
|
182
|
+
workersService.getWorker(worker.id).success(function(response) {
|
183
|
+
return $scope.worker = response.worker;
|
184
|
+
});
|
185
|
+
return $scope.resumeUpdating();
|
186
|
+
}
|
187
|
+
};
|
188
|
+
$scope.pauseUpdating = function() {
|
189
|
+
return autoUpdate = false;
|
190
|
+
};
|
191
|
+
$scope.resumeUpdating = function() {
|
192
|
+
autoUpdate = true;
|
193
|
+
return $timeout($scope.updateWorker, 5000);
|
194
|
+
};
|
195
|
+
autoUpdate = $scope.isWorkerAlive($scope.worker);
|
196
|
+
if ($scope.isWorkerAlive($scope.worker)) {
|
197
|
+
$scope.resumeUpdating();
|
198
|
+
}
|
199
|
+
});
|
200
|
+
|
201
|
+
}).call(this);
|
202
|
+
(function() {
|
203
|
+
angular.module('dashboardApp').controller('workersListController', function($scope, $rootScope, $timeout, $http, workers, rootPath, workersService, commonMethodsService) {
|
204
|
+
var autoUpdate;
|
205
|
+
commonMethodsService.setup($scope);
|
206
|
+
$scope.workers = workers;
|
207
|
+
autoUpdate = true;
|
208
|
+
$rootScope.$on('start-workersListController', function() {
|
209
|
+
return $scope.resumeUpdating();
|
210
|
+
});
|
211
|
+
$rootScope.$on('stop-workersListController', function() {
|
212
|
+
return $scope.pauseUpdating();
|
213
|
+
});
|
214
|
+
$scope.updateWorkers = function() {
|
215
|
+
if (autoUpdate) {
|
216
|
+
workersService.getCurrentList().success(function(response) {
|
217
|
+
return $scope.workers = response.workers;
|
218
|
+
});
|
219
|
+
return $scope.resumeUpdating();
|
220
|
+
}
|
221
|
+
};
|
222
|
+
$scope.pauseUpdating = function() {
|
223
|
+
return autoUpdate = false;
|
224
|
+
};
|
225
|
+
$scope.resumeUpdating = function() {
|
226
|
+
autoUpdate = true;
|
227
|
+
return $timeout($scope.updateWorkers, 5000);
|
228
|
+
};
|
229
|
+
$scope.resumeUpdating();
|
230
|
+
});
|
231
|
+
|
232
|
+
}).call(this);
|
233
|
+
(function() {
|
234
|
+
angular.module('dashboardApp').config([
|
235
|
+
'$routeProvider', '$locationProvider', function($routeProvider, $locationProvider, workersService, messagesService) {
|
236
|
+
var messageResolver, messagesResolver, subscribersResolver, workerResolver, workersResolver;
|
237
|
+
messagesResolver = function($q, messagesService, $route) {
|
238
|
+
var deferred, subscriber, workerId;
|
239
|
+
deferred = $q.defer();
|
240
|
+
workerId = $route.current.params.worker_id;
|
241
|
+
subscriber = $route.current.params.subscriber;
|
242
|
+
messagesService.getMessages(1, workerId, subscriber).success(function(response) {
|
243
|
+
return deferred.resolve(response.messages);
|
244
|
+
});
|
245
|
+
return deferred.promise;
|
246
|
+
};
|
247
|
+
messageResolver = function($q, messagesService, $route) {
|
248
|
+
var deferred;
|
249
|
+
deferred = $q.defer();
|
250
|
+
messagesService.getMessage($route.current.params.message_id).success(function(response) {
|
251
|
+
return deferred.resolve(response.message);
|
252
|
+
});
|
253
|
+
return deferred.promise;
|
254
|
+
};
|
255
|
+
workerResolver = function($q, $route, workersService) {
|
256
|
+
var deferred;
|
257
|
+
deferred = $q.defer();
|
258
|
+
workersService.getWorker($route.current.params.worker_id).success(function(response) {
|
259
|
+
return deferred.resolve(response.worker);
|
260
|
+
});
|
261
|
+
return deferred.promise;
|
262
|
+
};
|
263
|
+
workersResolver = function($q, workersService) {
|
264
|
+
var deferred;
|
265
|
+
deferred = $q.defer();
|
266
|
+
workersService.getCurrentList().success(function(response) {
|
267
|
+
return deferred.resolve(response.workers);
|
268
|
+
});
|
269
|
+
return deferred.promise;
|
270
|
+
};
|
271
|
+
subscribersResolver = function($q, subscribersService) {
|
272
|
+
var deferred;
|
273
|
+
deferred = $q.defer();
|
274
|
+
subscribersService.getIndex().success(function(response) {
|
275
|
+
return deferred.resolve(response.subscribers);
|
276
|
+
});
|
277
|
+
return deferred.promise;
|
278
|
+
};
|
279
|
+
$routeProvider.when("/", {
|
280
|
+
templateUrl: 'banter/workers-list.html',
|
281
|
+
controller: 'workersListController',
|
282
|
+
resolve: {
|
283
|
+
workers: workersResolver
|
284
|
+
}
|
285
|
+
}).when("/workers/:worker_id", {
|
286
|
+
templateUrl: 'banter/worker.html',
|
287
|
+
controller: 'workerController',
|
288
|
+
resolve: {
|
289
|
+
worker: workerResolver
|
290
|
+
}
|
291
|
+
}).when("/workers/:worker_id/messages", {
|
292
|
+
templateUrl: 'banter/messages.html',
|
293
|
+
controller: 'messagesController',
|
294
|
+
resolve: {
|
295
|
+
messages: messagesResolver
|
296
|
+
}
|
297
|
+
}).when("/subscribers/:subscriber/messages", {
|
298
|
+
templateUrl: 'banter/messages.html',
|
299
|
+
controller: 'messagesController',
|
300
|
+
resolve: {
|
301
|
+
messages: messagesResolver
|
302
|
+
}
|
303
|
+
}).when("/messages/:message_id", {
|
304
|
+
templateUrl: 'banter/message.html',
|
305
|
+
controller: 'messageController',
|
306
|
+
resolve: {
|
307
|
+
message: messageResolver
|
308
|
+
}
|
309
|
+
}).when("/messages", {
|
310
|
+
templateUrl: 'banter/messages.html',
|
311
|
+
controller: 'messagesController',
|
312
|
+
resolve: {
|
313
|
+
messages: messagesResolver
|
314
|
+
}
|
315
|
+
}).when("/subscribers", {
|
316
|
+
templateUrl: 'banter/subscribers.html',
|
317
|
+
controller: 'subscribersController',
|
318
|
+
resolve: {
|
319
|
+
subscribers: subscribersResolver
|
320
|
+
}
|
321
|
+
}).otherwise({
|
322
|
+
redirectTo: "/"
|
323
|
+
});
|
324
|
+
return $locationProvider.html5Mode(true);
|
325
|
+
}
|
326
|
+
]);
|
327
|
+
|
328
|
+
angular.module('dashboardApp').run([
|
329
|
+
'$rootScope', '$route', '$location', function($rootScope, $route, $location) {
|
330
|
+
return $rootScope.$on('$routeChangeStart', function(event, next, current) {
|
331
|
+
var _ref, _ref1;
|
332
|
+
if ((_ref = next.$$route) != null ? _ref.controller : void 0) {
|
333
|
+
$rootScope.$broadcast("start-" + next.$$route.controller);
|
334
|
+
}
|
335
|
+
if (current != null ? (_ref1 = current.$$route) != null ? _ref1.controller : void 0 : void 0) {
|
336
|
+
return $rootScope.$broadcast("stop-" + current.$$route.controller);
|
337
|
+
}
|
338
|
+
});
|
339
|
+
}
|
340
|
+
]);
|
341
|
+
|
342
|
+
}).call(this);
|
343
|
+
(function() {
|
344
|
+
angular.module('dashboardApp').service('commonMethodsService', [
|
345
|
+
function() {
|
346
|
+
this.setup = function(scope) {
|
347
|
+
return scope.asTime = function(time) {
|
348
|
+
return new Date(time);
|
349
|
+
};
|
350
|
+
};
|
351
|
+
}
|
352
|
+
]);
|
353
|
+
|
354
|
+
}).call(this);
|
355
|
+
(function() {
|
356
|
+
angular.module('dashboardApp').service('messageMethodsService', [
|
357
|
+
function() {
|
358
|
+
this.setup = function(scope) {
|
359
|
+
scope.isMessageFailed = function(message) {
|
360
|
+
return message.status === 'failed' || message.status === 'validation_failed';
|
361
|
+
};
|
362
|
+
scope.timeElapsed = function(message) {
|
363
|
+
if (!message.done_at) {
|
364
|
+
return 0;
|
365
|
+
}
|
366
|
+
return scope.asTime(message.done_at) - scope.asTime(message.started_at);
|
367
|
+
};
|
368
|
+
scope.isMessageExecuting = function(message) {
|
369
|
+
return scope.message.status === 'started';
|
370
|
+
};
|
371
|
+
return scope.isMessageSuccessful = function(message) {
|
372
|
+
return scope.message.status === 'success';
|
373
|
+
};
|
374
|
+
};
|
375
|
+
}
|
376
|
+
]);
|
377
|
+
|
378
|
+
}).call(this);
|
379
|
+
(function() {
|
380
|
+
angular.module('dashboardApp').service('messagesService', [
|
381
|
+
'$http', function($http) {
|
382
|
+
this.getMessages = function(page, workerId, subscriber) {
|
383
|
+
return $http({
|
384
|
+
method: 'get',
|
385
|
+
url: Banter.rootPath + "messages.json",
|
386
|
+
params: {
|
387
|
+
page: page,
|
388
|
+
worker_id: workerId,
|
389
|
+
subscriber: subscriber
|
390
|
+
}
|
391
|
+
});
|
392
|
+
};
|
393
|
+
this.getMessage = function(messageId) {
|
394
|
+
return $http({
|
395
|
+
method: 'get',
|
396
|
+
url: Banter.rootPath + ("messages/" + messageId + ".json")
|
397
|
+
});
|
398
|
+
};
|
399
|
+
}
|
400
|
+
]);
|
401
|
+
|
402
|
+
}).call(this);
|
403
|
+
(function() {
|
404
|
+
angular.module('dashboardApp').service('subscribersService', [
|
405
|
+
'$http', function($http) {
|
406
|
+
this.getIndex = function() {
|
407
|
+
return $http({
|
408
|
+
method: 'get',
|
409
|
+
url: Banter.rootPath + "subscribers.json"
|
410
|
+
});
|
411
|
+
};
|
412
|
+
}
|
413
|
+
]);
|
414
|
+
|
415
|
+
}).call(this);
|
416
|
+
(function() {
|
417
|
+
angular.module('dashboardApp').service('workerMethodsService', [
|
418
|
+
function() {
|
419
|
+
this.setup = function(scope) {
|
420
|
+
scope.isWorkerExecuting = function(worker) {
|
421
|
+
return worker != null ? worker.current_message : void 0;
|
422
|
+
};
|
423
|
+
return scope.isWorkerAlive = function(worker) {
|
424
|
+
return !(worker != null ? worker.stopped_at : void 0);
|
425
|
+
};
|
426
|
+
};
|
427
|
+
}
|
428
|
+
]);
|
429
|
+
|
430
|
+
}).call(this);
|
431
|
+
(function() {
|
432
|
+
angular.module('dashboardApp').service('workersService', [
|
433
|
+
'$http', function($http) {
|
434
|
+
this.getCurrentList = function() {
|
435
|
+
return $http({
|
436
|
+
method: 'get',
|
437
|
+
url: Banter.rootPath + "workers.json"
|
438
|
+
});
|
439
|
+
};
|
440
|
+
this.getWorker = function(workerId) {
|
441
|
+
return $http({
|
442
|
+
method: 'get',
|
443
|
+
url: "" + Banter.rootPath + "workers/" + workerId + ".json"
|
444
|
+
});
|
445
|
+
};
|
446
|
+
}
|
447
|
+
]);
|
448
|
+
|
449
|
+
}).call(this);
|