Subversion Repositories SmartDukaan

Rev

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