Subversion Repositories SmartDukaan

Rev

Rev 9878 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.util;

import in.shop2020.logistics.DeliveryType;
import in.shop2020.logistics.LogisticsInfo;
import in.shop2020.logistics.LogisticsService;
import in.shop2020.metamodel.core.Entity;
import in.shop2020.metamodel.definitions.Catalog;
import in.shop2020.metamodel.definitions.Category;
import in.shop2020.metamodel.definitions.DefinitionsContainer;
import in.shop2020.metamodel.util.CreationUtils;
import in.shop2020.model.v1.catalog.CatalogService.Client;
import in.shop2020.model.v1.catalog.Item;
import in.shop2020.model.v1.catalog.status;
import in.shop2020.model.v1.user.ItemCouponDiscount;
import in.shop2020.thrift.clients.CatalogClient;
import in.shop2020.thrift.clients.LogisticsClient;
import in.shop2020.thrift.clients.PromotionClient;
import in.shop2020.utils.GmailUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.mail.MessagingException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.xerces.parsers.DOMParser;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

/**
 * Command line utility to generate xml file for partners
 * 
 * @author rajveer
 *
 */
public class ProductListGenerator {

        private static Log log = LogFactory.getLog(ContentGenerationUtility.class);
        
        private String[] xmlIndentation = {"", "    ", "        ", "            ","                "};
        private Client cc = null;
        List <Long> inStockCatalogItemIds = new ArrayList<Long>();

        public Map<Long, List<Item>> entityIdItemMap;
        private static final String DEFAULT_PINCODE = "110001";
        DefinitionsContainer defContainer = Catalog.getInstance().getDefinitionsContainer();
        private List<Long> validParentCategories = Arrays.asList((long)Utils.LAPTOPS_CATEGORY, (long)Utils.CAMERAS_CATEGORY, (long)Utils.MOBILE_PHONES_CATAGORY, (long)Utils.TABLETS_CATEGORY);
        /*private List<Long> voucherEntities = new ArrayList<Long>();*/
        
        public ProductListGenerator(Map<Long, List<Item>> entityIdItemMap) throws Exception {
                this.entityIdItemMap = entityIdItemMap;
        }
        
        public ProductListGenerator(List<Item> items) throws Exception {
                populateEntityIdItemMap(items);
        }
        
        
        /**
         * Get the url of the entity
         * @param expEntity
         * @return url
         */
        private String getProductURL(long entityId, Item item){
                //long rootCategoryId = catm.getCategory(item.getCategory()).getParent_category_id();
                in.shop2020.metamodel.definitions.Category parentCategory = defContainer.getCategory(item.getCategory()).getParentCategory();
                
                String url = "http://www.saholic.com/" + parentCategory.getLabel().toLowerCase().replace(' ', '-') + "/";
                String productUrl = ((item.getBrand() != null) ? item.getBrand().trim() + " " : "").toLowerCase().replace(' ', '-')
        + "-" + ((item.getModelName() != null) ? item.getModelName().trim() + " " : "").toLowerCase().replace(' ', '-') 
            + "-" + (( item.getModelNumber() != null ) ? item.getModelNumber().trim() + " ": "" ).toLowerCase().replace(' ', '-')
        + "-" + entityId;
                productUrl = productUrl.replaceAll("/", "-");
                url = url + productUrl;
                url = url.replaceAll("-+", "-");
                return url;
        }
        
        
        /**
         * Get the url of the entity
         * @param expEntity
         * @return url
         */
        private String getProductURL(long entityId, Item item, int affiliateId){
                //long rootCategoryId = catm.getCategory(item.getCategory()).getParent_category_id();
                in.shop2020.metamodel.definitions.Category parentCategory = defContainer.getCategory(item.getCategory()).getParentCategory();
                
                String url = "http://www.saholic.com/" + parentCategory.getLabel().toLowerCase().replace(' ', '-') + "/";
                String productUrl = ((item.getBrand() != null) ? item.getBrand().trim() + " " : "").toLowerCase().replace(' ', '-')
                + "-" + ((item.getModelName() != null) ? item.getModelName().trim() + " " : "").toLowerCase().replace(' ', '-') 
                + "-" + (( item.getModelNumber() != null ) ? item.getModelNumber().trim() + " ": "" ).toLowerCase().replace(' ', '-')
                + "-" + entityId;
                productUrl = productUrl.replaceAll("/", "-");
                url = url + productUrl;
                url = url.replaceAll("-+", "-");
                return url + "?afid=" + affiliateId;
        }

        
    
        /**
         * Get the minimum mrp of the items
         * @param items
         * @return
         */
        private double getMinMRP(List<Item> items){
        double minPrice = Double.MAX_VALUE;
        for(Item item: items){
            if(minPrice > item.getMrp()){
                minPrice =  item.getMrp();
            }
        }
        return minPrice;
    }
        
