Rev 2793 | Rev 3127 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
package in.shop2020.util;import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.Calendar;import java.util.Date;import java.util.HashMap;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import in.shop2020.metamodel.core.Entity;import in.shop2020.metamodel.core.EntityState;import in.shop2020.metamodel.core.EntityStatus;import in.shop2020.metamodel.util.CreationUtils;import in.shop2020.metamodel.util.ExpandedEntity;import in.shop2020.model.v1.catalog.InventoryService.Client;import in.shop2020.model.v1.catalog.Item;import in.shop2020.model.v1.catalog.status;import in.shop2020.thrift.clients.CatalogServiceClient;import in.shop2020.ui.util.ComparisonStatsFetcher;import in.shop2020.ui.util.PriceInsertor;import in.shop2020.ui.util.NewVUI;import in.shop2020.ui.util.SpecialPageJSONConvertor;import org.apache.commons.cli.*;public class ContentGenerationUtility {private static Options options = null; // Command line optionsprivate static final String UPDATE_TYPE_OPTION = "u";private static final String GENERATION_TYPE_OPTION = "t";private static final String ENTITY_ID_OPTION = "e";private static String UPDATE_TYPE = "CONTENT";private static String GENERATION_TYPE = "INCREMENTAL";private static String ENTITY_ID = "ALL";Map<Long, Entity> entities;List<Item> items;List<Item> contentCompleteItems = new ArrayList<Item>();List<Item> phasedOutItems;CatalogServiceClient csc;Client client;Map<Long, List<Item>> entityIdItemMap = new LinkedHashMap<Long, List<Item>>();private CommandLine cmd = null; // Command Line argumentsLong lastGenerationTime;static{options = new Options();options.addOption(GENERATION_TYPE_OPTION, true, "Generation type");options.addOption(UPDATE_TYPE_OPTION, true, "Default is : " + UPDATE_TYPE);options.addOption(ENTITY_ID_OPTION, true, "all entities " + ENTITY_ID + " by default");}public ContentGenerationUtility() throws Exception{csc = new CatalogServiceClient();client = csc.getClient();}/*** @param args* @throws Exception*/public static void main(String[] args) throws Exception {ContentGenerationUtility cgu = new ContentGenerationUtility();//Load argumentscgu.loadArgs(args);//Call method based on argumentscgu.callMethod();}/*** Validate and set command line arguments.* Exit after printing usage if anything is astray* @param args String[] args as featured in public static void main()*/private void loadArgs(String[] args){CommandLineParser parser = new PosixParser();try {cmd = parser.parse(options, args);} catch (ParseException e) {System.err.println("Error parsing arguments");e.printStackTrace();System.exit(1);}// Check for mandatory argsif (!( cmd.hasOption(GENERATION_TYPE_OPTION) && cmd.hasOption(UPDATE_TYPE_OPTION))){HelpFormatter formatter = new HelpFormatter();formatter.printHelp("java ContentGenerationUtility.class -t { ALL | INCREMENTAL | ONE } -u { CONTENT | CATALOG } -e {EntityId} ", options);System.exit(1);}GENERATION_TYPE = cmd.getOptionValue(GENERATION_TYPE_OPTION);UPDATE_TYPE = cmd.getOptionValue(UPDATE_TYPE_OPTION);// Look for optional args.if(GENERATION_TYPE.equals("ONE")){if (cmd.hasOption(ENTITY_ID_OPTION)){ENTITY_ID = cmd.getOptionValue(ENTITY_ID_OPTION);}else{HelpFormatter formatter = new HelpFormatter();formatter.printHelp("java ContentGenerationUtility.class -t { ALL | INCREMENTAL | ONE } -u { CONTENT | CATALOG } -e {EntityId} ", options);System.exit(1);}}}/*** Call method based on arguments* @throws Exception*/private void callMethod() throws Exception{if(UPDATE_TYPE.equals("CONTENT")){this.generateContent();}if(UPDATE_TYPE.equals("CATALOG")){this.updatePrices();}}public boolean cleanDir(File dir, boolean deleteSelf) {if (dir.isDirectory()) {String[] children = dir.list();for (int i=0; i<children.length; i++) {boolean success = cleanDir(new File(dir, children[i]), true);if (!success) {return false;}}}// The directory is now empty so delete itif(deleteSelf){return dir.delete();}return true;}private void removeOldResources() throws IOException{File f = new File(Utils.EXPORT_SOLR_PATH);if(f.exists()){cleanDir(f, false);}File f1 = new File(Utils.EXPORT_ENTITIES_PATH_LOCALHOST);if(f1.exists()){cleanDir(f1, false);}File f2 = new File(Utils.EXPORT_ENTITIES_PATH_SAHOLIC);if(f2.exists()){cleanDir(f2, false);}File f3 = new File(Utils.EXPORT_ENTITIES_PATH_SHOP2020);if(f3.exists()){cleanDir(f3, false);}}/*** Update the prices in the generated content* @throws Exception*/private void updatePrices() throws Exception {lastGenerationTime = new Long(0);if(GENERATION_TYPE.equals("ONE")) {items = client.getItemsByCatalogId(Long.parseLong(ENTITY_ID));}else{items = client.getAllItemsByStatus(status.ACTIVE);items.addAll(client.getAllItemsByStatus(status.PAUSED));//Clean up the data from the solr directories.removeOldResources();}//this still needs to be evolved. Must not be used.if(GENERATION_TYPE.equals("INCREMENTAL")) {}//Populate the entityIdIemMappopulateEntityIdItemMap();PriceInsertor priceInserter = new PriceInsertor();for(Map.Entry<Long, List<Item>> entry: entityIdItemMap.entrySet()){long entityId = entry.getKey();List<Item> items = entry.getValue();//TODO Domain name and destination directory should be read from properties filepriceInserter.insertPriceInHtml(items, entityId, "saholic.com", Utils.EXPORT_ENTITIES_PATH_SAHOLIC);priceInserter.insertPriceInHtml(items, entityId, "shop2020.in", Utils.EXPORT_ENTITIES_PATH_SHOP2020);priceInserter.insertPriceInHtml(items, entityId, "localhost:8090", Utils.EXPORT_ENTITIES_PATH_LOCALHOST);priceInserter.insertPriceInSolrData(entityId, getMinPrice(items));}//Generate partners and json objects for phones onlyif(!GENERATION_TYPE.equals("ONE")) {ProductListGenerator generator = new ProductListGenerator(entityIdItemMap);generator.generateProductsListXML();generator.generateProductListJavascript();}}/**** @param items* @return the minimum price of the items*/private double getMinPrice(List<Item> items){double minPrice = Double.MAX_VALUE;for(Item item: items){if(minPrice > item.getSellingPrice()){minPrice = item.getSellingPrice();}}return minPrice;}/*** Generates content for the specified entity embedding links to the* specified domain name.** The method will not generate content if one of the following conditions is met:* <ol>* <li>The entity is not ready.* <li>The category has not been updated yet. (Set to -1).* <li>The content has not been updated.* </ol>** @throws*/private void generateContent() throws Exception{if(GENERATION_TYPE.equals("ALL")) {entities = CreationUtils.getEntities();lastGenerationTime = new Long(0);}else if(GENERATION_TYPE.equals("ONE")) {entities = new HashMap<Long, Entity>();entities.put(Long.parseLong(ENTITY_ID), CreationUtils.getEntity(Long.parseLong(ENTITY_ID)));lastGenerationTime = new Long(0);}else{entities = CreationUtils.getEntities();lastGenerationTime = CreationUtils.getLastContentGenerationTime();if(lastGenerationTime==null){lastGenerationTime = new Long(0);}}//Filter invalid entities hereList<Entity> validEntities = new ArrayList<Entity>();for(long entityID: entities.keySet()){if(isValidEntity(entities.get(entityID))){validEntities.add(entities.get(entityID));}}//Calculate comparison scoresNewCMP cmp = new NewCMP(validEntities);Map<Long, Map<Long, Double>> slideScoresByEntity = cmp.getSlideScores();CreationUtils.storeSlideScores(slideScoresByEntity);// Fetch comparison statistics only on sunday, else use the data stored in BDBCalendar cal = Calendar.getInstance();int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);//if(dayOfWeek == Calendar.SUNDAY){long toDate = cal.getTime().getTime();cal.add(Calendar.MONTH, -1);long fromDate = cal.getTime().getTime();ComparisonStatsFetcher csf = new ComparisonStatsFetcher();csf.fetchAndStoreComparisonStats(fromDate, toDate);//}items = client.getAllItemsByStatus(status.ACTIVE);items.addAll(client.getAllItemsByStatus(status.PAUSED));items.addAll(client.getAllItemsByStatus(status.CONTENT_COMPLETE));populateEntityIdItemMap();AccessoriesFinder af = new AccessoriesFinder(entityIdItemMap.keySet());Map<Long, Map<Long, List<Long>>> relatedAccessories = af.findAccessories();CreationUtils.storeRelatedAccessories(relatedAccessories);SpecialPageJSONConvertor bjc = new SpecialPageJSONConvertor();bjc.writeToJSONFile(new File(Utils.EXPORT_JAVASCRIPT_CONTENT_PATH + "special-pages.json"));NewVUI vui = new NewVUI(lastGenerationTime);for(Entity entity: validEntities){vui.generateContentForOneEntity(entity, Utils.EXPORT_VELOCITY_PATH);}CreationUtils.storeLastContentGenerationTime((new Date()).getTime());NewIR ir = new NewIR(validEntities);ir.exportIRData();//ir.transformIrDataXMLtoSolrXML();ir.exportIRMetaData();ir.transformIrMetaDataXMLSolrSchemaXML();for(Map.Entry<Long, List<Item>> entry: entityIdItemMap.entrySet()){List<Item> items = entry.getValue();for(Item item: items){if(item.getItemStatus()==status.CONTENT_COMPLETE){item.setItemStatus(status.ACTIVE);item.setStatus_description("This item is active");client.updateItem(item);}}}}/*** Checks weather entity is valid or not. Entity will be invalid in one of these cases:* <ol>* <li>The entity is not ready.* <li>The category has not been updated yet. (Set to -1).* <li>Content has not been updated after last content generation timestamp.* </ol>** @param entity* @return* @throws Exception*/private boolean isValidEntity(Entity entity) throws Exception{ExpandedEntity expEntity = new ExpandedEntity(entity);EntityState state = CreationUtils.getEntityState(entity.getID());long categoryID = expEntity.getCategoryID();if(state.getStatus() != EntityStatus.READY || categoryID == -1){return false;}if(state.getMerkedReadyOn().getTime() < this.lastGenerationTime){return false;}return true;}private void populateEntityIdItemMap(){Date todate = new Date();for(Item item: items){//TODO Can be removed as we are checking in calling functionif(!(item.getItemStatus()==status.ACTIVE || item.getItemStatus()==status.CONTENT_COMPLETE || item.getItemStatus() == status.PAUSED)){continue;}if(todate.getTime() < item.getStartDate()){continue;}List<Item> itemList = entityIdItemMap.get(item.getCatalogItemId());if(itemList == null){itemList = new ArrayList<Item>();}itemList.add(item);entityIdItemMap.put(item.getCatalogItemId(), itemList);}//Remove all items which have not been updated since last content generation.List<Long> removeEntities = new ArrayList<Long>();for(Long entityId:entityIdItemMap.keySet()){boolean isValidEntity = false;//If any one of the items has been updated before current timestamp, than we generate content for whole entityfor(Item item: entityIdItemMap.get(entityId)){if(item.getUpdatedOn() > lastGenerationTime){isValidEntity = true;}}if(!isValidEntity){removeEntities.add(entityId);}}for(Long entityId: removeEntities){entityIdItemMap.remove(entityId);}}}