Subversion Repositories SmartDukaan

Rev

Rev 3464 | Rev 3560 | 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
 
3516 rajveer 306
        // Fetch comparison statistics everyday and store them in BDB
307
        ComparisonStatsFetcher csf = new ComparisonStatsFetcher();
308
        csf.fetchAndStoreComparisonStats();
3083 vikas 309
 
310
        // Upload catalod to Google App Engine.
311
        if(GENERATION_TYPE.equals("ALL")) {
312
            List<Item> allItems = client.getAllItems(false);
313
            allItems.addAll(client.getAllItems(true));
314
            CatalogUploderToGAE catalogUploaderToGAE = new CatalogUploderToGAE();
315
            catalogUploaderToGAE.uploadItems(allItems);
316
        }
2733 rajveer 317
 
2726 rajveer 318
        items = client.getAllItemsByStatus(status.ACTIVE);
319
        items.addAll(client.getAllItemsByStatus(status.PAUSED));
320
        items.addAll(client.getAllItemsByStatus(status.CONTENT_COMPLETE));
321
        populateEntityIdItemMap();
322
 
323
        AccessoriesFinder af = new AccessoriesFinder(entityIdItemMap.keySet());
2658 rajveer 324
		Map<Long, Map<Long, List<Long>>> relatedAccessories = af.findAccessories();
325
		CreationUtils.storeRelatedAccessories(relatedAccessories);
2838 mandeep.dh 326
 
327
        SpecialPageJSONConvertor bjc = new SpecialPageJSONConvertor();
328
        bjc.writeToJSONFile(new File(Utils.EXPORT_JAVASCRIPT_CONTENT_PATH + "special-pages.json"));
329
 
2171 rajveer 330
        NewVUI vui = new NewVUI(lastGenerationTime);
2367 rajveer 331
        for(Entity entity: validEntities){
2433 rajveer 332
        		vui.generateContentForOneEntity(entity, Utils.EXPORT_VELOCITY_PATH);
2171 rajveer 333
        }
2367 rajveer 334
        CreationUtils.storeLastContentGenerationTime((new Date()).getTime());
335
 
336
 
337
        NewIR ir = new NewIR(validEntities);
2227 rajveer 338
        ir.exportIRData();
2367 rajveer 339
        //ir.transformIrDataXMLtoSolrXML();
2227 rajveer 340
        ir.exportIRMetaData();
341
        ir.transformIrMetaDataXMLSolrSchemaXML();
342
 
3439 varun.gupt 343
        // Generate synonyms list. This will be used in PriceComparisonTool to resolve the product names.
344
        SynonymExporter sx = new SynonymExporter(validEntities);
345
        sx.storeSynonyms();
346
 
2493 rajveer 347
        for(Map.Entry<Long, List<Item>> entry: entityIdItemMap.entrySet()){
348
        	List<Item> items = entry.getValue();
349
        	for(Item item: items){
350
        		if(item.getItemStatus()==status.CONTENT_COMPLETE){
351
                    item.setItemStatus(status.ACTIVE);
352
                    item.setStatus_description("This item is active");
353
                    client.updateItem(item);
354
        		}
355
        	}
356
        }
2726 rajveer 357
 
2171 rajveer 358
    }
2367 rajveer 359
 
2171 rajveer 360
 
361
    /**
2367 rajveer 362
     * Checks weather entity is valid or not. Entity will be invalid in one of these cases:
363
     * <ol>
364
     * <li>The entity is not ready.
365
     * <li>The category has not been updated yet. (Set to -1).
366
     * <li>Content has not been updated after last content generation timestamp.
367
     * </ol>
368
     * 
369
     * @param entity
370
     * @return
371
     * @throws Exception
2171 rajveer 372
     */
2367 rajveer 373
    private boolean isValidEntity(Entity entity) throws Exception{
374
        ExpandedEntity expEntity = new ExpandedEntity(entity);
375
        EntityState state = CreationUtils.getEntityState(entity.getID());
376
        long categoryID = expEntity.getCategoryID();
377
 
378
        if(state.getStatus() != EntityStatus.READY ||  categoryID == -1){
379
            return false;
380
        }
381
        if(state.getMerkedReadyOn().getTime() < this.lastGenerationTime){
382
            return false;
383
        }
384
        return true;
385
    }
386
 
387
 
388
    private void populateEntityIdItemMap(){
2171 rajveer 389
        Date todate = new Date();
2367 rajveer 390
        for(Item item: items){
2171 rajveer 391
            //TODO Can be removed as we are checking in calling function
392
            if(!(item.getItemStatus()==status.ACTIVE || item.getItemStatus()==status.CONTENT_COMPLETE || item.getItemStatus() == status.PAUSED)){
393
                continue;
394
            }
3245 rajveer 395
            if(todate.getTime() < item.getStartDate() ||  item.getSellingPrice() == 0){
2171 rajveer 396
                continue;
397
            }
2367 rajveer 398
            List<Item> itemList = entityIdItemMap.get(item.getCatalogItemId());
2171 rajveer 399
            if(itemList == null){
400
                itemList = new ArrayList<Item>();
401
            }
402
            itemList.add(item);
403
            entityIdItemMap.put(item.getCatalogItemId(), itemList);
404
        }
2367 rajveer 405
 
406
        //Remove all items which have not been updated since last content generation.
2171 rajveer 407
        List<Long> removeEntities = new ArrayList<Long>();
408
        for(Long entityId:entityIdItemMap.keySet()){
409
            boolean isValidEntity = false;
2367 rajveer 410
            //If any one of the items has been updated before current timestamp, than we generate content for whole entity
2171 rajveer 411
            for(Item item: entityIdItemMap.get(entityId)){
2367 rajveer 412
                if(item.getUpdatedOn() > lastGenerationTime){
2171 rajveer 413
                    isValidEntity = true;
414
                }
415
            }
416
            if(!isValidEntity){
417
                removeEntities.add(entityId);
418
            }
419
        }
420
        for(Long entityId: removeEntities){
421
            entityIdItemMap.remove(entityId);
422
        }
423
    }
424
 
425
}