        public List<Long> getInStockCatalogItemIds() {
                return inStockCatalogItemIds;
        }
        
        
        
    
        /**
         * Get the minimum price of the items
         * @param items
         * @return
         */
        private double getMinPrice(List<Item> items){
        double minPrice = Double.MAX_VALUE;
        for(Item item: items){
            if(minPrice > item.getSellingPrice()){
                minPrice = item.getSellingPrice();
            }
        }
        return minPrice;
    }

        /**
         * Check whether product is mobile or not
         * @param item
         * @return
         */
        private boolean isMobile(Item item){
                in.shop2020.metamodel.definitions.Category parentCategory = defContainer.getCategory(item.getCategory()).getParentCategory();
                return parentCategory.getID() == Utils.MOBILE_PHONES_CATAGORY;
        }
        
        /**
         * Checks whether a product is tablet or not
         */
        private boolean isTablet(Item item) {
                in.shop2020.metamodel.definitions.Category parentCategory = defContainer.getCategory(item.getCategory()).getParentCategory();
                return parentCategory.getID() == Utils.TABLETS_CATEGORY;
        }

        /**
         * Checks whether a product is camera or not
         */
        private boolean isCamera(Item item) {
                in.shop2020.metamodel.definitions.Category parentCategory = defContainer.getCategory(item.getCategory()).getParentCategory();
                return parentCategory.getID() == Utils.CAMERAS_CATEGORY;
        }
        
        /**
         * Checks whether a product is laptop or not
         */
        private boolean isLaptop(Item item) {
                in.shop2020.metamodel.definitions.Category parentCategory = defContainer.getCategory(item.getCategory()).getParentCategory();
                return parentCategory.getID() == Utils.LAPTOPS_CATEGORY;
        }
        
        /**
         * Checks whether a product is accessory or not
         */
        private boolean isAccessory(Item item)  {
                in.shop2020.metamodel.definitions.Category parentCategory = defContainer.getCategory(item.getCategory()).getParentCategory();
                return parentCategory.getID() == Utils.MOBILE_ACCESSORIES_CATEGORY || parentCategory.getID() == Utils.LAPTOP_ACCESSORIES_CATEGORY;
        }
        
        /**
         * 
         * @param item
         * @return
         */
        private String getProductTitle(Item item){
                String title = ((item.getBrand() != null) ? item.getBrand().trim() + " " : "")
                + ((item.getModelName() != null) ? item.getModelName().trim() + " " : "")
                + (( item.getModelNumber() != null ) ? item.getModelNumber().trim() : "" );
                title = title.replaceAll("  ", " ");
                return title;
        }
    
