Subversion Repositories SmartDukaan

Rev

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