Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4038 varun.gupt 1
package in.shop2020.web;
2
 
3
import java.io.IOException;
4
import java.util.ArrayList;
5
import java.util.Date;
6
import java.util.HashMap;
7
import java.util.List;
8
import java.util.Map;
9
 
10
import javax.servlet.ServletException;
11
import javax.servlet.http.HttpServlet;
12
import javax.servlet.http.HttpServletRequest;
13
import javax.servlet.http.HttpServletResponse;
14
 
15
import org.json.JSONArray;
16
import org.json.JSONException;
17
import org.json.JSONObject;
18
 
19
import com.google.appengine.api.datastore.DatastoreService;
20
import com.google.appengine.api.datastore.DatastoreServiceFactory;
21
import com.google.appengine.api.datastore.Entity;
22
import com.google.appengine.api.datastore.FetchOptions;
23
import com.google.appengine.api.datastore.Key;
24
import com.google.appengine.api.datastore.KeyFactory;
25
import com.google.appengine.api.datastore.PreparedQuery;
26
import com.google.appengine.api.datastore.Query;
27
import com.google.appengine.api.datastore.Query.FilterOperator;
28
import com.google.appengine.api.datastore.Query.SortDirection;
29
 
30
public class PriceComparisonServlet extends HttpServlet {
31
 
32
	private static final long serialVersionUID = 1L;
33
 
34
	private final String ENTITY_KIND_JOB = "ScrapeJob";
35
	private final String ENTITY_KIND_PHONE_PRICE = "PhonePrice";
36
 
37
	private DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
38
 
39
	public enum JobStatus {
40
		UNASSIGNED(0), ASSIGNED(1), COMPLETED(2);
41
 
42
		private int code;
43
 
44
		private JobStatus(int code)	{
45
			this.code = code;
46
		}
47
 
48
		public int getCode()	{
49
			return this.code;
50
		}
51
	}
52
 
53
	private Entity createScrapeJob(String url, String source)	{
54
 
55
		Entity scrapeJob = new Entity(ENTITY_KIND_JOB);
56
 
57
		scrapeJob.setProperty("url", url);
58
		scrapeJob.setProperty("source", source);
59
		scrapeJob.setProperty("status", JobStatus.UNASSIGNED.getCode());
60
		scrapeJob.setProperty("assigneeId", null);
61
		scrapeJob.setProperty("enqueuedOn", null);
62
 
63
		return scrapeJob;
64
	}
65
 
66
	private void assignScrapeJob(Entity scrapeJob, String assigneeId)	{
67
 
68
		System.out.println("Assignee Id: " + assigneeId);
69
		scrapeJob.setProperty("status", JobStatus.ASSIGNED.getCode());
70
		scrapeJob.setProperty("assigneeId", assigneeId);
71
		ds.put(scrapeJob);
72
	}
73
 
74
	private void enqueueScrapeJob(Entity scrapeJob)	{
75
		scrapeJob.setProperty("enqueuedOn", new Date());
76
		ds.put(scrapeJob);
77
	}
78
 
79
	private Entity assignJobToScraper(String assigneeId, String lastScrapedSource)	{
80
		Query query = new Query(ENTITY_KIND_JOB);
81
		query.addFilter("status", FilterOperator.EQUAL, JobStatus.UNASSIGNED.getCode());
82
		query.addSort("enqueuedOn", SortDirection.ASCENDING);
83
 
84
		PreparedQuery pq = ds.prepare(query);
85
		FetchOptions fo = FetchOptions.Builder.withLimit(1);
86
		Entity job;
87
 
88
		if (pq.countEntities(fo) > 0)	{
89
			job = pq.asList(fo).get(0);
90
 
91
			if (assigneeId == null)	{
92
				System.out.println("Assignee Id is null");
93
				String newAssigneeId = Long.toString(job.getKey().getId());
94
				System.out.println("New Job Id & Assignee Id: " + newAssigneeId);
95
 
96
				assignScrapeJob(job, newAssigneeId);
97
			} else	{
98
				System.out.println("Assignee Id is " + assigneeId);
99
				assignScrapeJob(job, assigneeId);
100
			}
101
 
102
		} else	{
103
			job = null;
104
		}
105
 
106
		System.out.println("Job assigned:" + job);
107
 
108
		return job;
109
	}
110
 
111
	private Map<String, String> toMap(Entity job)	{
112
 
113
		Map<String, String> jobMap = new HashMap<String, String>();
114
 
115
		if (job != null)	{
116
			jobMap.put("id", Long.toString(job.getKey().getId()));
117
			jobMap.put("source", (String) job.getProperty("source"));
118
			jobMap.put("assigneeId", (String) job.getProperty("assigneeId"));
119
			jobMap.put("url", (String) job.getProperty("url"));
120
 
121
		} else	{
122
			jobMap.put("id", null);
123
			jobMap.put("source", null);
124
			jobMap.put("assigneeId", null);
125
			jobMap.put("url", null);
126
		}
127
		return jobMap;
128
	}
129
 
130
	private int getTimeToWait()	{
131
		return 2 + (int) (Math.random() * 2);
132
	}
133
 
134
	private String getPhoneNameKey(String phoneName, String source)	{
135
		int bracketStartsAt = phoneName.indexOf('(');
136
 
137
		if(bracketStartsAt > -1)	{
138
			phoneName = phoneName.substring(0, bracketStartsAt);
139
		}
140
		String phoneNameKey = phoneName.replaceAll("[^a-zA-Z0-9]", "");
141
		return phoneNameKey.toLowerCase();
142
	}
143
 
144
	private void removeJobFromQueue(String jobId)	{
145
		Key k = KeyFactory.createKey(ENTITY_KIND_JOB, Long.parseLong(jobId));
146
		ds.delete(k);
147
	}
148
 
149
	private void savePhonePrices(JSONArray phonePrices, String source)	{
150
		System.out.println("Saving Price Data");
151
		List<Entity> priceEntities = new ArrayList<Entity>();
152
 
153
		for (int i = 0; i < phonePrices.length(); i ++)	{
154
			try {
155
				JSONObject phone = phonePrices.getJSONObject(i);
156
 
157
				Entity priceEntity = new Entity(ENTITY_KIND_PHONE_PRICE);
158
 
159
				priceEntity.setProperty("source", source);
160
				priceEntity.setProperty("name", phone.getString("name"));
161
				priceEntity.setProperty("price", phone.getString("price"));
162
				priceEntity.setProperty("in_stock", phone.getString("in_stock"));
163
				priceEntity.setProperty("url", phone.getString("product_url"));
164
 
165
				priceEntities.add(priceEntity);
166
 
167
			} catch (JSONException e) {
168
				e.printStackTrace();
169
			}
170
		}
171
		ds.put(priceEntities);
172
	}
173
 
174
	private void initJobQueue()	{
175
 
176
		Entity job1 = createScrapeJob("http://www.flipkart.com/mobiles/all/", "flipkart");
177
		enqueueScrapeJob(job1);
178
		Entity job2 = createScrapeJob("http://www.letsbuy.com/mobile-phones-mobiles-c-254_88?perpage=192", "letsbuy");
179
		enqueueScrapeJob(job2);
180
		Entity job3 = createScrapeJob("http://www.infibeam.com/Mobiles/search", "infibeam");
181
		enqueueScrapeJob(job3);
182
		Entity job4 = createScrapeJob("http://www.homeshop18.com/gsm-handsets/category:3027/", "homeshop18");
183
		enqueueScrapeJob(job4);
184
		Entity job5 = createScrapeJob("http://www.flipkart.com/mobiles/tablet-20278", "flipkart");
185
		enqueueScrapeJob(job5);
186
		Entity job6 = createScrapeJob("http://www.letsbuy.com/mobile-phones-tablets-c-254_393?perpage=192", "letsbuy");
187
		enqueueScrapeJob(job6);
188
		Entity job7 = createScrapeJob("http://www.homeshop18.com/ipads-2f-tablets/category:8937/", "homeshop18");
189
		enqueueScrapeJob(job7);
190
//		Entity job8 = createScrapeJob("http://www.adexmart.com/modules/coremanager/modules/filtersearch/filtersearch.json.php?act=filter&ident=16&page=1&perpage=1000&orderby=newest&orderway=desc", "adexmart");
191
//		enqueueScrapeJob(job8);
192
	}
193
 
194
	public void doGet(HttpServletRequest req, HttpServletResponse resp)	{
195
 
196
		String cmd = req.getParameter("cmd");
197
		System.out.println("Command recieved: " + cmd);
198
 
199
		Query q = new Query(ENTITY_KIND_PHONE_PRICE);
200
		PreparedQuery pq = ds.prepare(q);
201
 
202
		if (cmd != null)	{
203
 
204
			if (cmd.equals("delall"))	{
205
 
206
				System.out.println("Deleting all pricing");
207
 
208
				for (Entity pricing: pq.asIterable())	{
209
					ds.delete(pricing.getKey());
210
				}
211
 
212
				System.out.println("Deleting all jobs");
213
 
214
				q = new Query(ENTITY_KIND_JOB);
215
				pq = ds.prepare(q);
216
 
217
				for (Entity job: pq.asIterable())	{
218
					ds.delete(job.getKey());
219
				}
220
			} else if(cmd.equals("init"))	{
221
 
222
				System.out.println("Initializing the job queue");
223
 
224
				initJobQueue();
225
 
226
			} else if (cmd.equals("getjson")) {
227
 
228
				List<Map<String, String>> entities = new ArrayList<Map<String,String>>();
229
 
230
				Map<String, String> details;
231
 
232
				for (Entity pricing: pq.asIterable())	{
233
					details = new HashMap<String, String>();
234
 
235
					details.put("source", (String) pricing.getProperty("source"));
236
					details.put("name", (String) pricing.getProperty("name"));
237
					details.put("price", (String) pricing.getProperty("price"));
238
					details.put("in_stock", (String) pricing.getProperty("in_stock"));
239
					details.put("url", (String) pricing.getProperty("url"));
240
 
241
					entities.add(details);
242
				}
243
				resp.setContentType("application/json");
244
				try {
245
					resp.getWriter().print(new JSONArray(entities));
246
 
247
				} catch (IOException e) {
248
					e.printStackTrace();
249
				}
250
			}
251
		}
252
	}
253
 
254
	public void doPost(HttpServletRequest req, HttpServletResponse resp) {
255
 
256
		String clientId = (String) req.getParameter("id");
257
		String jobId = (String) req.getParameter("job_id");
258
		String source = (String) req.getParameter("source");
259
		String phonePrices = (String) req.getParameter("phone_prices");
260
		String nextUrl = (String) req.getParameter("next_url");
261
 
262
		Entity job;
263
		System.out.println(clientId + " " + jobId + " " + source + " " + phonePrices);
264
 
265
		if(clientId.equals("None") || jobId.equals("None") || source.equals("None") || phonePrices.equals("None"))	{
266
			System.out.println("Assigning first job");
267
			job = assignJobToScraper(null, null);
268
 
269
		} else	{
270
			try {
271
				JSONObject phonePricesJSONObj = new JSONObject("{priceData: " + phonePrices + "}");
272
//				JSONArray priceJSONArray = new JSONArray(phonePrices);
273
//				System.out.println(priceJSONArray);
274
				savePhonePrices(phonePricesJSONObj.getJSONArray("priceData"), source);
275
//				savePhonePrices(priceJSONArray, source);
276
 
277
				removeJobFromQueue(jobId);	// Removing executed job from the queue
278
 
279
			} catch (JSONException e) {
280
				e.printStackTrace();
281
			}
282
			System.out.println("Assigning next job");
283
 
284
			job = assignJobToScraper(clientId, source);
285
		}
286
 
287
		if(!nextUrl.equals("None") && !source.equals("None"))	{
288
			Entity newJob = createScrapeJob(nextUrl, source);
289
			enqueueScrapeJob(newJob);
290
		}
291
 
292
		System.out.println("Assigned Job & all attributes set:" + job);
293
 
294
		Map<String, String> scraperJobMap = toMap(job);
295
		scraperJobMap.put("timetowait", Integer.toString(getTimeToWait()));
296
 
297
		System.out.println("final Map:" + scraperJobMap);
298
		try {
299
			resp.getWriter().print(new JSONObject(scraperJobMap));
300
 
301
		} catch (IOException e) {
302
			e.printStackTrace();
303
		}
304
	}
305
}