Subversion Repositories SmartDukaan

Rev

Rev 5507 | Rev 5738 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3232 varun.gupt 1
$(function(){
3440 varun.gupt 2
	feedbacks = null;
3232 varun.gupt 3
 
3446 varun.gupt 4
	function getPriceAsInt(priceString)	{
5
		return parseInt(priceString.replace('Rs.', '').replace(',', ''));
6
	}
7
 
3551 varun.gupt 8
	function roundNumber(num, dec) {
9
		return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
10
	}
11
 
5291 varun.gupt 12
	function updateWithSecondaryCrawledData()	{
13
		$.ajax({
14
			url: '/feedback-url',
15
			type: 'GET',
5329 varun.gupt 16
			dataType: 'html',
17
 
18
			success: function(dataString){
19
				var data = eval('(' + dataString + ')');
20
				//console.log(dataString, data);
5291 varun.gupt 21
 
22
				$.each(data, function(entityId, sourceData){
5329 varun.gupt 23
					//console.log(entityId, sourceData);
5507 varun.gupt 24
					var tr = $('#' + entityId);
5291 varun.gupt 25
 
26
					$.each(sourceData, function(source, productData){
5329 varun.gupt 27
						//console.log(source, productData);
5291 varun.gupt 28
 
29
						var td = $(tr).children('td[source=' + source +']')[0];
30
						var anchor = $(td).children('a')[0];
5329 varun.gupt 31
						//console.log(anchor);
5291 varun.gupt 32
 
33
						$(anchor).attr('href', productData['product_url']);
34
						$(anchor).html(productData['price']);
35
 
36
						$(td).children('span.url-feedback-link').addClass('url-saved');
37
					});
5507 varun.gupt 38
					markBestPrice(tr);
5291 varun.gupt 39
				});
40
			}
41
		});
42
	}
43
 
3440 varun.gupt 44
	function updateWithFeedback()	{
45
		$.ajax({
46
			url: '/feedback',
47
			type: 'GET',
48
			success: function(data){
49
				feedbacks = eval('(' + data + ')');
50
 
51
				$.each(feedbacks, function(entityId, feedback){
52
					var tr = $('#' + entityId);
53
 
54
					$.each(feedback, function(source, feedback_instruction){
3462 varun.gupt 55
 
56
						var td = $(tr).children('td[source=' + source + ']')[0];
57
 
58
						if($(td).hasClass('conflict'))	updateCellWithFeedback(td, feedback_instruction);
3440 varun.gupt 59
					});
3446 varun.gupt 60
					markBestPrice(tr);
3440 varun.gupt 61
				});
5291 varun.gupt 62
				updateWithSecondaryCrawledData();
3440 varun.gupt 63
			}
64
		})
65
	}
66
 
67
	function updateCellWithFeedback(td, feedback)	{
68
		var anchor = $(td).children('.link-conflict');
3462 varun.gupt 69
 
3440 varun.gupt 70
		var source = $(td).attr('source');
5291 varun.gupt 71
		var cellActionLinks = $(td).children('.url-feedback-link, .reject-link').clone();
3440 varun.gupt 72
		$(anchor).html('Filtered');
73
 
74
		if(feedback.type == 'reject')	{
75
			$(td).html('Not Found ' + $('<a>').append($(anchor).clone()).remove().html()).addClass('with-feedback');
5291 varun.gupt 76
			$(td).append(cellActionLinks);
77
			$(td).children('span.reject-link').addClass('rejected')
3440 varun.gupt 78
 
79
		} else	{
80
			var itemInfo = lookupInfoForItem(eval($(td).attr('data')), feedback.selected_item);
4198 varun.gupt 81
 
82
			if (itemInfo != null)	{
83
				$(td).html(
84
					'<a href="' + baseUrl[source] + itemInfo.url + '">' + itemInfo.price + '</a> ' + 
85
					$('<a>').append($(anchor).clone()).remove().html()
86
				).addClass('with-feedback');
87
			}
3440 varun.gupt 88
		}
89
	}
90
 
91
	function lookupInfoForItem(data, itemName)	{
92
		var info = null;
93
 
94
		$.each(data, function(index, item){
95
 
96
			if (item.name == itemName)	{
97
				info = {name: item.name, price: item.price, url: item.url};
98
			}
99
		});
100
		return info;
101
	}
102
 
103
	$('tbody tr').each(function(index, e)	{
104
 		var class_tr = index % 2 == 0 ? 'even' : 'odd';
105
 		$(e).addClass(class_tr);
106
 		markBestPrice(this);
4198 varun.gupt 107
 
3440 varun.gupt 108
 		$(this).find('td').each(function(){
3462 varun.gupt 109
 			if($(this).hasClass('conflict'))	$(this).children('a').addClass('link-conflict');
4198 varun.gupt 110
 
111
 			if(! $(this).hasClass('diff') && ! $(this).hasClass('name') && ! $(this).hasClass('saholic'))	{
5291 varun.gupt 112
 				$(this).append('<span class="reject-link" title="Click to reject the displayed figure">X</span>&nbsp;');
4198 varun.gupt 113
 				$(this).append('<span class="url-feedback-link" title="Click to map a product page URL">U</span>');
114
 			}
3440 varun.gupt 115
 		});
116
	});
117
 
118
	updateWithFeedback();
119
 
3313 varun.gupt 120
	function markBestPrice(trNode)	{
3446 varun.gupt 121
		$(trNode).children().removeClass('best');
5291 varun.gupt 122
		var tdBestPrice = $(trNode).children('.saholic')[0];
123
		var saholicPrice = parseInt($(tdBestPrice).html());
3313 varun.gupt 124
		var bestPrice = saholicPrice;
3551 varun.gupt 125
		var maxPrice = saholicPrice;
3446 varun.gupt 126
 
127
		$(trNode).find('a[href!="#"]').each(function(index, a){
128
			var price = getPriceAsInt(a.innerHTML);
5291 varun.gupt 129
 
3313 varun.gupt 130
			if (price < bestPrice)	{
131
				bestPrice = price;
132
				tdBestPrice = $(a).parent();
133
			}
3551 varun.gupt 134
 
135
			if(price > maxPrice)	maxPrice = price;
3313 varun.gupt 136
		});
3551 varun.gupt 137
		var maxMinDiff = roundNumber((maxPrice - bestPrice) * 100 / maxPrice, 2);
138
 
3313 varun.gupt 139
		$(tdBestPrice).addClass('best');
140
 
141
		if (bestPrice < saholicPrice)	$($(trNode).children()[0]).addClass('red');
3551 varun.gupt 142
		var tds = $(trNode).children()
143
 
5639 amar.kumar 144
		if (tds.length == 9)	{
145
			tds[8].innerHTML = maxMinDiff + '%'
4198 varun.gupt 146
		} else	{var diffCssClass = '';
147
 
148
		if(maxMinDiff >= 25.0)	{
149
			diffCssClass = 'dark-orange';
150
		} else if(maxMinDiff >= 10.0)	{
151
			diffCssClass = 'orange';
3551 varun.gupt 152
		}
4198 varun.gupt 153
		$(trNode).append('<td class="diff ' + diffCssClass + '" title="Max-Min price difference">' + maxMinDiff + '%</td>');
154
		}
3313 varun.gupt 155
	}
156
 
157
	var baseUrl = {
158
		'flipkart': 'http://www.flipkart.com',
159
		'homeshop18': '',
160
		'infibeam': 'http://www.infibeam.com',
5291 varun.gupt 161
		'letsbuy': '',
5639 amar.kumar 162
		'snapdeal': 'http://www.snapdeal.com/',
163
		'sulekha': '',
164
		'tradus': 'http://www.tradus.com'
3313 varun.gupt 165
	};
166
 
3440 varun.gupt 167
	$('.conflict a').live('click', function(){
168
		var td = $(this).parent();
3232 varun.gupt 169
 
3440 varun.gupt 170
		var entityId = $(td).parent().attr('id');
171
		var source = $(td).attr('source');
172
 
173
		var data = eval("{results: " + $(td).attr('data') + "}");
174
 
175
		var feedback = null;
176
		var selectedItem = null; 
177
 
178
		if(feedbacks && feedbacks[entityId] && feedbacks[entityId][source])	{
179
			feedback = feedbacks[entityId][source];
180
 
181
			if (feedback.type == 'select')	selectedItem = feedback.selected_item;
182
		}
183
 
184
		if (feedback && feedback.type == 'reject')	{
185
			var text = '<div class="msg">Currently following set is marked <i>rejected</i></div>';
186
 
187
		} else	{
188
			var text = '';
189
		}
190
		text += '<table id="' + entityId + '" source="' + source + '">';
191
 
3232 varun.gupt 192
		for (i in data)	{
3440 varun.gupt 193
			var checked = selectedItem && selectedItem == data[i]['name'] ? 'checked' : ''; 
3232 varun.gupt 194
			text += '<tr>';
195
			text += '<td>' + data[i]['name'] + '</td>';
3313 varun.gupt 196
			text += '<td><a target="_blank" href="' + baseUrl[data[i]['source']] + data[i]['url'] + '">' + data[i]['price'] + '</a></td>';
3440 varun.gupt 197
			text += '<td><input type="radio" name="chosen_one_' + entityId + '" value="' + data[i]['name'] + '" ' + checked + '></td>';
3232 varun.gupt 198
			text += '</tr>';
199
		}
3440 varun.gupt 200
		text += '<tr>';
201
		text += '<td colspan="2" align="center"><a id="feedback-reject" href="#">Reject All</a></td>';
202
		text += '<td><a id="feedback-select" href="#">Save</a></td>';
203
		text += '</tr>';
3232 varun.gupt 204
		text += '</table>';
3440 varun.gupt 205
 
3232 varun.gupt 206
		$.facebox(text);
207
	});
3440 varun.gupt 208
 
209
	$('#feedback-reject').live('click', function(){
210
		var table = $(this).parents('table');
211
		var feedback = {
212
				type: 'reject',
213
				entityId: $(table).attr('id'),
214
				source: $(table).attr('source')
215
		};
216
		postFeedback(feedback, table);
217
	});
218
 
219
	$('#feedback-select').live('click', function(){
220
		var table = $(this).parents('table');
221
		var entityId = $(table).attr('id');
222
 
223
		var selected_item = $("input:radio[name='chosen_one_" + entityId + "']:checked").val();
224
 
225
		if(! selected_item)	{
226
 
227
			showMsg(table, true, 'At least one option must be selected');
228
 
229
		} else	{
230
			var feedback = {
231
					type: 'select',
232
					entityId: entityId,
233
					source: $(table).attr('source'),
234
					selected: selected_item
235
			};
236
			postFeedback(feedback, table);
237
		}
238
	});
239
 
240
	function postFeedback(feedback, table)	{
241
		var feedbackType = feedback.type;
242
		var entityId = feedback.entityId;
243
 
244
		$.ajax({
245
			url: '/feedback',
246
			type: 'POST',
247
			data: feedback,
248
			success: function(msg)	{
249
 
250
				if (feedbackType == 'reject')	{
251
					$("input:radio[name='chosen_one_" + entityId + "']:checked").prop('checked', false);
252
				}
253
				var td = $('#' + feedback.entityId).children('td[source=' + feedback.source + ']')[0];
254
				updateCellWithFeedback(td, {type: feedback.type, selected_item: feedback.selected});
5291 varun.gupt 255
 
256
				if(table && table != 'undefined')	{
257
					showMsg(table, false, 'Your feedback has been saved successfully.');
258
				}
3446 varun.gupt 259
				markBestPrice($(td).parent());
3440 varun.gupt 260
			},
261
			error: function(msg)	{
262
				showMsg(table, true, 'Error! please try again.');
263
			}
264
		});
265
	}
266
 
267
	function showMsg(table, is_error, msg)	{
268
		msg_class = is_error ? 'error' : 'notice';
269
 
270
		if($(table).siblings('.msg').length > 0)	{
271
			var msgDiv = $(table).siblings('.msg')[0];
272
			$(msgDiv).html(msg);
273
 
274
		} else	{
275
			$(table).before('<div class="msg">' + msg + '</div>');
276
		}
277
	}
278
 
4198 varun.gupt 279
	$('.url-feedback-link').live('click', function(){
280
		var source = $(this).parent().attr('source');
281
		var entity = $(this).parent().parent().attr('id');
282
//		console.log(source, entity);
283
		var html = '<div class="form-url-feedback">\n';
284
		var html = 'Enter the URL you want to be crawled for this product<br>\n';
285
		html += '<input type="text" id="url-feedback" size="40"><br />\n';
286
		html += '<input type="hidden" id="entity-url-feedback" value="' + entity + '">\n';
287
		html += '<input type="hidden" id="source-url-feedback" value="' + source + '">\n';
288
		html += '<input type="button" id="submit-url-feedback" value="Save">\n';
289
		html += '</div>';
290
		$.facebox(html);
291
	});
292
 
293
	$('#submit-url-feedback').live('click', function(){
294
		$.ajax({
295
			url: '/feedback-url',
296
			type: 'POST',
297
			data: {
298
				entity: $('#entity-url-feedback').val(), 
299
				source: $('#source-url-feedback').val(), 
300
				url: $('#url-feedback').val()
301
			},
302
			beforeSend: function(){
303
				$('#url-feedback, #submit-url-feedback').attr('disabled', 'disabled');
304
				$('#submit-url-feedback').val('Saving...').after('<img src="/static/images/loading.gif" width="24" />');
305
			},
306
			success: function(data){
307
				var html = '<table>';
308
				html += '<tr><td class="msg" colspan="2" align="center">The URL is saved and will be crawled next time</td></tr>';
5291 varun.gupt 309
				html += '<tr><td colspan="2">&nbsp;</td></tr>';
4198 varun.gupt 310
				html += '<tr><td align="center">' + data.name + '</td><td align="center">Rs.' + data.price + '</td></tr>';
311
				html += '</table>';
312
				var form = $('#facebox').find('.content').html(html);
5291 varun.gupt 313
 
314
				var tr = $('#' + data.entityId);
315
				var td = $(tr).children('td[source=' + data.source +']')[0];
316
				var anchor = $(td).children('a')[0];
317
 
318
				$(anchor).attr('href', data.product_url);
319
				$(anchor).html(data.price);
320
 
321
				$(td).children('span').addClass('url-saved');
4198 varun.gupt 322
			}
323
		});
324
	});
325
 
5291 varun.gupt 326
	$('.reject-link').live('click', function(){
327
		var source = $(this).parent().attr('source');
328
		var entity = $(this).parent().parent().attr('id');
329
 
330
		if($(this).hasClass('rejected'))	{
331
			var td = $(this).parent();
332
 
333
			var url = $(td).attr('url');
334
			var price = $(td).attr('price');
335
 
336
			var cellActionLinks = $(td).children('.url-feedback-link, .reject-link');
337
			$(td).html('<a target="_blank" href="' + url + '">' + price + '</a>');
338
			$(td).append(cellActionLinks);
339
			console.log($(td).children('.reject-link'));
340
			$($(td).children('.reject-link')[0]).removeClass('rejected');
341
 
342
		} else	{
343
			var feedback = {
344
					type: 'reject',
345
					entityId: entity,
346
					source: source
347
			};
348
 
349
			//Setting rejected URL in the cell's DOM
350
			var td = $('#' + entity).children('td[source=' + source + ']')[0];
351
			var anchor = $(td).children('a')[0];
352
			$(td).attr('price', $.trim($(anchor).html()));
353
			$(td).attr('url', $(anchor).attr('href'));
354
 
355
			postFeedback(feedback);
356
		}
357
	});
358
 
4198 varun.gupt 359
	$('#howTo').click(function(){
360
		html = '<ul>\n\
361
			<li class="first">The price data is crawled directly from competitor websites at 8:00 AM everyday</li>\n\
362
			<li class="first">All price figures are linked to their respective product pages</li>\n\
363
			<li class="first">Cells showing "Not Found" are linked to search result page of relevant website.</li>\n\
364
			<li class="first">Cells showing "Conflict" are linked to set of products which are conflicting to match with\n\
365
			the product. You can either select one of them or reject all depending on the case. The selection \n\
366
			will be taken into account when showing the dashboard next time.</li>\n\
367
			<li class="first">Clicking on "U" (present in all price cells) will pop up a form where you can submit a URL \n\
368
			pointing to the product page of the product. After submission this URL will be crawled and indexed \n\
369
			in real-time and saved in the list of URLs for scheduled crawling in future.</li>\n\
370
			<li class="first">In each row, right most cell shows the percentage difference between the minimum and maximum \n\
371
			price of that product. Color coding:\n\
372
				<ul>\n\
373
					<li>Yellow: 10 - 24.99% difference</li>\n\
374
					<li>Orange: Above 24.99%</li>\n\
375
				</ul></li>\n\
376
			<li class="first">In case of further clarification, email your query at varun.gupta@shop2020.in</li>\n\
377
			</ul>';
378
		$.facebox(html);
379
	});
380
 
5291 varun.gupt 381
	$('#all').click(function(){
382
		$('tbody tr').show();
383
	});
384
 
385
	$('#watchlist').click(function(){
386
		$('tbody tr .watchlist-icon').each(function(){
387
			if(! $(this).hasClass('on-watchlist'))	$(this).parent().parent().hide();
388
		});
389
	});
390
 
5401 varun.gupt 391
	$('#downloadXL').click(function(){
392
		$('form[action="/download"]').submit();
393
	});
394
 
3440 varun.gupt 395
	$('#facebox .close').live('click', function(){});
5291 varun.gupt 396
 
397
	var watchList = {
398
			get: function()	{
399
				$.ajax({
400
					type: 'GET',
401
					url: '/watchlist',
402
 
5329 varun.gupt 403
 
5291 varun.gupt 404
					error: function(jqXHR, textStatus, errorThrown)	{
5329 varun.gupt 405
						console.log(jqXHR, textStatus, errorThrown);
5291 varun.gupt 406
						alert('Could not get WatchList. Try again later.');
407
					},
408
					success: function(data, textStatus, jqXHR)	{
5329 varun.gupt 409
						console.log(data, textStatus, jqXHR);
5291 varun.gupt 410
						entities = eval('(' + data + ')');
411
 
412
						$.each(entities, function(index, entity)	{
413
							var elementId = '#' + entity;
414
							var tr = $(elementId);
415
							$($('#' + entity).find('.watchlist-icon')[0]).addClass('on-watchlist');
416
						});
417
					}
418
				});
419
			},
420
			add: function(entity)	{
421
				$.ajax({
422
					type: 'POST',
423
					url: '/watchlist',
424
					data: {'type': 'save', 'entity': entity},
425
 
426
					error: function(jqXHR, textStatus, errorThrown)	{
427
						console.log(jqXHR, textStatus, errorThrown);
428
						alert('Could not add this item to WatchList. Try again later.');
429
					},
430
					success: function(data, textStatus, jqXHR)	{
431
						console.log(data, textStatus, jqXHR);
432
						$($('#' + entity).find('.watchlist-icon')[0]).addClass('on-watchlist');
433
					}
434
				});
435
			},
436
			remove: function(entity)	{
437
				$.ajax({
438
					type: 'POST',
439
					url: '/watchlist',
440
					data: {'type': 'delete', 'entity': entity},
441
 
442
					error: function(jqXHR, textStatus, errorThrown)	{
443
						console.log(jqXHR, textStatus, errorThrown);
444
						alert('Could not remove this item from WatchList. Try again later.');
445
					},
446
					success: function(data, textStatus, jqXHR)	{
447
						console.log(data, textStatus, jqXHR);
448
						$($('#' + entity).find('.watchlist-icon')[0]).removeClass('on-watchlist');
449
					}
450
				});
451
			}
452
	};
453
 
454
	watchList.get();
455
 
456
	$('.watchlist-icon').click(function(){
457
 
458
		var entity = $(this).parent().parent().attr('id');
459
 
460
		if($(this).hasClass('on-watchlist'))	{
461
			watchList.remove(entity);
462
		} else	{
463
			watchList.add(entity);
464
		}
465
	});
3232 varun.gupt 466
});