refinerycms-stats 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ module Admin
2
+ class StatsController < Admin::BaseController
3
+
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class Stat < ActiveRecord::Base
2
+
3
+ acts_as_indexed :fields => [:bidon]
4
+
5
+ validates :bidon, :presence => true, :uniqueness => true
6
+
7
+ end
@@ -0,0 +1,93 @@
1
+ <% content_for :after_javascript_libraries do %>
2
+ <%= javascript_include_tag 'https://www.google.com/jsapi' %>
3
+ <%= javascript_include_tag 'refinerycms-stat' %>
4
+ <%= javascript_include_tag 'refinerycms-stat-translate' %>
5
+ <% end %>
6
+
7
+ <div id="login" style="visibility:hidden;">
8
+ <form action='#'>
9
+ <span id='status'><%= t('.login_analytics_html', :analytics_page_code => RefinerySetting.find_or_set(:analytics_page_code, "UA-0000000-0")) %></span>
10
+ <br/>
11
+ <input id='buttonLogin' type='button' value='<%= t(".button_login_text") %>'/>
12
+ </form>
13
+ </div>
14
+ <div id="logged" style="visibility:hidden;">
15
+ <%= t('.link_analytics_html') %>
16
+ <div id="tabs">
17
+ <ul>
18
+ <li><a href="#tabs-1"><%= t('.title_page_views') %></a></li>
19
+ <li><a href="#tabs-2"><%= t('.title_visits') %></a></li>
20
+ <li><a href="#tabs-3"><%= t('.title_visitors') %></a></li>
21
+ <li><a href="#tabs-4"><%= t('.title_average_time') %></a></li>
22
+ <li><a href="#tabs-5"><%= t('.title_source') %></a></li>
23
+ <li><a href="#tabs-6"><%= t('.title_keywords') %></a></li>
24
+ </ul>
25
+ <div id="page_part_editors">
26
+ <div id="tabs-1" class="stat">
27
+ <div id='pageViewsTableDiv'></div>
28
+ <div id='pageViewsColumnChartDiv' style="display:inline"></div>
29
+ <div id='pageViewsChartDiv' style="display:inline"></div>
30
+ </div>
31
+ <div id="tabs-2" class="stat">
32
+ <table>
33
+ <tr>
34
+ <td><div id='visitsTableDiv' style="display:inline"></div></td>
35
+ <td><div id='visitsLineChartDiv' style="display:inline"></div></td>
36
+ </tr>
37
+ </table>
38
+ </div>
39
+ <div id="tabs-3" class="stat">
40
+ <table>
41
+ <tr>
42
+ <td><div id='visitorsTableDiv' style="display:inline"></div></td>
43
+ <td><div id='visitorsLineChartDiv' style="display:inline"></div></td>
44
+ </tr>
45
+ </table>
46
+ </div>
47
+ <div id="tabs-4" class="stat">
48
+ <table>
49
+ <tr>
50
+ <td><div id='timesOnSiteTableDiv' style="display:inline"></div></td>
51
+ <td><div id='timesOnSiteLineChartDiv' style="display:inline"></div></td>
52
+ </tr>
53
+ </table>
54
+ </div>
55
+ <div id="tabs-5" class="stat">
56
+ <table>
57
+ <tr>
58
+ <td><div id='sourceTableDiv' style="display:inline"></div></td>
59
+ <td><div id='sourcePieChartDiv' style="display:inline"></div></td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <div id="tabs-6" class="stat">
64
+ <table>
65
+ <tr>
66
+ <td><div id='keywordTableDiv' style="display:inline"></div></td>
67
+ <td><div id='keywordPieChartDiv' style="display:inline"></div></td>
68
+ </tr>
69
+ </table>
70
+ </div>
71
+ </div>
72
+ <!-- For the API to work in IE, an image must be requested from the same
73
+ domain the script is hosted on. The image doesn't actually have
74
+ to exist, just be requested. More info here :
75
+ http://code.google.com/apis/gdata/client-js.html
76
+ -->
77
+ <img style='visibility:hidden' src='__utm.gif' alt='required for GData'/>
78
+ </div>
79
+
80
+ <% content_for :javascripts do %>
81
+ <script>
82
+ $(document).ready(function(){
83
+ $(function() {
84
+ $( "#tabs" ).tabs();
85
+ });
86
+ collectStatsData('<%= RefinerySetting.find_or_set(:analytics_page_code, "UA-0000000-0") %>');
87
+ });
88
+ </script>
89
+ <% end %>
90
+
91
+ <% content_for :stylesheets do %>
92
+ <%= stylesheet_link_tag 'stat' %>
93
+ <% end %>
@@ -0,0 +1,16 @@
1
+ en:
2
+ plugins:
3
+ stats:
4
+ title: Stats
5
+ admin:
6
+ stats:
7
+ index:
8
+ title_keywords: Keywords
9
+ title_page_views: Page views
10
+ title_source: Source
11
+ title_visitors: Visitors
12
+ title_visits: Visits
13
+ title_average_time: Average time
14
+ link_analytics_html: "You can view more data on the Google Analitycs site : <a href='https://www.google.com/analytics/'>https://www.google.com/analytics/</a><br/>."
15
+ login_analytics_html: "You need access to your Google Analytics data for this site.<br/>The code of your site for Google Analytics is : %{analytics_page_code}.<br/>You can change this code in <a href='/refinery/settings?search=analytics_page_code'>your settings</a>."
16
+ button_login_text: "Validate"
@@ -0,0 +1,16 @@
1
+ fr:
2
+ plugins:
3
+ stats:
4
+ title: Statistiques
5
+ admin:
6
+ stats:
7
+ index:
8
+ title_keywords: Mot clés
9
+ title_page_views: Pages Vues
10
+ title_source: Sources
11
+ title_visitors: Visiteurs
12
+ title_visits: Visites
13
+ title_average_time: Temps moyen
14
+ link_analytics_html: "Vous pouvez consulter plus de données sur le site de Google Analitycs : <a href='https://www.google.com/analytics/'>https://www.google.com/analytics/</a><br/>."
15
+ login_analytics_html: "Vous devez autoriser l'accés à vos données Google Analytics pour ce site.<br/>Le code de votre site pour Google Analytics est : %{analytics_page_code}.<br/>Vous pouvez modifier ce code dans <a href='/refinery/settings?search=analytics_page_code'>vos paramètres</a>."
16
+ button_login_text: "Valider"
@@ -0,0 +1,11 @@
1
+ ::Refinery::Application.routes.draw do
2
+ resources :stats, :only => [:index, :show]
3
+
4
+ scope(:path => 'refinery', :as => 'admin', :module => 'admin') do
5
+ resources :stats, :except => :show do
6
+ collection do
7
+ post :update_positions
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,6 @@
1
+ class RefinerycmsStats < Refinery::Generators::EngineInstaller
2
+
3
+ source_root File.expand_path('../../../', __FILE__)
4
+ engine_name "stats"
5
+
6
+ end
@@ -0,0 +1,20 @@
1
+ require 'refinerycms-base'
2
+
3
+ module Refinery
4
+ module Stats
5
+ class Engine < Rails::Engine
6
+ initializer "static assets" do |app|
7
+ app.middleware.insert_after ::ActionDispatch::Static, ::ActionDispatch::Static, "#{root}/public"
8
+ end
9
+
10
+ config.after_initialize do
11
+ Refinery::Plugin.register do |plugin|
12
+ plugin.name = "stats"
13
+ plugin.activity = {
14
+ :class => Stat
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ namespace :refinery do
2
+
3
+ namespace :stats do
4
+
5
+ # call this task my running: rake refinery:stats:my_task
6
+ # desc "Description of my task below"
7
+ # task :my_task => :environment do
8
+ # # add your logic here
9
+ # end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,33 @@
1
+ var I18n = I18n || {};
2
+ I18n.translations = {
3
+ "en":{
4
+ "admin":{
5
+ "stats":{
6
+ "title":"Title",
7
+ "visits":"Visits",
8
+ "visitors":"Visitors",
9
+ "page_views": "Page Views",
10
+ "keywords": "Keywords",
11
+ "date": "Date",
12
+ "average_time": "Average time",
13
+ "source": "Source",
14
+ "path": "Path"
15
+ }
16
+ }
17
+ },
18
+ "fr":{
19
+ "admin":{
20
+ "stats":{
21
+ "title":"Titre",
22
+ "visits":"Visites",
23
+ "visitors":"Visiteurs",
24
+ "page_views": "Pages Vues",
25
+ "keywords": "Mots clés",
26
+ "date": "Date",
27
+ "average_time": "Temps moyen",
28
+ "source": "Source",
29
+ "path": "Chemin"
30
+ }
31
+ }
32
+ }
33
+ };
@@ -0,0 +1,446 @@
1
+ // Copyright 2009 Google Inc. All Rights Reserved.
2
+
3
+ /* Licensed under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License.
5
+ * You may obtain a copy of the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS,
11
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ * See the License for the specific language governing permissions and
13
+ * limitations under the License.
14
+ */
15
+ /**
16
+ * @fileoverview A very simple demo showing how easy it is to visualize
17
+ * GA data in the Google Visualization API. In this demo we show the
18
+ * top 10 tracked pages tiles and page URIs by pageviews in a
19
+ * Gviz Table, Pie Chart and Column Chart.
20
+ */
21
+
22
+ var myService;
23
+ var dataTable;
24
+ var pageViewsTable;
25
+ var pageViewsChart;
26
+ var pageViewsColumnChart;
27
+ var visitsLineChart;
28
+ var visitsTable;
29
+ var timesOnSiteLineChart;
30
+ var timesOnSiteTable;
31
+ var sourcePieChart;
32
+ var sourceTable;
33
+ var keywordPieChart;
34
+ var keywordTable;
35
+ var scope = 'https://www.google.com/analytics/feeds';
36
+ var profileId;
37
+ var pageCode;
38
+
39
+ /**
40
+ * Initialize all the objects from the Google AJAX Apis once they
41
+ * have been loaded and are ready to use.
42
+ */
43
+ function collectStatsData(pageCodeArg) {
44
+ var divLogin = document.getElementById('login');
45
+ var divLogged = document.getElementById('logged');
46
+ divLogin.style.visibility = 'hidden';
47
+ divLogged.style.visibility = 'hidden';
48
+
49
+ if (google.accounts.user.checkLogin(scope)) {
50
+ divLogin.style.visibility = 'hidden';
51
+ divLogged.style.visibility = 'visible';
52
+ divLogged.style.position = 'relative';
53
+ divLogged.style.position = "relative";
54
+ divLogged.style.top = -divLogin.offsetHeight+"px";
55
+
56
+ pageCode = pageCodeArg;
57
+ myService = new google.gdata.analytics.AnalyticsService('gaExportAPI_gViz_v1.0');
58
+ pageViewsTable = new google.visualization.Table(document.getElementById('pageViewsTableDiv'));
59
+ pageViewsChart = new google.visualization.PieChart(document.getElementById('pageViewsChartDiv'));
60
+ pageViewsColumnChart = new google.visualization.ColumnChart(document.getElementById('pageViewsColumnChartDiv'));
61
+
62
+
63
+ sourcePieChart = new google.visualization.PieChart(document.getElementById('sourcePieChartDiv'));
64
+ sourceTable = new google.visualization.Table(document.getElementById('sourceTableDiv'));
65
+
66
+ keywordPieChart = new google.visualization.PieChart(document.getElementById('keywordPieChartDiv'));
67
+ keywordTable = new google.visualization.Table(document.getElementById('keywordTableDiv'));
68
+
69
+ visitsLineChart = new google.visualization.LineChart(document.getElementById('visitsLineChartDiv'));
70
+ visitsTable = new google.visualization.Table(document.getElementById('visitsTableDiv'));
71
+
72
+ visitorsLineChart = new google.visualization.LineChart(document.getElementById('visitorsLineChartDiv'));
73
+ visitorsTable = new google.visualization.Table(document.getElementById('visitorsTableDiv'));
74
+
75
+ timesOnSiteLineChart = new google.visualization.LineChart(document.getElementById('timesOnSiteLineChartDiv'));
76
+ timesOnSiteTable = new google.visualization.Table(document.getElementById('timesOnSiteTableDiv'));
77
+
78
+ getWebPropertyFeed();
79
+ } else {
80
+ divLogin.style.visibility = 'visible';
81
+ divLogged.style.visibility = 'hidden';
82
+ document.getElementById('buttonLogin').onclick = handleLogin;
83
+ }
84
+ }
85
+
86
+ function handleLogin() {
87
+ google.accounts.user.login(scope);
88
+ }
89
+
90
+ function getWebPropertyFeed() {
91
+ var webPropertyFeedUri = [scope, '/datasources/ga/accounts/',pageCode.split('-')[1],'/webproperties/',pageCode,'/profiles'].join('');
92
+
93
+ // Send asynchronous request to the Management API.
94
+ myService.getManagementFeed(webPropertyFeedUri, printWebPropertyFeed,handleError);
95
+ }
96
+
97
+ function printWebPropertyFeed(result) {
98
+ var feed = result.feed;
99
+ var entries = feed.getEntries();
100
+ var GAProfileId;
101
+ if (entries.length) {
102
+ for (var i = 0, entry; entry = entries[i]; ++i) {
103
+ GAProfileId = entry.getPropertyValue('ga:profileId');
104
+ }
105
+ }
106
+ profileId = GAProfileId;
107
+ getPageViewsDataFeed();
108
+ getVisitsDataFeed();
109
+ getVisitorsDataFeed();
110
+ getTimeOnSiteDataFeed();
111
+ getSourceDataFeed();
112
+ getKeywordDataFeed();
113
+ }
114
+
115
+ function getDateConditions() {
116
+ var toDay = new Date();
117
+ var lastMonth = new Date (toDay.getFullYear(), toDay.getMonth()-1, toDay.getDate());
118
+
119
+ var lastMonthStr;
120
+ if ((lastMonth.getMonth() + 1) < 10) {
121
+ lastMonthStr = '0'+(lastMonth.getMonth() + 1);
122
+ } else {
123
+ lastMonthStr = (lastMonth.getMonth() + 1);
124
+ }
125
+
126
+ var lastMonthDayStr;
127
+ if (lastMonth.getDate() < 10) {
128
+ lastMonthDayStr = '0'+(lastMonth.getDate());
129
+ } else {
130
+ lastMonthDayStr = (lastMonth.getDate());
131
+ }
132
+
133
+ var currentMonthStr;
134
+ if ((toDay.getMonth() + 1) < 10) {
135
+ currentMonthStr = '0'+(toDay.getMonth() + 1);
136
+ } else {
137
+ currentMonthStr = (toDay.getMonth() + 1);
138
+ }
139
+
140
+ var currentMonthDayStr;
141
+ if (toDay.getDate() < 10) {
142
+ currentMonthDayStr = '0'+(toDay.getDate());
143
+ } else {
144
+ currentMonthDayStr = (toDay.getDate());
145
+ }
146
+
147
+ var conditions = '?start-date='+ lastMonth.getFullYear() + '-' + lastMonthStr + '-' + lastMonthDayStr + '&end-date='+ toDay.getFullYear() + '-' + currentMonthStr + '-' + currentMonthDayStr
148
+
149
+ return conditions;
150
+ }
151
+
152
+ /**
153
+ * Request data from GA Export API
154
+ */
155
+ function getPageViewsDataFeed() {
156
+ var myFeedUri = scope + '/data' + getDateConditions() +
157
+ '&dimensions=ga:pageTitle,ga:pagePath' +
158
+ '&metrics=ga:pageviews' +
159
+ '&sort=-ga:pageviews' +
160
+ '&max-results=10' +
161
+ '&ids=ga:' + profileId;
162
+
163
+ myService.getDataFeed(myFeedUri, handlePageViewsDataFeed, handleError);
164
+ }
165
+
166
+ /**
167
+ * Request data from GA Export API
168
+ */
169
+ function getVisitsDataFeed() {
170
+ var myFeedUri = scope + '/data' + getDateConditions() +
171
+ '&dimensions=ga:day,ga:year,ga:month,ga:date' +
172
+ '&metrics=ga:visits' +
173
+ '&sort=ga:date' +
174
+ '&ids=ga:' + profileId;
175
+
176
+ myService.getDataFeed(myFeedUri, handleVisitsDataFeed, handleError);
177
+ }
178
+
179
+ /**
180
+ * Request data from GA Export API
181
+ */
182
+ function getVisitorsDataFeed() {
183
+ var myFeedUri = scope + '/data' + getDateConditions() +
184
+ '&dimensions=ga:day,ga:year,ga:month,ga:date' +
185
+ '&metrics=ga:visitors' +
186
+ '&sort=ga:date' +
187
+ '&ids=ga:' + profileId;
188
+
189
+ myService.getDataFeed(myFeedUri, handleVisitorsDataFeed, handleError);
190
+ }
191
+
192
+ /**
193
+ * Request data from GA Export API
194
+ */
195
+ function getTimeOnSiteDataFeed() {
196
+ var myFeedUri = scope + '/data' + getDateConditions() +
197
+ '&dimensions=ga:day,ga:year,ga:month,ga:date' +
198
+ '&metrics=ga:timeOnSite,ga:visits' +
199
+ '&sort=ga:date' +
200
+ '&ids=ga:' + profileId;
201
+
202
+ myService.getDataFeed(myFeedUri, handleTimeOnSiteDataFeed, handleError);
203
+ }
204
+
205
+ /**
206
+ * Request data from GA Export API
207
+ */
208
+ function getSourceDataFeed() {
209
+ var myFeedUri = scope + '/data' + getDateConditions() +
210
+ '&dimensions=ga:source' +
211
+ '&metrics=ga:visits' +
212
+ '&sort=-ga:visits' +
213
+ '&max-results=20' +
214
+ '&ids=ga:' + profileId;
215
+
216
+ myService.getDataFeed(myFeedUri, handleSourceDataFeed, handleError);
217
+ }
218
+
219
+ /**
220
+ * Request data from GA Export API
221
+ */
222
+ function getKeywordDataFeed() {
223
+ var myFeedUri = scope + '/data' + getDateConditions() +
224
+ '&dimensions=ga:keyword' +
225
+ '&metrics=ga:visits' +
226
+ '&sort=-ga:visits' +
227
+ '&max-results=20' +
228
+ '&ids=ga:' + profileId;
229
+
230
+ myService.getDataFeed(myFeedUri, handleKeywordDataFeed, handleError);
231
+ }
232
+
233
+ /**
234
+ * Handle and display any error that occurs from the API request.
235
+ * @param {Object} e The error object returned by the Analytics API.
236
+ */
237
+ function handleError(e) {
238
+ var msg = e.cause ? e.cause.statusText : e.message;
239
+ msg = 'ERROR: ' + msg;
240
+ alert(msg);
241
+ }
242
+
243
+ /**
244
+ * Handle all the data returned by GA Export API.
245
+ * Delete existing GViz dataTable before creating a new one.
246
+ * @param {Object} myResultsFeedRoot the feed object
247
+ * retuned by the data feed.
248
+ */
249
+ function handlePageViewsDataFeed(resultsFeedRoot) {
250
+ dataTable = new google.visualization.DataTable();
251
+ fillPageViewsDataTable(dataTable, resultsFeedRoot);
252
+ pageViewsTable.draw(dataTable);
253
+
254
+ // remove the URI column to only graph 1 dimension
255
+ dataTable.removeColumn(0);
256
+ pageViewsChart.draw(dataTable, {width: 950, height: 400});
257
+ pageViewsColumnChart.draw(dataTable, {width: 950, height: 300, legend: 'none'});
258
+ }
259
+
260
+ /**
261
+ * Handle all the data returned by GA Export API.
262
+ * Delete existing GViz dataTable before creating a new one.
263
+ * @param {Object} myResultsFeedRoot the feed object
264
+ * retuned by the data feed.
265
+ */
266
+ function handleVisitsDataFeed(resultsFeedRoot) {
267
+ dataTable = new google.visualization.DataTable();
268
+ fillVisitsDataTable(dataTable, resultsFeedRoot);
269
+ visitsLineChart.draw(dataTable, {width: 750, height: 500, legend: 'none'});
270
+ visitsTable.draw(dataTable);
271
+ }
272
+
273
+ function handleVisitorsDataFeed(resultsFeedRoot) {
274
+ dataTable = new google.visualization.DataTable();
275
+ fillVisitorsDataTable(dataTable, resultsFeedRoot);
276
+ visitorsLineChart.draw(dataTable, {width: 750, height: 500, legend: 'none'});
277
+ visitorsTable.draw(dataTable);
278
+ }
279
+
280
+ function handleTimeOnSiteDataFeed(resultsFeedRoot) {
281
+ dataTable = new google.visualization.DataTable();
282
+ fillTimesOnSiteDataTable(dataTable, resultsFeedRoot);
283
+ timesOnSiteLineChart.draw(dataTable, {width: 750, height: 500, legend: 'none'});
284
+ timesOnSiteTable.draw(dataTable);
285
+ }
286
+
287
+ function handleSourceDataFeed(resultsFeedRoot) {
288
+ dataTable = new google.visualization.DataTable();
289
+ fillSourceDataTable(dataTable, resultsFeedRoot);
290
+ sourcePieChart.draw(dataTable, {width: 600, height: 400, legend: 'none'});
291
+ sourceTable.draw(dataTable);
292
+ }
293
+
294
+ function handleKeywordDataFeed(resultsFeedRoot) {
295
+ dataTable = new google.visualization.DataTable();
296
+ fillKeywordDataTable(dataTable, resultsFeedRoot);
297
+ keywordPieChart.draw(dataTable, {width: 600, height: 400, legend: 'none'});
298
+ keywordTable.draw(dataTable);
299
+ }
300
+
301
+ /**
302
+ * Put the feed result into a GViz Data Table.
303
+ * @param {Object} dataTable the GViz dataTable
304
+ dataTable.setCell(0, 1, '0'); object to put data into.
305
+ * @param {Object} myResultsFeedRoot the feed returned by the GA Export API.
306
+ * @return {Objcet} GViz DataTable object.
307
+ */
308
+ function fillPageViewsDataTable(dataTable, myResultsFeedRoot) {
309
+ var entries = myResultsFeedRoot.feed.getEntries();
310
+
311
+ var datas = getGADatasInTable(entries, ['pageTitle','pagePath','pageviews']);
312
+ fillDataTable(entries, dataTable, [['string', I18n.t('admin.stats.title'), datas[0]],['string', I18n.t('admin.stats.path'), datas[1]],['number', I18n.t('admin.stats.page_views'), datas[2]]]);
313
+ }
314
+
315
+ function fillKeywordDataTable(dataTable, myResultsFeedRoot) {
316
+ var entries = myResultsFeedRoot.feed.getEntries();
317
+ var keywords = new Array();
318
+ var visits = new Array();
319
+
320
+ for (var i = 0, entry; entry = entries[i]; ++i) {
321
+
322
+ if (entry.getValueOf('ga:keyword') != '(not set)') {
323
+ keywords.push(entry.getValueOf('ga:keyword'));
324
+ visits.push(entry.getValueOf('ga:visits'));
325
+ }
326
+ }
327
+
328
+ fillDataTable(entries, dataTable, [['string', I18n.t('admin.stats.keywords'), keywords],['number', I18n.t('admin.stats.visits'), visits]]);
329
+ dataTable.removeRow(dataTable.getNumberOfRows()-1);
330
+ }
331
+
332
+ function fillSourceDataTable(dataTable, myResultsFeedRoot) {
333
+ var entries = myResultsFeedRoot.feed.getEntries();
334
+ var dates = new Array();
335
+
336
+ var datas = getGADatasInTable(entries, ['source', 'visits']);
337
+ fillDataTable(entries, dataTable, [['string', I18n.t('admin.stats.source'), datas[0]],['number', I18n.t('admin.stats.visits'), datas[1]]]);
338
+ }
339
+
340
+ function fillVisitsDataTable(dataTable, myResultsFeedRoot) {
341
+ var entries = myResultsFeedRoot.feed.getEntries();
342
+ var dates = new Array();
343
+
344
+ var datas = getGADatasInTable(entries, ['visits'], dates);
345
+ fillDataTable(entries, dataTable, [['string', I18n.t('admin.stats.date'), dates],['number', I18n.t('admin.stats.visits'), datas[0]]]);
346
+ }
347
+
348
+ function fillVisitorsDataTable(dataTable, myResultsFeedRoot) {
349
+ var entries = myResultsFeedRoot.feed.getEntries();
350
+ var dates = new Array();
351
+
352
+ var datas = getGADatasInTable(entries, ['visitors'], dates);
353
+ fillDataTable(entries, dataTable, [['string',I18n.t('admin.stats.date'), dates],['number', I18n.t('admin.stats.visitors'), datas[0]]]);
354
+ }
355
+
356
+ function fillTimesOnSiteDataTable(dataTable, myResultsFeedRoot) {
357
+ var entries = myResultsFeedRoot.feed.getEntries();
358
+ var timesOnSite = new Array();
359
+ var dates = new Array();
360
+
361
+ for (var i = 0, entry; entry = entries[i]; ++i) {
362
+ fillDate(entry, timesOnSite, dates);
363
+
364
+ if (entry.getValueOf('ga:visits') != 0) {
365
+ timesOnSite.push(entry.getValueOf('ga:timeOnSite') / entry.getValueOf('ga:visits'));
366
+ } else {
367
+ timesOnSite.push(0);
368
+ }
369
+ }
370
+
371
+ for (var i = 0; i < timesOnSite.length ; ++i) {
372
+ timesOnSite[i] = Math.round(timesOnSite[i] / 60);
373
+ }
374
+
375
+ convertDates(dates);
376
+
377
+ fillDataTable(entries, dataTable, [['string',I18n.t('admin.stats.date'), dates],['number', I18n.t('admin.stats.average_time'), timesOnSite]]);
378
+ }
379
+
380
+ function fillDate(entry, dataTable, dateTable) {
381
+ var date = new Date(entry.getValueOf('ga:year'), entry.getValueOf('ga:month')-1, entry.getValueOf('ga:day'));
382
+
383
+ // At the beginning of each day, check if data was missing for previous
384
+ // day. Insert "0" in appropriate visitor's array as necessary, using
385
+ // fillToSameSize helper method.
386
+ var lastDate = dateTable[dateTable.length - 1];
387
+ if(lastDate) {
388
+ while (Date.parse(date) != Date.parse(lastDate)) {
389
+ lastDate = new Date (lastDate.getFullYear(), lastDate.getMonth(), lastDate.getDate() + 1);
390
+ if (Date.parse(date) != Date.parse(lastDate)) {
391
+ dataTable.push(0);
392
+ dateTable.push(lastDate);
393
+ }
394
+ }
395
+ }
396
+
397
+ dateTable.push(date);
398
+ }
399
+
400
+ function fillDataTable(entries, dataTable, datas) {
401
+ for (var i = 0; i < datas.length; i++) {
402
+ dataTable.addColumn(datas[i][0], datas[i][1]);
403
+ }
404
+
405
+ dataTable.addRows(entries.length);
406
+
407
+ for (var idx = 0; idx < entries.length; idx++) {
408
+ var entry = entries[idx];
409
+ for (var i = 0; i < datas.length; i++) {
410
+ dataTable.setCell(idx, i, datas[i][2][idx]);
411
+ }
412
+ }
413
+ }
414
+
415
+ function getGADatasInTable(entries, datas, dates) {
416
+ var results = new Array();
417
+
418
+ for (var idx = 0; idx < entries.length; idx++) {
419
+ var entry = entries[idx];
420
+ for (var i = 0; i <datas.length; i++) {
421
+ results.push(new Array());
422
+ var GAData = entry.getValueOf('ga:'+datas[i]);
423
+ if (dates) {
424
+ fillDate(entry, results[i], dates);
425
+ }
426
+ results[i].push(GAData);
427
+ }
428
+ }
429
+
430
+ convertDates(dates);
431
+ return results
432
+ }
433
+
434
+ function convertDates(dates) {
435
+ if (dates) {
436
+ for (var i = 0; i < dates.length; i++) {
437
+ dates[i] = dates[i].toLocaleString().substr(0,10);
438
+ }
439
+ }
440
+ }
441
+
442
+ // Load the Google Visualization API client Libraries
443
+ google.load('visualization', '1', {packages: ['piechart', 'table', 'columnchart', 'linechart']});
444
+
445
+ // Load the Google data JavaScript client library
446
+ google.load('gdata', '2.x', {packages: ['analytics']});
@@ -0,0 +1,14 @@
1
+ div.stat {
2
+ width: 958px;
3
+ opacity: 1;
4
+ border-bottom-left-radius: 5px;
5
+ border-bottom-right-radius: 5px;
6
+ border-top-right-radius: 5px;
7
+ background: none repeat scroll 0 0 #FFFFFF;
8
+ border: 1px solid #CCCCCC;
9
+ padding: 5px 5px 0;
10
+ }
11
+
12
+ .ui-tabs-nav {
13
+ padding: 0px;
14
+ }
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: refinerycms-stats
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: "0.1"
6
+ platform: ruby
7
+ authors:
8
+ - Guirec CORBEL
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-26 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: Ruby on Rails Stats engine for Refinery CMS
17
+ email: guirec.corbel@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/generators/refinerycms_stats_generator.rb
26
+ - lib/refinerycms-stats.rb
27
+ - lib/tasks/stats.rake
28
+ - config/locales/en.yml
29
+ - config/locales/fr.yml
30
+ - config/routes.rb
31
+ - app/controllers/admin/stats_controller.rb
32
+ - app/models/stat.rb
33
+ - app/views/admin/stats/index.html.erb
34
+ - public/javascripts/refinerycms-stat-translate.js
35
+ - public/javascripts/refinerycms-stat.js
36
+ - public/stylesheets/stat.css
37
+ homepage: http://www.guirec-corbel.com
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ requirements: []
58
+
59
+ rubyforge_project:
60
+ rubygems_version: 1.8.5
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Stats engine for Refinery CMS
64
+ test_files: []
65
+