Subversion Repositories SmartDukaan

Rev

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