        /**
         * get xml feed for partner sites
         * @param irDataXMLSnippets
         * @throws Exception
         */
        private void getProductsXML(ArrayList<String> irDataXMLSnippets) throws Exception{
                LogisticsService.Client prod_client = null;
                Map<Long, ItemCouponDiscount> couponsAndDiscounts = new HashMap<Long, ItemCouponDiscount>();
                
                try {
                        
                        List<Long> itemIds = new ArrayList<Long>();
                        
                        for(Long entityId: entityIdItemMap.keySet()){
                                
                                List<Item> items = entityIdItemMap.get(entityId);
                                Item firstItem = items.get(0);
                                
                                if(!firstItem.getItemStatus().equals(status.COMING_SOON) && isMobile(firstItem) || isLaptop(firstItem)) {
                                        itemIds.add(firstItem.getId());
                                }
                        }
                        
                        PromotionClient promotionClient = new PromotionClient();
                        in.shop2020.model.v1.user.PromotionService.Client promotionServiceClient = promotionClient.getClient();
                        
                        List<ItemCouponDiscount> itemsCouponsAndDiscounts = promotionServiceClient.getItemDiscountMap(itemIds);
                        
                        for (ItemCouponDiscount itemCouponDiscount: itemsCouponsAndDiscounts) {
                                couponsAndDiscounts.put(itemCouponDiscount.getItemId(), itemCouponDiscount);
                        }

                        LogisticsClient logistics_prod = new LogisticsClient("logistics_service_prod_server_host","logistics_service_prod_server_port");
                        prod_client = logistics_prod.getClient();
                        
                } catch (Exception e) {
                        prod_client = null;
                        Utils.info("Logistics estimations can't be fetched as Logistics Service is inaccessible" + e);
                }
                
                for(Long entityId: entityIdItemMap.keySet()){
                        List<Item> items = entityIdItemMap.get(entityId);
                        Item firstItem = items.get(0);
                        
                        if((firstItem.getItemStatus().equals(status.COMING_SOON) && !firstItem.isShowSellingPrice()) || !isMobile(firstItem) && !isTablet(firstItem))   {
                                continue;
                        }
                        
                        irDataXMLSnippets.add(this.xmlIndentation[1] + "<products>");   
                        
                        irDataXMLSnippets.add(this.xmlIndentation[2] + "<ProductSKU>" + entityId + "</ProductSKU>");
                        
                        String title = getProductTitle(firstItem);
                        irDataXMLSnippets.add(this.xmlIndentation[2] + "<ProductName>" + title + "</ProductName>");

                        String url = getProductURL(entityId, firstItem);
                                                
                        String imageUrl = "http://static" + ((entityId+1)%3) + ".saholic.com" + File.separator + "images" + File.separator +
                                          "website" + File.separator + entityId + File.separator + "icon.jpg";

                        irDataXMLSnippets.add(this.xmlIndentation[2] + "<ProductURL>" + url + "</ProductURL>");
                        irDataXMLSnippets.add(this.xmlIndentation[2] + "<Availability>" + (inStockCatalogItemIds.contains(entityId) ? "Y" : "N") + "</Availability>");
                        double minPrice = getMinPrice(items);
                        
                        if(couponsAndDiscounts.containsKey(firstItem.getId()))  {
                                
                                int discountedPrice = (int)(minPrice - couponsAndDiscounts.get(firstItem.getId()).getDiscount());
                                irDataXMLSnippets.add(this.xmlIndentation[2] + "<ProductPrice>" + discountedPrice + "</ProductPrice>");
                                
                        } else  {
                                irDataXMLSnippets.add(this.xmlIndentation[2] + "<ProductPrice>" + minPrice + "</ProductPrice>");
                        }
                        
                        if (StringUtils.isNotEmpty(firstItem.getBestDealText())) {
                                irDataXMLSnippets.add(this.xmlIndentation[2] + "<DealText>" + StringEscapeUtils.escapeXml(firstItem.getBestDealText()) + "</DealText>");
                        }
                        
                        irDataXMLSnippets.add(this.xmlIndentation[2] + "<ProductMRP>" + getMinMRP(items) + "</ProductMRP>");
                        
                        LogisticsInfo logisticsInfo = null;
                        if(prod_client != null){
                                try {
                                        Long itemId = prod_client.getEntityLogisticsEstimation(
                                                        entityId, DEFAULT_PINCODE, DeliveryType.PREPAID)
                                                        .get(0).getItemId();
                                        logisticsInfo = prod_client.getLogisticsEstimation(itemId,
                                                        DEFAULT_PINCODE, DeliveryType.PREPAID);
                                        irDataXMLSnippets.add(this.xmlIndentation[2] + "<ProductDeliveryEstimate>" + logisticsInfo.getDeliveryTime() + "</ProductDeliveryEstimate>");
                                } catch (Exception e1) {
                                        Utils.info("Unable to get Estimation for Entity: " + entityId + "\n" + e1);
                                }
                        }
                        irDataXMLSnippets.add(this.xmlIndentation[2] + "<ProductImageURL>" + imageUrl + "</ProductImageURL>");
                        
                        irDataXMLSnippets.add(this.xmlIndentation[1] + "</products>");          
                }
        }
        
        /**
         * Generate the xml list of all the active phones and store in a file
         * @throws Exception
         */
        public void generateProductsListXML() throws Exception {
                ArrayList<String> productXMLSnippets = new ArrayList<String>();
                productXMLSnippets.add("<saholic.com>");
                
                getProductsXML(productXMLSnippets);
                
                productXMLSnippets.add("</saholic.com>");
                
                String productDataXML = StringUtils.join(productXMLSnippets, "\n");
                
                Utils.info(productDataXML);
                
                // Write it to file
                String productXMLFilename = Utils.EXPORT_PARTNERS_CONTENT_PATH + "saholicmobilephones.xml";
                DBUtils.store(productDataXML, productXMLFilename);
        }

