Subversion Repositories SmartDukaan

Rev

Rev 3439 | Rev 3516 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2171 rajveer 1
package in.shop2020.util;
2
import in.shop2020.metamodel.core.Entity;
3
import in.shop2020.metamodel.core.EntityState;
4
import in.shop2020.metamodel.core.EntityStatus;
5
import in.shop2020.metamodel.util.CreationUtils;
6
import in.shop2020.metamodel.util.ExpandedEntity;
7
import in.shop2020.model.v1.catalog.InventoryService.Client;
8
import in.shop2020.model.v1.catalog.Item;
9
import in.shop2020.model.v1.catalog.status;
3127 rajveer 10
import in.shop2020.thrift.clients.CatalogClient;
3083 vikas 11
import in.shop2020.ui.util.CatalogUploderToGAE;
2733 rajveer 12
import in.shop2020.ui.util.ComparisonStatsFetcher;
3083 vikas 13
import in.shop2020.ui.util.NewVUI;
2367 rajveer 14
import in.shop2020.ui.util.PriceInsertor;
2838 mandeep.dh 15
import in.shop2020.ui.util.SpecialPageJSONConvertor;
3464 rajveer 16
import in.shop2020.utils.GmailUtils;
2171 rajveer 17
 
3083 vikas 18
import java.io.File;
19
import java.io.IOException;
20
import java.util.ArrayList;
21
import java.util.Calendar;
22
import java.util.Date;
23
import java.util.HashMap;
24
import java.util.LinkedHashMap;
25
import java.util.List;
26
import java.util.Map;
2171 rajveer 27
 
3464 rajveer 28
import javax.mail.MessagingException;
29
 
3083 vikas 30
import org.apache.commons.cli.CommandLine;
31
import org.apache.commons.cli.CommandLineParser;
32
import org.apache.commons.cli.HelpFormatter;
33
import org.apache.commons.cli.Options;
34
import org.apache.commons.cli.ParseException;
35
import org.apache.commons.cli.PosixParser;
2171 rajveer 36
 
37
 
3083 vikas 38
 
