Subversion Repositories SmartDukaan

Rev

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