        /**
         * Generate the xml list of all the active accessories and store in a file
         * @throws Exception
         */
        public void generateAccessoriesXML() throws Exception   {
                LogisticsService.Client prod_client = null;
        
                try     {
                        LogisticsClient logistics_prod = new LogisticsClient("logistics_service_prod_server_host","logistics_service_prod_server_port");
                        prod_client = logistics_prod.getClient();
                
                } catch (Exception e) {
                        prod_client = null;
                        Utils.info("Logistics estimations can't be fetched as Logistics Service is inaccessible" + e);
                }
                List<String> accessoriesXMLSnippets = new ArrayList<String>();
                
                accessoriesXMLSnippets.add("<saholic.com>");
                
                for(Long entityId: entityIdItemMap.keySet())    {
                        
                        List<Item> items = entityIdItemMap.get(entityId);
                        Item firstItem = items.get(0);
                        
                        if(! isAccessory(firstItem))    {
                                continue;
                        }
                        String title = getProductTitle(firstItem);
                        String url = getProductURL(entityId, firstItem);
                        String imageUrl = "http://static" + ((entityId+1)%3) + ".saholic.com" + File.separator + "images" + File.separator +
            "website" + File.separator + entityId + File.separator + "icon.jpg";
                        
                        accessoriesXMLSnippets.add(this.xmlIndentation[1] + "<products>");      
                        accessoriesXMLSnippets.add(this.xmlIndentation[2] + "<ProductSKU>" + entityId + "</ProductSKU>");
                        accessoriesXMLSnippets.add(this.xmlIndentation[2] + "<ProductName>" + StringEscapeUtils.escapeXml(title) + "</ProductName>");
                        accessoriesXMLSnippets.add(this.xmlIndentation[2] + "<ProductURL>" + StringEscapeUtils.escapeXml(url) + "</ProductURL>");
                        accessoriesXMLSnippets.add(this.xmlIndentation[2] + "<ProductPrice>" + getMinPrice(items) + "</ProductPrice>");
                        accessoriesXMLSnippets.add(this.xmlIndentation[2] + "<ProductMRP>" + getMinMRP(items) + "</ProductMRP>");
                        
                        LogisticsInfo logisticsInfo = null;
                        if(prod_client != null){
                                try {
                                        Long itemId = prod_client.getEntityLogisticsEstimation(entityId, DEFAULT_PINCODE, DeliveryType.PREPAID).get(0).getItemId();
                                        logisticsInfo = prod_client.getLogisticsEstimation(itemId, DEFAULT_PINCODE, DeliveryType.PREPAID);
                                        accessoriesXMLSnippets.add(this.xmlIndentation[2] + "<ProductDeliveryEstimate>" + logisticsInfo.getDeliveryTime() + "</ProductDeliveryEstimate>");
                                } catch (Exception e1) {
                                        Utils.info("Unable to get Estimation for Entity: " + entityId + "\n" + e1);
                                }
                        }
                        accessoriesXMLSnippets.add(this.xmlIndentation[2] + "<ProductImageURL>" + imageUrl + "</ProductImageURL>");
                        accessoriesXMLSnippets.add(this.xmlIndentation[1] + "</products>");             
                }
                
                accessoriesXMLSnippets.add("</saholic.com>");

                String accessoriesXML = StringUtils.join(accessoriesXMLSnippets, "\n");
                
                Utils.info(accessoriesXML);
                
                // Write it to file
                String accessoriesXMLFilename = Utils.EXPORT_PARTNERS_CONTENT_PATH + "saholicaccessories.xml";
                DBUtils.store(accessoriesXML, accessoriesXMLFilename);
        }

        
        
        /**
         * Generate the xml list of all the active cameras and store in a file
         * @throws Exception
         */
        public void generateCamerasXML() throws Exception       {
                LogisticsService.Client prod_client = null;
                
                try     {
                        LogisticsClient logistics_prod = new LogisticsClient("logistics_service_prod_server_host","logistics_service_prod_server_port");
                        prod_client = logistics_prod.getClient();
                        
                } catch (Exception e) {
                        prod_client = null;
                        Utils.info("Logistics estimations can't be fetched as Logistics Service is inaccessible" + e);
                }
                List<String> camerasXMLSnippets = new ArrayList<String>();
                
                camerasXMLSnippets.add("<saholic.com>");
                
                for(Long entityId: entityIdItemMap.keySet())    {
                        
                        List<Item> items = entityIdItemMap.get(entityId);
                        Item firstItem = items.get(0);
                        
                        if(! isCamera(firstItem))       {
                                continue;
                        }
                        String title = getProductTitle(firstItem);
                        String url = getProductURL(entityId, firstItem);
                        String imageUrl = "http://static" + ((entityId+1)%3) + ".saholic.com" + File.separator + "images" + File.separator +
                        "website" + File.separator + entityId + File.separator + "icon.jpg";
                        
                        camerasXMLSnippets.add(this.xmlIndentation[1] + "<products>");  
                        camerasXMLSnippets.add(this.xmlIndentation[2] + "<ProductSKU>" + entityId + "</ProductSKU>");
                        camerasXMLSnippets.add(this.xmlIndentation[2] + "<ProductName>" + StringEscapeUtils.escapeXml(title) + "</ProductName>");
                        camerasXMLSnippets.add(this.xmlIndentation[2] + "<ProductURL>" + StringEscapeUtils.escapeXml(url) + "</ProductURL>");
                        camerasXMLSnippets.add(this.xmlIndentation[2] + "<ProductPrice>" + getMinPrice(items) + "</ProductPrice>");
                        camerasXMLSnippets.add(this.xmlIndentation[2] + "<ProductMRP>" + getMinMRP(items) + "</ProductMRP>");
                        camerasXMLSnippets.add(this.xmlIndentation[2] + "<Availability>" + (inStockCatalogItemIds.contains(entityId) ? "Y" : "N") + "</Availability>");
                        
                        LogisticsInfo logisticsInfo = null;
                        if(prod_client != null){
                                try {
                                        Long itemId = prod_client.getEntityLogisticsEstimation(entityId, DEFAULT_PINCODE, DeliveryType.PREPAID).get(0).getItemId();
                                        logisticsInfo = prod_client.getLogisticsEstimation(itemId, DEFAULT_PINCODE, DeliveryType.PREPAID);
                                        camerasXMLSnippets.add(this.xmlIndentation[2] + "<ProductDeliveryEstimate>" + logisticsInfo.getDeliveryTime() + "</ProductDeliveryEstimate>");
                                } catch (Exception e1) {
                                        Utils.info("Unable to get Estimation for Entity: " + entityId + "\n" + e1);
                                }
                        }
                        camerasXMLSnippets.add(this.xmlIndentation[2] + "<ProductImageURL>" + imageUrl + "</ProductImageURL>");
                        camerasXMLSnippets.add(this.xmlIndentation[1] + "</products>");         
                }
                
                camerasXMLSnippets.add("</saholic.com>");
                
                String camerasXML = StringUtils.join(camerasXMLSnippets, "\n");
                
                Utils.info(camerasXML);
                
                // Write it to file
                String accessoriesXMLFilename = Utils.EXPORT_PARTNERS_CONTENT_PATH + "saholiccameras.xml";
                DBUtils.store(camerasXML, accessoriesXMLFilename);
        }