2171 rajveer 39
public class ContentGenerationUtility {
40
    private static Options options = null; // Command line options
41
 
2367 rajveer 42
    private static final String UPDATE_TYPE_OPTION = "u";
2171 rajveer 43
    private static final String GENERATION_TYPE_OPTION = "t";
44
    private static final String ENTITY_ID_OPTION = "e";
45
 
2367 rajveer 46
    private static String UPDATE_TYPE = "CONTENT";
2171 rajveer 47
    private static String GENERATION_TYPE = "INCREMENTAL";
48
    private static String ENTITY_ID = "ALL";
49
    Map<Long, Entity> entities;
50
    List<Item> items;
2367 rajveer 51
    List<Item> contentCompleteItems  = new ArrayList<Item>();
52
    List<Item> phasedOutItems;
3127 rajveer 53
    CatalogClient csc;
2171 rajveer 54
    Client client;
55
    Map<Long, List<Item>> entityIdItemMap = new LinkedHashMap<Long, List<Item>>();
56
    private CommandLine cmd = null; // Command Line arguments
57
    Long lastGenerationTime;
58
 
59
    static{
60
        options = new Options();
61
        options.addOption(GENERATION_TYPE_OPTION, true, "Generation type");
2367 rajveer 62
        options.addOption(UPDATE_TYPE_OPTION, true, "Default is : " + UPDATE_TYPE);
2171 rajveer 63
        options.addOption(ENTITY_ID_OPTION, true, "all entities " + ENTITY_ID + " by default");
64
    }
65
 
66
    public ContentGenerationUtility() throws Exception{
3127 rajveer 67
        csc = new CatalogClient();
2171 rajveer 68
        client = csc.getClient();
69
    }
70
 
2367 rajveer 71
 
2171 rajveer 72
    /**
73
     * @param args
74
     * @throws Exception 
75
     */
3464 rajveer 76
    public static void main(String[] args) throws Exception{
2171 rajveer 77
        ContentGenerationUtility cgu = new ContentGenerationUtility();
2367 rajveer 78
        //Load arguments
2171 rajveer 79
        cgu.loadArgs(args);
2367 rajveer 80
        //Call method based on arguments
81
        cgu.callMethod();
2171 rajveer 82
    }
2367 rajveer 83
 
2171 rajveer 84
 
2367 rajveer 85
	/**
2171 rajveer 86
     * Validate and set command line arguments.
87
     * Exit after printing usage if anything is astray
88
     * @param args String[] args as featured in public static void main()
89
     */
90
    private void loadArgs(String[] args){
91
        CommandLineParser parser = new PosixParser();
92
        try {
93
            cmd = parser.parse(options, args);
94
        } catch (ParseException e) {
95
            System.err.println("Error parsing arguments");
96
            e.printStackTrace();
97
            System.exit(1);
98
        }
99
 
100
        // Check for mandatory args
101
 
2367 rajveer 102
        if (!( cmd.hasOption(GENERATION_TYPE_OPTION)  &&  cmd.hasOption(UPDATE_TYPE_OPTION))){
2171 rajveer 103
            HelpFormatter formatter = new HelpFormatter();
2367 rajveer 104
            formatter.printHelp("java ContentGenerationUtility.class -t { ALL | INCREMENTAL | ONE } -u { CONTENT | CATALOG } -e {EntityId} ", options);
2171 rajveer 105
            System.exit(1);
106
        }
107
 
108
        GENERATION_TYPE = cmd.getOptionValue(GENERATION_TYPE_OPTION);
2367 rajveer 109
 
110
        UPDATE_TYPE = cmd.getOptionValue(UPDATE_TYPE_OPTION);
111
 
2171 rajveer 112
        // Look for optional args.
113
        if(GENERATION_TYPE.equals("ONE")){
114
            if (cmd.hasOption(ENTITY_ID_OPTION)){
115
                ENTITY_ID = cmd.getOptionValue(ENTITY_ID_OPTION);
116
            }else{
117
                HelpFormatter formatter = new HelpFormatter();
2367 rajveer 118
                formatter.printHelp("java ContentGenerationUtility.class -t { ALL | INCREMENTAL | ONE } -u { CONTENT | CATALOG } -e {EntityId} ", options);
2171 rajveer 119
                System.exit(1);
120
            }
121
        }
2367 rajveer 122
    }
123
 
124
    /**
125
     * Call method based on arguments
126
     * @throws Exception
127
     */
3464 rajveer 128
    private void callMethod(){
129
    	boolean isSuccess = false;
130
    	String logfile = "/tmp/content-from-cms.log";
2367 rajveer 131
    	if(UPDATE_TYPE.equals("CONTENT")){
3464 rajveer 132
    		logfile = "/tmp/content-from-cms.log";
133
    		try{
134
    			this.generateContent();
135
    			isSuccess = true;
136
    		}catch (Exception e) {
137
    			e.printStackTrace();
138
			}
2367 rajveer 139
    	}
140
 
141
    	if(UPDATE_TYPE.equals("CATALOG")){
3464 rajveer 142
    		logfile = "/tmp/content-from-catalog.log";
143
    		try{
144
    			this.updatePrices();
145
    			isSuccess = true;
146
    		}catch (Exception e) {
147
    			e.printStackTrace();
148
			}
149
    	}
150
 
151
    	GmailUtils gm = new GmailUtils();
152
		String[] sendTo = { "chandranshu.s@shop2020.in", "rajveer.singh@shop2020.in" };
153
		try {
154
			gm.sendSSLMessage(sendTo, "Content Generation Successful ? : " + isSuccess, "Content generation completed at time : " + Calendar.getInstance().getTime().toString(), "build@shop2020.in", "shop2020", logfile);
155
		} catch (MessagingException e) {
156
			// TODO Auto-generated catch block
157
			e.printStackTrace();
158
		}
2367 rajveer 159
    }
160
 
161
 
162
 
2369 rajveer 163
	public boolean cleanDir(File dir, boolean deleteSelf) {
2367 rajveer 164
	    if (dir.isDirectory()) {
165
	        String[] children = dir.list();
166
	        for (int i=0; i<children.length; i++) {
2369 rajveer 167
	            boolean success = cleanDir(new File(dir, children[i]), true);
2367 rajveer 168
	            if (!success) {
169
	                return false;
170
	            }
171
	        }
172
	    }
173
	    // The directory is now empty so delete it
2369 rajveer 174
	    if(deleteSelf){
175
	    	return dir.delete();
176
	    }
177
	    return true;
2367 rajveer 178
	}
179
 
180
 
181
	private void removeOldResources() throws IOException{
182
		File f = new File(Utils.EXPORT_SOLR_PATH);
183
		if(f.exists()){
2369 rajveer 184
			cleanDir(f, false);
2367 rajveer 185
		}
186
 
187
		File f1 = new File(Utils.EXPORT_ENTITIES_PATH_LOCALHOST);
188
		if(f1.exists()){
2369 rajveer 189
			cleanDir(f1, false);
2367 rajveer 190
		}
191
 
192
		File f2 = new File(Utils.EXPORT_ENTITIES_PATH_SAHOLIC);
193
		if(f2.exists()){
2369 rajveer 194
			cleanDir(f2, false);
2367 rajveer 195
		}
196
 
197
		File f3 = new File(Utils.EXPORT_ENTITIES_PATH_SHOP2020);
198
		if(f3.exists()){
2369 rajveer 199
			cleanDir(f3, false);
2367 rajveer 200
		}
201
	}
202
 
203
    /**
204
     * Update the prices in the generated content
205
     * @throws Exception
206
     */
207
    private void updatePrices() throws Exception {
208
    	lastGenerationTime = new Long(0);
209
        if(GENERATION_TYPE.equals("ONE")) {
210
            items = client.getItemsByCatalogId(Long.parseLong(ENTITY_ID));
211
        }else{
212
            items = client.getAllItemsByStatus(status.ACTIVE);
213
            items.addAll(client.getAllItemsByStatus(status.PAUSED));
214
 
215
            //Clean up the data from the solr directories.
216
            removeOldResources();
217
 
218
        }
219
        //this still needs to be evolved. Must not be used.
220
        if(GENERATION_TYPE.equals("INCREMENTAL")) {
221
        }
222
 
223
 
2171 rajveer 224
 
2367 rajveer 225
        //Populate the entityIdIemMap 
226
        populateEntityIdItemMap();
227
 
228
        PriceInsertor priceInserter = new PriceInsertor();
229
 
230
        for(Map.Entry<Long, List<Item>> entry: entityIdItemMap.entrySet()){
231
        	long entityId = entry.getKey();
232
        	List<Item> items = entry.getValue();
233
            //TODO Domain name and destination  directory should be read from properties file
234
        	priceInserter.insertPriceInHtml(items, entityId, "saholic.com", Utils.EXPORT_ENTITIES_PATH_SAHOLIC);
235
        	priceInserter.insertPriceInHtml(items, entityId, "shop2020.in", Utils.EXPORT_ENTITIES_PATH_SHOP2020);
236
        	priceInserter.insertPriceInHtml(items, entityId, "localhost:8090", Utils.EXPORT_ENTITIES_PATH_LOCALHOST);
237
        	priceInserter.insertPriceInSolrData(entityId, getMinPrice(items));
238
        }
239
 
240
        //Generate partners and json objects for phones only
241
        if(!GENERATION_TYPE.equals("ONE")) {
242
        	ProductListGenerator generator = new ProductListGenerator(entityIdItemMap);
243
			generator.generateProductsListXML();
244
			generator.generateProductListJavascript();
245
        }
246
 
2171 rajveer 247
    }
248
 
2367 rajveer 249
 
2171 rajveer 250
    /**
2367 rajveer 251
     * 
252
     * @param items
253
     * @return the minimum price of the items
254
     */
255
	private double getMinPrice(List<Item> items){
256
        double minPrice = Double.MAX_VALUE;
257
        for(Item item: items){
258
            if(minPrice > item.getSellingPrice()){
259
                minPrice = item.getSellingPrice();
260
            }
261
        }
262
        return minPrice;
263
    }
264
 
265
 
266
	/**
2171 rajveer 267
     * Generates content for the specified entity embedding links to the
268
     * specified domain name.
269
     * 
2367 rajveer 270
     * The method will not generate content if one of the following conditions is met:
2171 rajveer 271
     * <ol>
272
     * <li>The entity is not ready.
273
     * <li>The category has not been updated yet. (Set to -1).
2367 rajveer 274
     * <li>The content has not been updated.
2171 rajveer 275
     * </ol>
2367 rajveer 276
     *
277
     * @throws
2171 rajveer 278
     */
279
    private void generateContent() throws Exception{
2367 rajveer 280
        if(GENERATION_TYPE.equals("ALL")) {
281
        	entities = CreationUtils.getEntities();
282
            lastGenerationTime = new Long(0);
283
        }else if(GENERATION_TYPE.equals("ONE")) {
284
        	entities = new HashMap<Long, Entity>();
285
        	entities.put(Long.parseLong(ENTITY_ID), CreationUtils.getEntity(Long.parseLong(ENTITY_ID)));
2171 rajveer 286
            lastGenerationTime = new Long(0);   
287
        }else{
2367 rajveer 288
        	entities = CreationUtils.getEntities();
2171 rajveer 289
            lastGenerationTime = CreationUtils.getLastContentGenerationTime();
290
            if(lastGenerationTime==null){
291
                lastGenerationTime = new Long(0);
292
            }    
293
        }
2367 rajveer 294
        //Filter invalid entities here
295
        List<Entity> validEntities = new ArrayList<Entity>();
296
        for(long entityID: entities.keySet()){
297
        	if(isValidEntity(entities.get(entityID))){
298
        		validEntities.add(entities.get(entityID));
299
        	}
2171 rajveer 300
        }
2367 rajveer 301
        //Calculate comparison scores
302
        NewCMP cmp = new NewCMP(validEntities);
2171 rajveer 303
        Map<Long, Map<Long, Double>> slideScoresByEntity = cmp.getSlideScores();
2367 rajveer 304
        CreationUtils.storeSlideScores(slideScoresByEntity);
2658 rajveer 305
 
2743 rajveer 306
        // Fetch comparison statistics only on sunday, else use the data stored in BDB
307
        Calendar cal = Calendar.getInstance();
3083 vikas 308
        //int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
2793 rajveer 309
        //if(dayOfWeek == Calendar.SUNDAY){
2775 rajveer 310
    		long toDate = cal.getTime().getTime();
311
    		cal.add(Calendar.MONTH, -1);
312
    		long fromDate = cal.getTime().getTime();
2743 rajveer 313
        	ComparisonStatsFetcher csf = new ComparisonStatsFetcher();
2775 rajveer 314
        	csf.fetchAndStoreComparisonStats(fromDate, toDate);
2793 rajveer 315
        //}
3083 vikas 316
 
317
        // Upload catalod to Google App Engine.
318
        if(GENERATION_TYPE.equals("ALL")) {
319
            List<Item> allItems = client.getAllItems(false);
320
            allItems.addAll(client.getAllItems(true));
321
            CatalogUploderToGAE catalogUploaderToGAE = new CatalogUploderToGAE();
322
            catalogUploaderToGAE.uploadItems(allItems);
323
        }
2733 rajveer 324
 
2726 rajveer 325
        items = client.getAllItemsByStatus(status.ACTIVE);
326
        items.addAll(client.getAllItemsByStatus(status.PAUSED));
327
        items.addAll(client.getAllItemsByStatus(status.CONTENT_COMPLETE));
328
        populateEntityIdItemMap();
329
 
330
        AccessoriesFinder af = new AccessoriesFinder(entityIdItemMap.keySet());
2658 rajveer 331
		Map<Long, Map<Long, List<Long>>> relatedAccessories = af.findAccessories();
332
		CreationUtils.storeRelatedAccessories(relatedAccessories);
2838 mandeep.dh 333
 
334
        SpecialPageJSONConvertor bjc = new SpecialPageJSONConvertor();
335
        bjc.writeToJSONFile(new File(Utils.EXPORT_JAVASCRIPT_CONTENT_PATH + "special-pages.json"));
336
 
2171 rajveer 337
        NewVUI vui = new NewVUI(lastGenerationTime);
2367 rajveer 338
        for(Entity entity: validEntities){
2433 rajveer 339
        		vui.generateContentForOneEntity(entity, Utils.EXPORT_VELOCITY_PATH);
2171 rajveer 340
        }
2367 rajveer 341
        CreationUtils.storeLastContentGenerationTime((new Date()).getTime());
342
 
343
 
344
        NewIR ir = new NewIR(validEntities);
2227 rajveer 345
        ir.exportIRData();
2367 rajveer 346
        //ir.transformIrDataXMLtoSolrXML();
2227 rajveer 347
        ir.exportIRMetaData();
348
        ir.transformIrMetaDataXMLSolrSchemaXML();
349
 
3439 varun.gupt 350
        // Generate synonyms list. This will be used in PriceComparisonTool to resolve the product names.
351
        SynonymExporter sx = new SynonymExporter(validEntities);
352
        sx.storeSynonyms();
353
 
2493 rajveer 354
        for(Map.Entry<Long, List<Item>> entry: entityIdItemMap.entrySet()){
355
        	List<Item> items = entry.getValue();
356
        	for(Item item: items){
357
        		if(item.getItemStatus()==status.CONTENT_COMPLETE){
358
                    item.setItemStatus(status.ACTIVE);
359
                    item.setStatus_description("This item is active");
360
                    client.updateItem(item);
361
        		}
362
        	}
363
        }
2726 rajveer 364
 
2171 rajveer 365
    }
2367 rajveer 366
 
2171 rajveer 367
 
368
    /**
2367 rajveer 369
     * Checks weather entity is valid or not. Entity will be invalid in one of these cases:
370
     * <ol>
371
     * <li>The entity is not ready.
372
     * <li>The category has not been updated yet. (Set to -1).
373
     * <li>Content has not been updated after last content generation timestamp.
374
     * </ol>
375
     * 
376
     * @param entity
377
     * @return
378
     * @throws Exception
2171 rajveer 379
     */
2367 rajveer 380
    private boolean isValidEntity(Entity entity) throws Exception{
381
        ExpandedEntity expEntity = new ExpandedEntity(entity);
382
        EntityState state = CreationUtils.getEntityState(entity.getID());
383
        long categoryID = expEntity.getCategoryID();
384
 
385
        if(state.getStatus() != EntityStatus.READY ||  categoryID == -1){
386
            return false;
387
        }
388
        if(state.getMerkedReadyOn().getTime() < this.lastGenerationTime){
389
            return false;
390
        }
391
        return true;
392
    }
393
 
394
 
395
    private void populateEntityIdItemMap(){
2171 rajveer 396
        Date todate = new Date();
2367 rajveer 397
        for(Item item: items){
2171 rajveer 398
            //TODO Can be removed as we are checking in calling function
399
            if(!(item.getItemStatus()==status.ACTIVE || item.getItemStatus()==status.CONTENT_COMPLETE || item.getItemStatus() == status.PAUSED)){
400
                continue;
401
            }
3245 rajveer 402
            if(todate.getTime() < item.getStartDate() ||  item.getSellingPrice() == 0){
2171 rajveer 403
                continue;
404
            }
2367 rajveer 405
            List<Item> itemList = entityIdItemMap.get(item.getCatalogItemId());
2171 rajveer 406
            if(itemList == null){
407
                itemList = new ArrayList<Item>();
408
            }
409
            itemList.add(item);
410
            entityIdItemMap.put(item.getCatalogItemId(), itemList);
411
        }
2367 rajveer 412
 
413
        //Remove all items which have not been updated since last content generation.
2171 rajveer 414
        List<Long> removeEntities = new ArrayList<Long>();
415
        for(Long entityId:entityIdItemMap.keySet()){
416
            boolean isValidEntity = false;
2367 rajveer 417
            //If any one of the items has been updated before current timestamp, than we generate content for whole entity
2171 rajveer 418
            for(Item item: entityIdItemMap.get(entityId)){
2367 rajveer 419
                if(item.getUpdatedOn() > lastGenerationTime){
2171 rajveer 420
                    isValidEntity = true;
421
                }
422
            }
423
            if(!isValidEntity){
424
                removeEntities.add(entityId);
425
            }
426
        }
427
        for(Long entityId: removeEntities){
428
            entityIdItemMap.remove(entityId);
429
        }
430
    }
431
 
432
}