Subversion Repositories SmartDukaan

Rev

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