Subversion Repositories SmartDukaan

Rev

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