        /**
         * get xml feed for partner sites
         * @param irDataXMLSnippets
         * @throws Exception
         */
        private void getProductsJavascript(StringBuffer sb) throws Exception{

                Map<String, Map<String, Long>> products = new HashMap<String, Map<String,Long>>();
                
                for(Map.Entry<Long, List<Item>> entry : entityIdItemMap.entrySet())     {
                        Item item = entry.getValue().get(0);
                        in.shop2020.metamodel.definitions.Category category = defContainer.getCategory(item.getCategory());
                        in.shop2020.metamodel.definitions.Category parentCategory = category.getParentCategory();
                        String categoryLabel = category.getLabel();
                        if(parentCategory.isComparable()){
                                categoryLabel = parentCategory.getLabel();
                        }
                        if(!products.containsKey(categoryLabel)){
                                Map<String, Long> catMap = new HashMap<String, Long>();
                                products.put(categoryLabel, catMap);
                        }
                        products.get(categoryLabel).put(getProductTitle(item), entry.getKey());
                }
                sb.append(new JSONObject(products));
        }
        
        
        /**
         * Generate the javascript list of all the active phones and store in a file
         * @throws Exception
         */
        public void generateProductListJavascript() throws Exception {
                StringBuffer productsJavascript = new StringBuffer();
                
                productsJavascript.append("var productIdNames=");
                
                getProductsJavascript(productsJavascript);
                
                productsJavascript.append(";");
                
                // Write it to file
                String productXMLFilename = Utils.EXPORT_JAVASCRIPT_CONTENT_PATH + "saholicmobilephones.js";
                DBUtils.store(productsJavascript.toString(), productXMLFilename);
        }

    private void populateEntityIdItemMap(List<Item> items){
        entityIdItemMap = new HashMap<Long, List<Item>>(); 
        for(Item item: items){
            //TODO Can be removed as we are checking in calling function
            if(!(item.getItemStatus()==status.ACTIVE || item.getItemStatus() == status.PAUSED)){
                continue;
            }
            if( item.getSellingPrice() == 0){
                continue;
            }
            List<Item> itemList = entityIdItemMap.get(item.getCatalogItemId());
            if(itemList == null){
                itemList = new ArrayList<Item>();
            }
            itemList.add(item);
            entityIdItemMap.put(item.getCatalogItemId(), itemList);
        }
    }
    
