]> git.r.bdr.sh - rbdr/cologne/blob - lib/formatters/event_tracker.js
53cef9573ebf290e102ed25878b5efb1885fdf5b
[rbdr/cologne] / lib / formatters / event_tracker.js
1 (function (global) {
2 var Module;
3
4 // Load up dependencies
5 if (typeof require === 'function') {
6 var Ne = require('neon');
7 Module = Ne.Module;
8 } else {
9 Module = global.Module;
10 }
11
12 var Cobalt = {};
13 Module(Cobalt, 'Formatter')({});
14
15 Cobalt.Formatter.EventTracker = Module(Cobalt.Formatter, 'EventTracker')({
16
17 // Main formatter entry point, validate type and send to proper format
18 // method
19 format : function (logObject) {
20 switch(this._validateFormat(logObject)){
21 case 'error':
22 return this._formatError(logObject);
23 break;
24 case 'event':
25 logObject._type = 'event';
26 return this._formatEvent(logObject);
27 break;
28 }
29 return undefined;
30 },
31
32 // Format error
33 _formatError : function (logObject) {
34 var errorObject;
35
36 errorObject = logObject.error;
37 errorObject._type = 'error';
38
39 if (typeof Client !== 'undefined') {
40 errorObject.site_id = Client.pageInfo.site.id;
41 }else if (global.data && global.data.site && global.data.site.id) {
42 errorObject.site_id = global.data.site.id;
43 }
44 errorObject.scoped_class_name = errorObject.meta.scopedClassName;
45 errorObject.user_agent = global.navigator.userAgent;
46
47 return errorObject;
48 },
49
50 // Format the event
51 _formatEvent : function (logObject) {
52 var eventToSend;
53
54 eventToSend = this._createStructure(logObject);
55
56 return eventToSend;
57 },
58
59 // Check for the fingerprint of an event or an error
60 _validateFormat : function (logObject) {
61 if (typeof logObject === 'object'){
62 // Check for error object (must have meta)
63 if (logObject.hasOwnProperty('error')) {
64 if (logObject.error.hasOwnProperty('meta')) {
65 return 'error';
66 }
67 // Check for event object (must have type)
68 } else if (logObject.hasOwnProperty('event')) {
69 if (logObject.event.hasOwnProperty('type')) {
70 return 'event';
71 }
72 }
73 }
74 return undefined;
75 },
76
77 // This was ported as-is, but It's weird that we're doing lithium logic in
78 // here. TODO: Please move this elsewhere. - ben
79 _pushToLithium : function (object) {
80 var lithiumEvent;
81
82 if (typeof Li !== 'undefined') {
83 if (Li.stack) {
84 lithiumEvent = {
85 type : object.event.type,
86 instanceName : (object.event.data) ? (object.event.data.name || object.event.data.id || '---') : '---',
87 time : global.Cobalt.now()
88 };
89
90 Li.events.push(lithiumEvent);
91 Li.stack.push(lithiumEvent);
92
93 // Another note: There was another push to Li.stack that checked if it
94 // was typeof === array. Which will never happen since array is typeof
95 // Object. But I could be wrong. So... yeah. That.
96
97 if (Li.events.length > 20) {
98 Li.stack.shift();
99 }
100 }
101 }
102 },
103
104 // Create the main structure, also push to lithium
105 _createStructure : function (logObject) {
106 var event = {};
107
108 this._pushToLithium(logObject);
109
110 event.site_id = global.Client ? Client.pageInfo.site.id : 'client not found';
111 event.event_type = logObject.event.type;
112
113 event.data = logObject.event.data || {};
114 event.data = this._process(event.data);
115 event.data.user_time_stamp = global.Cobalt.now();
116
117 event = this._addSiteData(event);
118 event = this._addTrackingData(event);
119
120 event._type = 'event';
121
122 return event;
123 },
124
125 // Add required data from siteInfo
126 _addSiteData : function (event) {
127 if (typeof siteInfo !== 'undefined') {
128 event.data.trial_period_days_left = siteInfo.trialPeriodDaysLeft;
129 event.data.billing_status = siteInfo.billingStatus;
130 event.data.is_admin_on_trial = siteInfo.isAdminOnTrial;
131 event.data.is_new_site = siteInfo.isNewSite;
132 event.data.is_for_play = siteInfo.forPlay;
133 event.data.page_path = siteInfo.currentPagePath;
134 }
135
136 return event;
137 },
138
139 // Add required tracking variables for ad campaigns and such
140 _addTrackingData : function (event) {
141 if (typeof siteInfo !== 'undefined' && siteInfo.trackingVariables) {
142 event.data.initial_referring_domain = siteInfo.trackingVariables.initial_referring_domain;
143 event.data.referrer = siteInfo.trackingVariables.referrer;
144 event.data.search_keyword = siteInfo.trackingVariables.search_keyword;
145 event.data.utm_campaign = siteInfo.trackingVariables.utm_campaign;
146 event.data.utm_content = siteInfo.trackingVariables.utm_content;
147 event.data.utm_medium = siteInfo.trackingVariables.utm_medium;
148 event.data.utm_source = siteInfo.trackingVariables.utm_source;
149 event.data.utm_term = siteInfo.trackingVariables.utm_term;
150 }
151
152 return event;
153 },
154
155 // Send data through processors to extract valuable metadata
156 _process : function (data) {
157 if( typeof data !== 'undefined' && typeof data.constructor !== 'undefined' && typeof data.constructor.className !== 'undefined' ){
158 switch( data.constructor.className ){
159 case 'App':
160 return { meta: this._processApp(data) };
161
162 case 'Entry':
163 return { meta: this._processEntry(data) };
164
165 case 'Dot':
166 return { meta: this._processDot(data) };
167
168 case 'SiteSkin':
169 return { meta: this._processSiteSkin(data) };
170
171 case 'RepositorySkin':
172 return { meta: this._processRepositorySkin(data) };
173
174 default :
175 //do nothing and create an snapshot for the object
176 var snapshot = {};
177
178 $.each(data, function(i, el){
179 if(typeof el === 'string' || typeof el === 'number' || typeof el === 'boolean'){
180 snapshot[i] = el;
181 }
182 });
183
184 return { meta: { status: 'No processor for '+data.constructor.className, snapshot: snapshot } };
185 }
186
187 }else{
188 // No process for you
189 return { meta: data };
190 }
191 },
192
193 _processApp : function (data) {
194 var eventData = {
195 displayName : data.record.displayName,
196 repositoryAppId : data.record.repositoryApp().id,
197 repositoryAppName : data.record.repositoryApp().name
198 };
199
200 return { app: eventData };
201 },
202
203 _processEntry : function (data) {
204 //get app data
205 var app = this.processApp( Client.page['app_' + data.appId] );
206
207 var entry = {
208 id : data.id,
209 fieldValues : {}
210 };
211
212 //parse and save fieldvalues
213 $.each(data.fieldValues, function(i, field){
214 entry.fieldValues[field.fieldName] = field.value;
215 });
216
217 return {app: app, entry : entry};
218 },
219
220 _processDot : function (data) {
221 var target = { type: data.ruleTree.type };
222
223 switch (target.type){
224 case 'app' :
225 target.app = this.processApp( Client.page['app_'+data.ruleTree.id.replace('app_style_','')] ).app;
226 break;
227 }
228
229 var dot = {
230 type: data.type,
231 name: data.name
232 };
233
234 return {target: target, dot : dot};
235 },
236
237 _processSiteSkin : function (data) {
238 return { siteSkin : {
239 skinName: skinData.name,
240 skinId: skinData.id
241 }
242 };
243 },
244
245 _processRepositorySkin : function (data) {
246 var skin = {
247 id : data.id,
248 name : data.name,
249 userName : data.userName,
250 acquireMode : data.acquireMode,
251 amountInCents : data.amountInCents,
252 featured : data.featured,
253 installCount : data.installCount,
254 popular : data.popular
255 };
256
257 return { repositorySkin: skin };
258 }
259 });
260
261 if (Cobalt.Formatter.EventTracker.__objectSpy) {
262 Cobalt.Formatter.EventTracker.__objectSpy.destroy();
263 }
264
265 if (typeof require === 'function') {
266 global.EventTracker = Cobalt.Formatter.EventTracker;
267 } else {
268 global.Cobalt.Formatter.EventTracker = Cobalt.Formatter.EventTracker;
269 }
270 }(typeof window !== 'undefined' ? window : (typeof exports !== 'undefined' ? exports : self)));