Subversion Repositories SmartDukaan

Rev

Rev 5401 | Rev 5639 | 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
 
144
		if (tds.length == 7)	{
145
			tds[6].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': '',
162
		'snapdeal': 'http://www.snapdeal.com/'
3313 varun.gupt 163
	};
164
 
3440 varun.gupt 165
	$('.conflict a').live('click', function(){
166
		var td = $(this).parent();
3232 varun.gupt 167
 
3440 varun.gupt 168
		var entityId = $(td).parent().attr('id');
169
		var source = $(td).attr('source');
170
 
171
		var data = eval("{results: " + $(td).attr('data') + "}");
172
 
173
		var feedback = null;
174
		var selectedItem = null; 
175
 
176
		if(feedbacks && feedbacks[entityId] && feedbacks[entityId][source])	{
177
			feedback = feedbacks[entityId][source];
178
 
179
			if (feedback.type == 'select')	selectedItem = feedback.selected_item;
180
		}
181
 
182
		if (feedback && feedback.type == 'reject')	{
183
			var text = '<div class="msg">Currently following set is marked <i>rejected</i></div>';
184
 
185
		} else	{
186
			var text = '';
187
		}
188
		text += '<table id="' + entityId + '" source="' + source + '">';
189
 
3232 varun.gupt 190
		for (i in data)	{
3440 varun.gupt 191
			var checked = selectedItem && selectedItem == data[i]['name'] ? 'checked' : ''; 
3232 varun.gupt 192
			text += '<tr>';
193
			text += '<td>' + data[i]['name'] + '</td>';
3313 varun.gupt 194
			text += '<td><a target="_blank" href="' + baseUrl[data[i]['source']] + data[i]['url'] + '">' + data[i]['price'] + '</a></td>';
3440 varun.gupt 195
			text += '<td><input type="radio" name="chosen_one_' + entityId + '" value="' + data[i]['name'] + '" ' + checked + '></td>';
3232 varun.gupt 196
			text += '</tr>';
197
		}
3440 varun.gupt 198
		text += '<tr>';
199
		text += '<td colspan="2" align="center"><a id="feedback-reject" href="#">Reject All</a></td>';
200
		text += '<td><a id="feedback-select" href="#">Save</a></td>';
201
		text += '</tr>';
3232 varun.gupt 202
		text += '</table>';
3440 varun.gupt 203
 
3232 varun.gupt 204
		$.facebox(text);
205
	});
3440 varun.gupt 206
 
207
	$('#feedback-reject').live('click', function(){
208
		var table = $(this).parents('table');
209
		var feedback = {
210
				type: 'reject',
211
				entityId: $(table).attr('id'),
212
				source: $(table).attr('source')
213
		};
214
		postFeedback(feedback, table);
215
	});
216
 
217
	$('#feedback-select').live('click', function(){
218
		var table = $(this).parents('table');
219
		var entityId = $(table).attr('id');
220
 
221
		var selected_item = $("input:radio[name='chosen_one_" + entityId + "']:checked").val();
222
 
223
		if(! selected_item)	{
224
 
225
			showMsg(table, true, 'At least one option must be selected');
226
 
227
		} else	{
228
			var feedback = {
229
					type: 'select',
230
					entityId: entityId,
231
					source: $(table).attr('source'),
232
					selected: selected_item
233
			};
234
			postFeedback(feedback, table);
235
		}
236
	});
237
 
238
	function postFeedback(feedback, table)	{
239
		var feedbackType = feedback.type;
240
		var entityId = feedback.entityId;
241
 
242
		$.ajax({
243
			url: '/feedback',
244
			type: 'POST',
245
			data: feedback,
246
			success: function(msg)	{
247
 
248
				if (feedbackType == 'reject')	{
249
					$("input:radio[name='chosen_one_" + entityId + "']:checked").prop('checked', false);
250
				}
251
				var td = $('#' + feedback.entityId).children('td[source=' + feedback.source + ']')[0];
252
				updateCellWithFeedback(td, {type: feedback.type, selected_item: feedback.selected});
5291 varun.gupt 253
 
254
				if(table && table != 'undefined')	{
255
					showMsg(table, false, 'Your feedback has been saved successfully.');
256
				}
3446 varun.gupt 257
				markBestPrice($(td).parent());
3440 varun.gupt 258
			},
259
			error: function(msg)	{
260
				showMsg(table, true, 'Error! please try again.');
261
			}
262
		});
263
	}