    /**
     * Generate XML feed for mobile site
     * @throws Exception
     */
    public void generateXMLFeedForMobileSite() throws Exception {
        List<String> productXMLSnippets = new ArrayList<String>();
                productXMLSnippets.add("<Products>");
                List<Long> itemIds = new ArrayList<Long>();
                
                for(Long entityId: entityIdItemMap.keySet()){
                        List<Item> items = entityIdItemMap.get(entityId);
                        Item firstItem = items.get(0);
                        Utils.info("first Item: " + firstItem);
                        
                        if(isMobile(firstItem) || isLaptop(firstItem)) {
                                itemIds.add(firstItem.getId());
                        }
                }

                List<String> descriptions = new ArrayList<String>();
                descriptions.add("8MP camera, Super AMOLED Plus display, Android Gingerbread");
                descriptions.add("Android OS v2.2 Froyo, 800MHz processor, 3.5\" capacitive display");
                descriptions.add("Dual-SIM, Wi-Fi, Bluetooth, Social networking &amp; IM");
                descriptions.add("Android Gingerbread, Facebook button, 5MP camera");
                descriptions.add("Android Gingerbread, 1GHz processor, 3.7\" Gorilla Glass display");
                descriptions.add("2GB RAM, 500GB HDD, Intel Core 2 Duo T6570 processor, DOS");
                descriptions.add("4GB RAM, 500GB HDD, Intel Core i5 2410M processor, Windows 7 Basic");
                descriptions.add("3.2\" touchscreen, 2MP camera, IM &amp; social networking");
                
                for(Long entityId: entityIdItemMap.keySet()) {
                        List<Item> items = entityIdItemMap.get(entityId);
                        Item firstItem = items.get(0);
                        
                        if(!isMobile(firstItem) && !isLaptop(firstItem)){
                                continue;
                        }

                        String url = getProductURL(entityId, firstItem);
                        String imageUrl = "http://www.saholic.com/images/website" + File.separator + entityId + File.separator + "thumbnail.jpg";
                        String description = descriptions.get((int) (8 * Math.random()));
                        double minPrice = getMinPrice(items);
                        
                        String productType = "";
                        
                        if (firstItem.getCategory() == 10006)   {
                                productType = "Mobile Phone";
                        
                        } else if (firstItem.getCategory() == 10010)    {
                                productType = "Tablet";
                                
                        } else if (firstItem.getCategory() == 10050)    {
                                productType = "Laptop";
                        }
                        
                        productXMLSnippets.add(this.xmlIndentation[1] + "<Product>");   
                        
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ID>" + entityId + "</ID>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<Type>" + productType + "</Type>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<Brand>" + firstItem.getBrand() + "</Brand>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ModelName>" + firstItem.getModelName() + "</ModelName>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ModelNumber>" + firstItem.getModelNumber() + "</ModelNumber>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<URL>" + url + "</URL>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ImageURL>" + imageUrl + "</ImageURL>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ShortDesc>" + description + "</ShortDesc>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<MRP>" + firstItem.getMrp() + "</MRP>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<SellingPrice>" + (int)minPrice  + "</SellingPrice>");
                        
                        productXMLSnippets.add(this.xmlIndentation[1] + "</Product>");
                }
                
                productXMLSnippets.add("</Products>");
                
                String productDataXML = StringUtils.join(productXMLSnippets, "\n");
                
                Utils.info(productDataXML);
                
                // Write it to file
                String productXMLFilename = Utils.EXPORT_PARTNERS_CONTENT_PATH + "msitedata.xml";
                DBUtils.store(productDataXML, productXMLFilename);
    }

