Subversion Repositories SmartDukaan

Rev

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