264
 
265
	function showMsg(table, is_error, msg)	{
266
		msg_class = is_error ? 'error' : 'notice';
267
 
268
		if($(table).siblings('.msg').length > 0)	{
269
			var msgDiv = $(table).siblings('.msg')[0];
270
			$(msgDiv).html(msg);
271
 
272
		} else	{
273
			$(table).before('<div class="msg">' + msg + '</div>');
274
		}
275
	}
276
 
4198 varun.gupt 277
	$('.url-feedback-link').live('click', function(){
278
		var source = $(this).parent().attr('source');
279
		var entity = $(this).parent().parent().attr('id');
280
//		console.log(source, entity);
281
		var html = '<div class="form-url-feedback">\n';
282
		var html = 'Enter the URL you want to be crawled for this product<br>\n';
283
		html += '<input type="text" id="url-feedback" size="40"><br />\n';
284
		html += '<input type="hidden" id="entity-url-feedback" value="' + entity + '">\n';
285
		html += '<input type="hidden" id="source-url-feedback" value="' + source + '">\n';
286
		html += '<input type="button" id="submit-url-feedback" value="Save">\n';
287
		html += '</div>';
288
		$.facebox(html);
289
	});
290
 
291
	$('#submit-url-feedback').live('click', function(){
292
		$.ajax({
293
			url: '/feedback-url',
294
			type: 'POST',
295
			data: {
296
				entity: $('#entity-url-feedback').val(), 
297
				source: $('#source-url-feedback').val(), 
298
				url: $('#url-feedback').val()
299
			},
300
			beforeSend: function(){
301
				$('#url-feedback, #submit-url-feedback').attr('disabled', 'disabled');
302
				$('#submit-url-feedback').val('Saving...').after('<img src="/static/images/loading.gif" width="24" />');
303
			},
304
			success: function(data){
305
				var html = '<table>';
306
				html += '<tr><td class="msg" colspan="2" align="center">The URL is saved and will be crawled next time</td></tr>';
5291 varun.gupt 307
				html += '<tr><td colspan="2">&nbsp;</td></tr>';
4198 varun.gupt 308
				html += '<tr><td align="center">' + data.name + '</td><td align="center">Rs.' + data.price + '</td></tr>';
309
				html += '</table>';
310
				var form = $('#facebox').find('.content').html(html);
5291 varun.gupt 311
 
312
				var tr = $('#' + data.entityId);
313
				var td = $(tr).children('td[source=' + data.source +']')[0];
314
				var anchor = $(td).children('a')[0];
315
 
316
				$(anchor).attr('href', data.product_url);
317
				$(anchor).html(data.price);
318
 
319
				$(td).children('span').addClass('url-saved');
4198 varun.gupt 320
			}
321
		});
322
	});
323
 
5291 varun.gupt 324
	$('.reject-link').live('click', function(){
325
		var source = $(this).parent().attr('source');
326
		var entity = $(this).parent().parent().attr('id');
327
 
328
		if($(this).hasClass('rejected'))	{
329
			var td = $(this).parent();
330
 
331
			var url = $(td).attr('url');
332
			var price = $(td).attr('price');
333
 
334
			var cellActionLinks = $(td).children('.url-feedback-link, .reject-link');
335
			$(td).html('<a target="_blank" href="' + url + '">' + price + '</a>');
336
			$(td).append(cellActionLinks);
337
			console.log($(td).children('.reject-link'));
338
			$($(td).children('.reject-link')[0]).removeClass('rejected');
339
 
340
		} else	{
341
			var feedback = {
342
					type: 'reject',
343
					entityId: entity,
344
					source: source
345
			};
346
 
347
			//Setting rejected URL in the cell's DOM
348
			var td = $('#' + entity).children('td[source=' + source + ']')[0];
349
			var anchor = $(td).children('a')[0];
350
			$(td).attr('price', $.trim($(anchor).html()));
351
			$(td).attr('url', $(anchor).attr('href'));
352
 
353
			postFeedback(feedback);
354
		}
355
	});
356
 