        /**
         * Generate the xml list of all the active phones and store in a file
         * @throws Exception
         */
        public void generateProductXMLForDisplayAds() throws Exception {
                Utils.info("Generating Product XML for display ads");
                List<String> productXMLSnippets = new ArrayList<String>();
                productXMLSnippets.add("<saholic.com>");
                List<Long> itemIds = new ArrayList<Long>();

                Utils.info("Entity Ids: " + entityIdItemMap.keySet());
                
                for(Long entityId: entityIdItemMap.keySet()){
                        List<Item> items = entityIdItemMap.get(entityId);
                        Item firstItem = items.get(0);
                        Utils.info("first Item: " + firstItem);
                        
                        if(isMobile(firstItem) || isLaptop(firstItem)) {
                                itemIds.add(firstItem.getId());
                        }
                }

                PromotionClient promotionClient = new PromotionClient();
                in.shop2020.model.v1.user.PromotionService.Client promotionServiceClient = promotionClient.getClient();
                
                List<ItemCouponDiscount> itemsCouponsAndDiscounts = promotionServiceClient.getItemDiscountMap(itemIds);
                
                Map<Long, ItemCouponDiscount> couponsAndDiscounts = new HashMap<Long, ItemCouponDiscount>();
                
                for (ItemCouponDiscount itemCouponDiscount: itemsCouponsAndDiscounts) {
                        couponsAndDiscounts.put(itemCouponDiscount.getItemId(), itemCouponDiscount);
                }
                Utils.info("Entity IDs: " + entityIdItemMap.keySet());
                
                for(Long entityId: entityIdItemMap.keySet()) {
                        List<Item> items = entityIdItemMap.get(entityId);
                        Item firstItem = items.get(0);
                        
                        Utils.info("First Item: " + firstItem);
                        
                        if(!isMobile(firstItem) && !isLaptop(firstItem)){
                                continue;
                        }
                        
                        productXMLSnippets.add(this.xmlIndentation[1] + "<products>");  
                        
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ProductSKU>" + entityId + "</ProductSKU>");
                        
                        String title = getProductTitle(firstItem);
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ProductName>" + title + "</ProductName>");

                        String url = getProductURL(entityId, firstItem);
                        
                        String imageUrl = "http://static" + ((entityId+1)%3) + ".saholic.com" + File.separator + "images" + File.separator + entityId + File.separator + "icon.jpg";    
                        
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ProductURL>" + url + "</ProductURL>");

                        productXMLSnippets.add(this.xmlIndentation[2] + "<ProductImageURL>" + imageUrl + "</ProductImageURL>");
                        
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ProductMRP>" + firstItem.getMrp() + "</ProductMRP>");
                        
                        double minPrice = getMinPrice(items);
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ProductSellingPrice>" + (int)minPrice  + "</ProductSellingPrice>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<Availability>" + (inStockCatalogItemIds.contains(entityId) ? "Y" : "N") + "</Availability>");
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ProductDiscount>" + (int)((firstItem.getMrp()-minPrice)/firstItem.getMrp()*100) + "</ProductDiscount>");
                        
                        long itemId = firstItem.getId();
                        
                        if(couponsAndDiscounts.containsKey(itemId))     {
                                
                                ItemCouponDiscount itemCouponDiscount = couponsAndDiscounts.get(itemId);

                                productXMLSnippets.add(this.xmlIndentation[2] + "<ProductCoupons>");
                                productXMLSnippets.add(this.xmlIndentation[3] + "<Coupon>");
                                productXMLSnippets.add(this.xmlIndentation[4] + "<CouponCode>" + itemCouponDiscount.getCouponCode() + "</CouponCode>");
                                productXMLSnippets.add(this.xmlIndentation[4] + "<PriceAfterCoupon>" + (int)(minPrice - itemCouponDiscount.getDiscount()) + "</PriceAfterCoupon>");
                                productXMLSnippets.add(this.xmlIndentation[3] + "</Coupon>");
                                productXMLSnippets.add(this.xmlIndentation[2] + "</ProductCoupons>");
                                
                        } else  {
                                productXMLSnippets.add(this.xmlIndentation[2] + "<ProductCoupons />");
                        }
                        
                        String description = "";
                        Entity entity = CreationUtils.getEntity(entityId);
                        if(entity!=null){
                                if(entity.getSlide(130001) !=null){
                                        description = StringEscapeUtils.escapeXml(entity.getSlide(130001).getFreeformContent().getFreeformText());
                                }
                        }
                        
                        productXMLSnippets.add(this.xmlIndentation[2] + "<ProductDescription>" + description + "</ProductDescription>");
                        
                        productXMLSnippets.add(this.xmlIndentation[1] + "</products>"); 
                }
                
                productXMLSnippets.add("</saholic.com>");
                
                String productDataXML = StringUtils.join(productXMLSnippets, "\n");
                
                Utils.info(productDataXML);
                
                // Write it to file
                String productXMLFilename = Utils.EXPORT_PARTNERS_CONTENT_PATH + "advertismentapi.xml";
                DBUtils.store(productDataXML, productXMLFilename);
        }
        
        public static void main(String[] args) {
                        try {
                        CatalogClient cl = new CatalogClient();
                        in.shop2020.model.v1.catalog.CatalogService.Client client = cl.getClient();
                        List<Item> items = client.getAllItemsByStatus(status.ACTIVE);
                        items.addAll(client.getAllItemsByStatus(status.PAUSED));
                        ProductListGenerator generator = new ProductListGenerator(items);
                
                log.info("Before thinkdigit feed.");
                generator.generateThinkDigitFeed();

                
                log.info("Before product list xml.");
                generator.generateProductsListXML();
                
                log.info("Before product accessories xml.");
                generator.generateAccessoriesXML();
                
                log.info("Before product camera xml.");
                generator.generateCamerasXML();
                
                log.info("Before product display ads.");
                        } catch (Exception ex){
                                String logfile = "/tmp/content-from-cms.log";
                                 GmailUtils gm = new GmailUtils();
                                String[] sendTo = { "anikendra.das@shop2020.in", "amit.gupta@shop2020.in" };

                                try {
                                    gm.sendSSLMessage(sendTo, "Partners feed generation failed", ""
                                            + Calendar.getInstance().getTime().toString(),
                                            "build@shop2020.in", "cafe@nes", logfile);
                                } catch (MessagingException e) {
                                    log.error("Could not send status mail", e);
                                }
                        }
                //generator.generateProductXMLForDisplayAds();
        }
        
