gricer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +84 -0
  3. data/Rakefile +49 -0
  4. data/app/assets/images/gricer/fluid/breadcrumb.png +0 -0
  5. data/app/assets/javascripts/gricer.js.coffee +85 -0
  6. data/app/assets/javascripts/gricer_backend_jquery.js.coffee +352 -0
  7. data/app/assets/javascripts/jquery.flot.js +2599 -0
  8. data/app/assets/javascripts/jquery.flot.pie.js +750 -0
  9. data/app/assets/javascripts/jquery.flot.resize.js +60 -0
  10. data/app/assets/javascripts/jquery.flot.symbol.js +70 -0
  11. data/app/assets/javascripts/worldmap.js +146 -0
  12. data/app/assets/stylesheets/gricer/fluid-jquery-ui.css.scss +1298 -0
  13. data/app/assets/stylesheets/gricer/fluid.css.scss +240 -0
  14. data/app/assets/stylesheets/gricer/helpers/css3.css.scss +21 -0
  15. data/app/controllers/gricer/base_controller.rb +141 -0
  16. data/app/controllers/gricer/capture_controller.rb +42 -0
  17. data/app/controllers/gricer/dashboard_controller.rb +18 -0
  18. data/app/controllers/gricer/requests_controller.rb +42 -0
  19. data/app/controllers/gricer/sessions_controller.rb +24 -0
  20. data/app/helpers/gricer/base_helper.rb +22 -0
  21. data/app/models/gricer/agent.rb +789 -0
  22. data/app/models/gricer/request.rb +239 -0
  23. data/app/models/gricer/session.rb +433 -0
  24. data/app/views/gricer/capture/index.html.erb +1 -0
  25. data/app/views/gricer/dashboard/_menu.html.erb +10 -0
  26. data/app/views/gricer/dashboard/_overview.html.erb +33 -0
  27. data/app/views/gricer/dashboard/index.html.erb +19 -0
  28. data/config/routes.rb +51 -0
  29. data/lib/gricer.rb +36 -0
  30. data/lib/gricer/action_controller/base.rb +28 -0
  31. data/lib/gricer/action_controller/track.rb +132 -0
  32. data/lib/gricer/active_model/statistics.rb +167 -0
  33. data/lib/gricer/config.rb +125 -0
  34. data/lib/gricer/engine.rb +9 -0
  35. data/lib/gricer/localization.rb +3 -0
  36. data/lib/tasks/gricer_tasks.rake +92 -0
  37. data/spec/controllers/gricer/base_controller_spec.rb +207 -0
  38. data/spec/controllers/gricer/capture_controller_spec.rb +44 -0
  39. data/spec/controllers/gricer/dashboard_controller_spec.rb +44 -0
  40. data/spec/controllers/gricer/requests_controller_spec.rb +36 -0
  41. data/spec/controllers/gricer/sessions_controller_spec.rb +37 -0
  42. data/spec/dummy/Rakefile +7 -0
  43. data/spec/dummy/app/assets/javascripts/application.js +9 -0
  44. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  45. data/spec/dummy/app/assets/stylesheets/dashboard.css +4 -0
  46. data/spec/dummy/app/assets/stylesheets/scaffold.css +56 -0
  47. data/spec/dummy/app/assets/stylesheets/sessions.css +4 -0
  48. data/spec/dummy/app/controllers/application_controller.rb +23 -0
  49. data/spec/dummy/app/controllers/dashboard_controller.rb +19 -0
  50. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  51. data/spec/dummy/app/helpers/dashboard_helper.rb +2 -0
  52. data/spec/dummy/app/views/dashboard/index.html.erb +236 -0
  53. data/spec/dummy/app/views/layouts/application.html.erb +16 -0
  54. data/spec/dummy/config.ru +4 -0
  55. data/spec/dummy/config/application.rb +48 -0
  56. data/spec/dummy/config/boot.rb +10 -0
  57. data/spec/dummy/config/cucumber.yml +9 -0
  58. data/spec/dummy/config/database.yml +25 -0
  59. data/spec/dummy/config/environment.rb +5 -0
  60. data/spec/dummy/config/environments/development.rb +27 -0
  61. data/spec/dummy/config/environments/production.rb +51 -0
  62. data/spec/dummy/config/environments/test.rb +39 -0
  63. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  64. data/spec/dummy/config/initializers/inflections.rb +10 -0
  65. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  66. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  67. data/spec/dummy/config/initializers/session_store.rb +8 -0
  68. data/spec/dummy/config/initializers/wrap_parameters.rb +12 -0
  69. data/spec/dummy/config/locales/en.yml +5 -0
  70. data/spec/dummy/config/routes.rb +11 -0
  71. data/spec/dummy/db/schema.rb +241 -0
  72. data/spec/dummy/log/development.log +0 -0
  73. data/spec/dummy/public/404.html +26 -0
  74. data/spec/dummy/public/422.html +26 -0
  75. data/spec/dummy/public/500.html +26 -0
  76. data/spec/dummy/public/favicon.ico +0 -0
  77. data/spec/dummy/script/rails +6 -0
  78. data/spec/helpers/gricer/base_helper_spec.rb +28 -0
  79. data/spec/lib/gricer/action_controller/track_spec.rb +63 -0
  80. data/spec/models/gricer/agent_spec.rb +829 -0
  81. data/spec/models/gricer/request_spec.rb +145 -0
  82. data/spec/models/gricer/session_spec.rb +209 -0
  83. data/spec/routing/capture_routes_spec.rb +6 -0
  84. data/spec/routing/dashboard_routes_spec.rb +9 -0
  85. data/spec/routing/requests_routes_spec.rb +90 -0
  86. data/spec/routing/sessions_routes_spec.rb +115 -0
  87. data/spec/spec_helper.rb +23 -0
  88. metadata +185 -0
