Subversion Repositories SmartDukaan

Rev

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