    private String readFile(String path) throws IOException {
                FileInputStream stream = new FileInputStream(new File(path));
                try {
                        FileChannel fc = stream.getChannel();
                        MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()-1);
                        /* Instead of using default, pass in a decoder. */
                        return Charset.defaultCharset().decode(bb).toString();
                }
                finally {
                        stream.close();
                }
        }
    /**
     * Feed generated for thinkdigit that only contains the live items
     * feed should have s
     */
    public void generateThinkDigitFeed() throws Exception{
        
        List<Long> riskyPausedItems = this.getRiskyPausedItems();
        List<String> productXMLSnippets = new ArrayList<String>();
        productXMLSnippets.add("<root>");
        String thinkDigitFeedFileName = Utils.EXPORT_PARTNERS_CONTENT_PATH + "all-categories.xml";
        for (Long entityId : entityIdItemMap.keySet()){
                List<Item> items = entityIdItemMap.get(entityId);
                long cate = items.get(0).getCategory();
                
                Utils.info(items.get(0).getId() + ","  + String.valueOf(cate));
                Category category = Catalog.getInstance().getDefinitionsContainer().getCategory(cate);
                Category parentCategory = category.getParentCategory(); 
            for(Item item: items){
                if(item.getItemStatus().equals(status.ACTIVE)) {
                        if(!(item.isRisky() && riskyPausedItems.contains(item.getId()) )){
                                inStockCatalogItemIds.add(entityId);
                                if(validParentCategories.contains(parentCategory.getID())) { 
                                        productXMLSnippets.add(this.xmlIndentation[1] + "<products>");
                                        productXMLSnippets.add(this.xmlIndentation[2] + "<id>" + item.getCatalogItemId() + "</id>");
                                        productXMLSnippets.add(this.xmlIndentation[2] + "<product>" + getProductTitle(item) + "</product>");
                                        productXMLSnippets.add(this.xmlIndentation[2] + "<Product_URL>" + getProductURL(item.getCatalogItemId(), item, 59) + "</Product_URL>");
                                        productXMLSnippets.add(this.xmlIndentation[2] + "<Product_Price>" + (int)item.getSellingPrice() + "</Product_Price>");
                                        productXMLSnippets.add(this.xmlIndentation[2] + "<Merchant_Name>" + "saholic.com" + "</Merchant_Name>");
                                        productXMLSnippets.add(this.xmlIndentation[2] + "<Category_Name>" + parentCategory.getLabel() + "</Category_Name>");
                                        productXMLSnippets.add(this.xmlIndentation[1] + "</products>");
                                }
                                break;
                        }
                }
            }
        }
        productXMLSnippets.add("</root>");
        String productDataXML = StringUtils.join(productXMLSnippets, "\n");
        DBUtils.store(productDataXML, thinkDigitFeedFileName);

    }
    
    public static void updatePriceForEntity(long catalogItemId, double sp, double mrp){
        try{
                String filename = Utils.EXPORT_PARTNERS_CONTENT_PATH + "saholicmobilephones.xml";
                File file = new File(filename);
                if (file.exists()){
                        DOMParser parser = new DOMParser();
                        parser.parse(filename);
                        Document doc = parser.getDocument();
                        NodeList list = doc.getElementsByTagName("ProductSKU");
                        for(int i=0; i<list.getLength(); i++){
                                if(list.item(i).getTextContent().equals(catalogItemId+"")){
                                        Node spNode = doc.getElementsByTagName("ProductPrice").item(i);
                                        spNode.setTextContent(sp+"");
                                        Node mrpNode = doc.getElementsByTagName("ProductMRP").item(i);
                                        mrpNode.setTextContent(mrp+"");
                                }
                        }
                        writeXmlFile(doc, filename);
                }
                else{
                        System.out.println("File not found!");
                }
        }
        catch (Exception e){
                e.getMessage();
        }
    }
    
    // This method writes a DOM document to a file
    public static void writeXmlFile(Document doc, String filename) {
        try {
                // Prepare the DOM document for writing
                Source source = new DOMSource(doc);

                // Prepare the output file
                File file = new File(filename);
                Result result = new StreamResult(file);

                // Write the DOM document to the file
                Transformer xformer = TransformerFactory.newInstance().newTransformer();
                xformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
        } catch (TransformerException e) {
        }
    }
    
    private List<Long> getRiskyPausedItems() {
                try {
                        Reader reader = new FileReader(Utils.EXPORT_PATH + Utils.RISKY_PAUSED_JSON);
                        return new Gson().fromJson(reader, new TypeToken<List<Long>>() {}.getType());
                } catch (FileNotFoundException e) {
                        log.error("Could not read paused file");
                        e.printStackTrace();
                        return new ArrayList<Long>();
                }
        }
}