4198 varun.gupt 357
	$('#howTo').click(function(){
358
		html = '<ul>\n\
359
			<li class="first">The price data is crawled directly from competitor websites at 8:00 AM everyday</li>\n\
360
			<li class="first">All price figures are linked to their respective product pages</li>\n\
361
			<li class="first">Cells showing "Not Found" are linked to search result page of relevant website.</li>\n\
362
			<li class="first">Cells showing "Conflict" are linked to set of products which are conflicting to match with\n\
363
			the product. You can either select one of them or reject all depending on the case. The selection \n\
364
			will be taken into account when showing the dashboard next time.</li>\n\
365
			<li class="first">Clicking on "U" (present in all price cells) will pop up a form where you can submit a URL \n\
366
			pointing to the product page of the product. After submission this URL will be crawled and indexed \n\
367
			in real-time and saved in the list of URLs for scheduled crawling in future.</li>\n\
368
			<li class="first">In each row, right most cell shows the percentage difference between the minimum and maximum \n\
369
			price of that product. Color coding:\n\
370
				<ul>\n\
371
					<li>Yellow: 10 - 24.99% difference</li>\n\
372
					<li>Orange: Above 24.99%</li>\n\
373
				</ul></li>\n\
374
			<li class="first">In case of further clarification, email your query at varun.gupta@shop2020.in</li>\n\
375
			</ul>';
376
		$.facebox(html);
377
	});
378
 
5291 varun.gupt 379
	$('#all').click(function(){
380
		$('tbody tr').show();
381
	});
382
 
383
	$('#watchlist').click(function(){
384
		$('tbody tr .watchlist-icon').each(function(){
385
			if(! $(this).hasClass('on-watchlist'))	$(this).parent().parent().hide();
386
		});
387
	});
388
 
5401 varun.gupt 389
	$('#downloadXL').click(function(){
390
		$('form[action="/download"]').submit();
391
	});
392
 
3440 varun.gupt 393
	$('#facebox .close').live('click', function(){});
5291 varun.gupt 394
 
395
	var watchList = {
396
			get: function()	{
397
				$.ajax({
398
					type: 'GET',
399
					url: '/watchlist',
400
 
5329 varun.gupt 401
 
5291 varun.gupt 402
					error: function(jqXHR, textStatus, errorThrown)	{
5329 varun.gupt 403
						console.log(jqXHR, textStatus, errorThrown);
5291 varun.gupt 404
						alert('Could not get WatchList. Try again later.');
405
					},
406
					success: function(data, textStatus, jqXHR)	{
5329 varun.gupt 407
						console.log(data, textStatus, jqXHR);
5291 varun.gupt 408
						entities = eval('(' + data + ')');
409
 
410
						$.each(entities, function(index, entity)	{
411
							var elementId = '#' + entity;
412
							var tr = $(elementId);
413
							$($('#' + entity).find('.watchlist-icon')[0]).addClass('on-watchlist');
414
						});
415
					}
416
				});
417
			},
418
			add: function(entity)	{
419
				$.ajax({
420
					type: 'POST',
421
					url: '/watchlist',
422
					data: {'type': 'save', 'entity': entity},
423
 
424
					error: function(jqXHR, textStatus, errorThrown)	{
425
						console.log(jqXHR, textStatus, errorThrown);
426
						alert('Could not add this item to WatchList. Try again later.');
427
					},
428
					success: function(data, textStatus, jqXHR)	{
429
						console.log(data, textStatus, jqXHR);
430
						$($('#' + entity).find('.watchlist-icon')[0]).addClass('on-watchlist');
431
					}
432
				});
433
			},
434
			remove: function(entity)	{
435
				$.ajax({
436
					type: 'POST',
437
					url: '/watchlist',
438
					data: {'type': 'delete', 'entity': entity},
439
 
440
					error: function(jqXHR, textStatus, errorThrown)	{
441
						console.log(jqXHR, textStatus, errorThrown);
442
						alert('Could not remove this item from WatchList. Try again later.');
443
					},
444
					success: function(data, textStatus, jqXHR)	{
445
						console.log(data, textStatus, jqXHR);
446
						$($('#' + entity).find('.watchlist-icon')[0]).removeClass('on-watchlist');
447
					}
448
				});
449
			}
450
	};
451
 
452
	watchList.get();
453
 
454
	$('.watchlist-icon').click(function(){
455
 
456
		var entity = $(this).parent().parent().attr('id');
457
 
458
		if($(this).hasClass('on-watchlist'))	{
459
			watchList.remove(entity);
460
		} else	{
461
			watchList.add(entity);
462
		}
463
	});
3232 varun.gupt 464
});