Subversion Repositories SmartDukaan

Rev

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