@@ -0,0 +1,240 @@
1
+ @import 'helpers/css3';
2
+
3
+ .gricer-stat {
4
+ position: absolute;
5
+ top: 0;
6
+ bottom: 0;
7
+ width: 100%;
8
+ overflow: none;
9
+ font-size: 11px;
10
+ line-height: 15px;
11
+ font-family: 'Lucida Grande', 'Arial', 'Helvetica', 'Sans-Serif';
12
+
13
+ #gricer-header {
14
+ background: #000;
15
+ color: #000;
16
+ line-height: 20px;
17
+ height: 20px;
18
+ background: #eee;
19
+ @include gradient(#eee,#ccc);
20
+
21
+ .path {
22
+ a {
23
+ display: block;
24
+ float: left;
25
+ color: #000;
26
+ background: image-url("gricer/fluid/breadcrumb.png") right top no-repeat;
27
+ height: 20px;
28
+ line-height: 20px;
29
+ padding: 0 15px 0 8px;
30
+ text-decoration: none;
31
+ }
32
+
33
+ a:last-child {
34
+ font-weight: bold;
35
+ }
36
+ }
37
+
38
+ .dates {
39
+ padding: 0 7px;
40
+ float: right;
41
+ input {
42
+ width: 8em;
43
+ height: 11px;
44
+ padding: 2px;
45
+ border: none;
46
+ background: transparent;
47
+ }
48
+ #gricer-from-field {
49
+ text-align: right;
50
+ }
51
+ }
52
+ }
53
+
54
+ #gricer-menu {
55
+ position: absolute;
56
+ float: left;
57
+ width: 182px;
58
+ padding: 4px 0;
59
+ background: #dfe4eb;
60
+ border-right: 1px solid #b4b4b4;
61
+ top: 20px;
62
+
63
+ bottom: 0;
64
+ overflow: auto;
65
+
66
+ a, span {
67
+ display: block;
68
+ text-decoration: none;
69
+ color: #000;
70
+ border-top: 1px solid transparent;
71
+ padding: 2px 8px;
72
+ &.active {
73
+ border-top: 1px solid #a3b1cc;
74
+ background: #94a6c5;
75
+ @include gradient(#b0bed7, #8195b8);
76
+ color: #fff;
77
+ }
78
+ }
79
+
80
+ span {
81
+ color: #999;
82
+ font-weight: bold;
83
+ }
84
+
85
+ div a {
86
+ padding-left: 16px;
87
+ }
88
+ }
89
+
90
+ #gricer-container
91
+ {
92
+ position: absolute;
93
+ float: left;
94
+ left: 183px;
95
+ top: 20px;
96
+ right: 0;
97
+ bottom: 0;
98
+ }
99
+
100
+
101
+ #gricer-container {
102
+
103
+ .overview {
104
+ position: absolute;
105
+ top: 0;
106
+ bottom: 0;
107
+ width: 100%;
108
+ overflow: auto;
109
+ padding: 4px 8px;
110
+ font-size: 30px;
111
+ line-height: 45px;
112
+ }
113
+
114
+ .flot-chart {
115
+ position: absolute;
116
+ background: #666f83;
117
+ color: #999;
118
+ top: 0;
119
+ left: 0;
120
+ right: 0;
121
+ padding: 0 2.5%;
122
+ height: 250px;
123
+ #flot-line-chart, #flot-pie-chart {
124
+ width: 100%;
125
+ height: 250px;
126
+ }
127
+
128
+ }
129
+
130
+ .type-selector {
131
+ position: absolute;
132
+ right: 4px;
133
+ top: 4px;
134
+
135
+ span, a {
136
+ padding: 2px 4px;
137
+ background: #ccc;
138
+ @include gradient(#ddd, #bbb);
139
+ border-right: 1px solid #b4b4b4;
140
+ color: #000;
141
+ text-decoration: none;
142
+ }
143
+
144
+ span {
145
+ background: #666;
146
+ @include gradient(#555, #777);
147
+ color: #fff;
148
+ }
149
+
150
+ span:first-child,
151
+ a:first-child {
152
+ @include border-radius(9px 0 0 9px);
153
+ padding-left: 9px;
154
+ }
155
+
156
+ span:last-child,
157
+ a:last-child {
158
+ @include border-radius(0 9px 9px 0);
159
+ border-right: none;
160
+ padding-right: 9px;
161
+ }
162
+ }
163
+
164
+ .data {
165
+ position: absolute;
166
+ top: 250px;
167
+ bottom: 0;
168
+ width: 100%;
169
+ overflow: auto;
170
+ }
171
+ table {
172
+ width: 100%;
173
+ padding: 0;
174
+ border-spacing: 0;
175
+ empty-cells: show;
176
+
177
+ th, td {
178
+ width: auto;
179
+ padding: 2px 4px;
180
+ font-size: 11px;
181
+
182
+ a {
183
+ color: #009;
184
+ text-decoration: none;
185
+ }
186
+
187
+ .badge {
188
+ float: left;
189
+ display: block;
190
+ @include border-radius(5px);
191
+ margin: 3px;
192
+ width: 10px;
193
+ height: 10px;
194
+ }
195
+ }
196
+
197
+ tr:nth-child(even) {
198
+ th, td {
199
+ background-color: #f3f5fa;
200
+ white-space: nowrap;
201
+ }
202
+ }
203
+
204
+ tr:first-child {
205
+ th {
206
+ background: #eee;
207
+ @include gradient(#ccc,#eee);
208
+ border-bottom: 1px solid #b4b4b4;
209
+ border-right: 1px solid #b4b4b4;
210
+ overflow: hidden;
211
+ white-space: nowrap;
212
+ }
213
+ }
214
+
215
+ th.number,
216
+ td.number {
217
+ text-align: right;
218
+ }
219
+
220
+ th.boolean,
221
+ td.boolean {
222
+ max-width: 30px;
223
+ }
224
+
225
+ td.boolean {
226
+ text-align: center;
227
+ }
228
+
229
+ &.process {
230
+ tr:nth-child(1) {
231
+ th {
232
+ text-align: center;
233
+ font-size: 9px;
234
+ lin-height: 11px;
235
+ }
236
+ }
237
+ }
238
+ }
239
+ }
240
+ }
@@ -0,0 +1,21 @@
1
+ @mixin border-radius($radius) {
2
+ -webkit-border-radius: $radius;
3
+ -moz-border-radius: $radius;
4
+ -o-border-radius: $radius;
5
+ -ms-border-radius: $radius;
6
+ -khtml-border-radius: $radius;
7
+ border-radius: $radius;
8
+ }
9
+
10
+ @mixin gradient($from, $to) {
11
+ background-image: -webkit-gradient(linear, left top, left bottom, from($from), to($to));
12
+ background-image: -moz-linear-gradient($from, $to);
13
+ background-image: linear-gradient($from, $to);
14
+ }
15
+
16
+ @mixin rotate($degree: -90deg) {
17
+ -moz-transform:rotate($degree);
18
+ -webkit-transform:rotate($degree);
19
+ -o-transform:rotate($degree);
20
+ transform:rotate($degree);
21
+ }
@@ -0,0 +1,141 @@
1
+ module Gricer
2
+ # This is the base controller which is used by Gricer's basic statistics controllers
3
+ #
4
+ # You can use this to make your own statistics controllers from a scaffold.
5
+ class BaseController < ::ApplicationController
6
+ before_filter :guess_from_thru
7
+ helper BaseHelper
8
+
9
+ layout ::Gricer.config.admin_layout if ::Gricer.config.admin_layout
10
+
11
+ # This action generates a JSON for a process statistics.
12
+ def process_stats
13
+ @items = basic_collection
14
+
15
+ handle_special_fields
16
+
17
+ data = {
18
+ alternatives: [
19
+ {
20
+ type: 'spread',
21
+ uri: url_for(action: "spread_stats", field: params[:field], filters: params[:filters], only_path: true)
22
+ },
23
+ {
24
+ type: 'process'
25
+ }
26
+ ],
27
+ from: @stat_from.to_time.utc.to_i * 1000,
28
+ thru: @stat_thru.to_time.utc.to_i * 1000,
29
+ step: @stat_step.to_i * 1000,
30
+ data: @items.stat(params[:field], @stat_from, @stat_thru, @stat_step)
31
+ }
32
+
33
+ if further_details.keys.include? params[:field]
34
+ filters = (params[:filters] || {})
35
+ filters[params[:field]] = '%{self}'
36
+
37
+ data[:detail_uri] = url_for(action: "process_stats", field: further_details[params[:field]], filters: filters, only_path: true)
38
+ end
39
+
40
+ render json: data
41
+ end
42
+
43
+ # This action generates a JSON for a spread statistics.
44
+ def spread_stats
45
+ @items = basic_collection.between_dates(@stat_from, @stat_thru)
46
+
47
+ handle_special_fields
48
+
49
+ data = {
50
+ alternatives: [
51
+ {
52
+ type: 'spread'
53
+ },
54
+ {
55
+ type: 'process',
56
+ uri: url_for(action: "process_stats", field: params[:field], filters: params[:filters], only_path: true)
57
+ }
58
+ ],
59
+ from: @stat_from.to_time.utc.to_i * 1000,
60
+ thru: @stat_thru.to_time.utc.to_i * 1000,
61
+ total: @items.count(:id),
62
+ data: @items.count_by(params[:field])
63
+ }
64
+
65
+ if further_details.keys.include? params[:field]
66
+ filters = (params[:filters] || {})
67
+ filters[params[:field]] = '%{self}'
68
+
69
+ data[:detail_uri] = url_for(action: "spread_stats", field: further_details[params[:field]], filters: filters, only_path: true)
70
+ end
71
+
72
+ render json: data
73
+ end
74
+
75
+ private
76
+ # @abstract
77
+ # Define which is the basic collection to be processed by the controller.
78
+ # This value has to be overwritten to use the process_stats or spread_stats actions.
79
+ def basic_collection
80
+ raise 'basic_collection must be defined'
81
+ end
82
+
83
+ # Define how to handle special fields
84
+ def handle_special_fields
85
+ if params[:filters]
86
+ params[:filters].each do |filter_attr, filter_value|
87
+ @items = @items.filter_by(filter_attr, filter_value)
88
+ end
89
+ end
90
+ end
91
+
92
+ # Define how to handle further details
93
+ def further_details
94
+ {}
95
+ end
96
+
97
+ # Guess for which time range to display statistics
98
+ def guess_from_thru
99
+ begin
100
+ @stat_thru = Time.parse(params[:thru]).to_date
101
+ rescue
102
+ end
103
+
104
+ begin
105
+ @stat_from = Time.parse(params[:from]).to_date
106
+ rescue
107
+ end
108
+
109
+ if @stat_from.nil?
110
+ if @stat_thru.nil?
111
+ @stat_thru = Time.now.localtime.to_date - 1.day
112
+ end
113
+ @stat_from = @stat_thru - 1.week + 1.day
114
+ else
115
+ if @stat_thru.nil?
116
+ @stat_thru = @stat_from + 1.week - 1.day
117
+ end
118
+ end
119
+
120
+ @stat_step = 1.day
121
+
122
+ duration = @stat_thru - @stat_from
123
+
124
+ if duration < 90
125
+ @stat_step = 12.hours
126
+ end
127
+
128
+ if duration < 30
129
+ @stat_step = 6.hour
130
+ end
131
+
132
+ if duration < 10
133
+ @stat_step = 1.hour
134
+ end
135
+
136
+ #if @stat_thru - @stat_from > 12.month
137
+ # @stat_step = 4.week
138
+ #end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,42 @@
1
+ module Gricer
2
+ # This is the controller to capture additional values from the Javascript track tag.
3
+ #
4
+ # @see Gricer::TrackHelper#gricer_track_tag
5
+ class CaptureController < ::ApplicationController
6
+ # This action stores the data submitted by the Javascript.
7
+ def index
8
+ gricer_request = Request.find_by_id(params[:id])
9
+ gricer_session = Session.find_by_id(session[:gricer_session])
10
+
11
+ if gricer_session
12
+ gricer_session.javascript = true
13
+ gricer_session.java = params[:j]
14
+ gricer_session.flash_version = params[:f] unless params[:f] == 'false'
15
+ gricer_session.silverlight_version = params[:sl] unless params[:sl] == 'false'
16
+ gricer_session.screen_width = params[:sx]
17
+ gricer_session.screen_height = params[:sy]
18
+ gricer_session.screen_size = "#{params[:sx]}x#{params[:sy]}" unless params[:sx].blank? or params[:sy].blank?
19
+ gricer_session.screen_depth = params[:sd]
20
+ gricer_session.save
21
+
22
+ if gricer_request and gricer_request.session == gricer_session
23
+
24
+ gricer_request.javascript = true
25
+ gricer_request.window_width = params[:wx]
26
+ gricer_request.window_height = params[:wy]
27
+
28
+ if gricer_request.save
29
+ render text: 'ok'
30
+ else
31
+ render text: 'session only', status: 500
32
+ end
33
+ return
34
+ else
35
+ render text: 'session only'
36
+ return
37
+ end
38
+ end
39
+ render text: 'failed', status: 500
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,18 @@
1
+ module Gricer
2
+ # This controller contains the dashboard for the administration view
3
+ class DashboardController < BaseController
4
+ # This action renders the frame for the statistics tool
5
+ def index
6
+ @sessions = Session.browsers.between_dates(@stat_from, @stat_thru)
7
+ @requests = Request.browsers.between_dates(@stat_from, @stat_thru)
8
+ end
9
+
10
+ # This action renderes the overview of some data in the statistics tool
11
+ def overview
12
+ @sessions = Session.browsers.between_dates(@stat_from, @stat_thru)
13
+ @requests = Request.browsers.between_dates(@stat_from, @stat_thru)
14
+
15
+ render partial: 'overview.html', locals: {sessions: @sessions, requests: @requests}
16
+ end
17
+ end
18
+ end