Subversion Repositories SmartDukaan

Rev

Rev 2362 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.util;
import java.util.ArrayList;
import java.util.Date;
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.NewVUI;

import org.apache.commons.cli.*;



public class ContentGenerationUtility {
    private static Options options = null; // Command line options
    
    private static final String GENERATION_TYPE_OPTION = "t";
    private static final String ENTITY_ID_OPTION = "e";
    
    private static String GENERATION_TYPE = "INCREMENTAL";
    private static String ENTITY_ID = "ALL";
    Map<Long, Entity> entities;
    List<Item> items;
    List<Item> contentCompleteItems;
    CatalogServiceClient csc;
    Client client;
    Map<Long, List<Item>> entityIdItemMap = new LinkedHashMap<Long, List<Item>>();
    private CommandLine cmd = null; // Command Line arguments
    Long lastGenerationTime;
    
    static{
        options = new Options();
        options.addOption(GENERATION_TYPE_OPTION, true, "Generation 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();
        cgu.loadArgs(args);
        cgu.generateContent();
    }
    
    /**
     * 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 args
        
        if (! cmd.hasOption(GENERATION_TYPE_OPTION)){
            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp("java ContentGenerationUtility.class -t {ALL,INCREMENTAL,ONE} -e {EntityId} ", options);
            System.exit(1);
        }
        
        GENERATION_TYPE = cmd.getOptionValue(GENERATION_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} -e {EntityId} ", options);
                System.exit(1);
            }
        }
        
    }
    
    /**
     * Generates content for the specified entity embedding links to the
     * specified domain name.
     * 
     * The method updates the member variable problems in any of the following
     * four cases:
     * <ol>
     * <li>The entity is not ready.
     * <li>The category has not been updated yet. (Set to -1).
     * <li>There are no items in the catalog corresponding to this entity.
     * <li>There are no active or content-complete items in the catalog
     * corresponding to this entity.
     * <li>Neither the items have been updated nor the content has been updated.
     * </ol>
     * 
     * @param entity
     *            - Entity for which the content has to be generated.
     * @param domain
     *            - The domain name to be used to serve static content.
     * @param exportPath
     *            - Local file system path where content has to be generated.
     * @return -True if content is generated successfully, False otherwise.
     * @throws Exception
     */

    /**
     * 
     */
    private void generateContent() throws Exception{
        if(GENERATION_TYPE.equals("ALL") || GENERATION_TYPE.equals("ONE")) {
            lastGenerationTime = new Long(0);   
        }else{
            lastGenerationTime = CreationUtils.getLastContentGenerationTime();
            if(lastGenerationTime==null){
                lastGenerationTime = new Long(0);
            }    
        }
        
        if(GENERATION_TYPE.equals("ONE")) {
            items = client.getItemsByCatalogId(Long.parseLong(ENTITY_ID));
            contentCompleteItems = new ArrayList<Item>();
            for(Item item: items){
                if(item.getItemStatus() == status.CONTENT_COMPLETE){
                    contentCompleteItems.add(item);
                }
                
            }
        }else{
            contentCompleteItems = client.getAllItemsByStatus(status.CONTENT_COMPLETE);
            items = client.getAllItemsByStatus(status.ACTIVE);
            items.addAll(client.getAllItemsByStatus(status.PAUSED));
            items.addAll(contentCompleteItems);
        }
        //If non incremental content needs to be generated
        if(GENERATION_TYPE.equals("INCREMENTAL")) {
            
        }
        
        removeInvalidItems();
        
        NewIR ir = new NewIR(entityIdItemMap);
        ir.exportIRData();
        ir.transformIrDataXMLtoSolrXML();
        ir.exportIRMetaData();
        ir.transformIrMetaDataXMLSolrSchemaXML();
        
        NewCMP cmp = new NewCMP(entityIdItemMap);
        Map<Long, Map<Long, Double>> slideScoresByEntity = cmp.getSlideScores();
//        Utils.info("slideScoresByEntity=" + slideScoresByEntity);
        
        CreationUtils.storeSlideScores(slideScoresByEntity);

        NewVUI vui = new NewVUI(lastGenerationTime);
        for(long entityID: entityIdItemMap.keySet()){
            //TODO Domain name and destination  directory should be read from properties file 
            vui.generateHtmlForOneEntity(CreationUtils.getEntity(entityID), "saholic.com", Utils.EXPORT_ENTITIES_PATH_SAHOLIC, entityIdItemMap.get(entityID));
            vui.generateHtmlForOneEntity(CreationUtils.getEntity(entityID), "shop2020.in", Utils.EXPORT_ENTITIES_PATH_SHOP2020, entityIdItemMap.get(entityID));
            vui.generateHtmlForOneEntity(CreationUtils.getEntity(entityID), "localhost:8090", Utils.EXPORT_ENTITIES_PATH_LOCALHOST, entityIdItemMap.get(entityID));
        }

        // Mark content-complete items as active after the content has been
        // generated
        for(Item item:contentCompleteItems){
            item.setItemStatus(status.ACTIVE);
            item.setStatus_description("This item is active");
            client.updateItem(item);
        }

    }
    
    /**
     * Iterate through all candidate items and remove item if one of following conditions met.
     * <li> If item is not in one  of three states ( ACTIVE, CONTENT_COMPLETE, PAUSED)
     * <li> If Entity is invalid 
     * <li> If neither content nor item is updated after last content generation
     *   
     * @throws Exception 
     *   
     */
    private void removeInvalidItems() throws Exception{
        entities =  CreationUtils.getEntities();
        Date todate = new Date();
        for(Item item: items){            
            List<Item> itemList = entityIdItemMap.get(item.getCatalogItemId());
            //TODO Can be removed as we are checking in calling function
            if(!(item.getItemStatus()==status.ACTIVE || item.getItemStatus()==status.CONTENT_COMPLETE || item.getItemStatus() == status.PAUSED)){
                continue;
            }
            if(todate.getTime() < item.getStartDate()){
                continue;
            }
            if(itemList == null){
                
                if(!isValidEntity(entities.get(item.getCatalogItemId()))){
                    continue;
                }
                itemList = new ArrayList<Item>();
            }
            itemList.add(item);
            entityIdItemMap.put(item.getCatalogItemId(), itemList);
        }
        
        /**
         * Remove all items which have not been updated ever.
         */
        List<Long> removeEntities = new ArrayList<Long>();
        for(Long entityId:entityIdItemMap.keySet()){
            boolean isValidEntity = false;
            //If any one of the items has been updated since last generation timestamp, than we generate content for whole entity
            for(Item item: entityIdItemMap.get(entityId)){
                if(item.getUpdatedOn() > this.lastGenerationTime){
                    isValidEntity = true;
                }
            }
            if(!isValidEntity){
                removeEntities.add(entityId);
            }
        }
        for(Long entityId: removeEntities){
            entityIdItemMap.remove(entityId);
        }

        
    }
    
    /**
     * 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;
    }
        
}