/*
* [SkuStore.java]
*
* Summary: Probe sku numbers of non-Amazon estores. Not to probe stock, but to find numbers.
*
* Copyright: (c) 2016-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
*
* Licence: This software may be copied and used freely for any purpose but military.
* http://mindprod.com/contact/nonmil.html
*
* Requires: JDK 1.8+
*
* Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
*
* Version History:
* 1.0 2016-01-25 initial version
*/
package com.mindprod.stores;
import com.mindprod.fastcat.FastCat;
import com.mindprod.http.Get;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static java.lang.System.*;
/**
* Probe sku numbers of non-Amazon estores. Not to probe stock, but to find numbers.
*
* Cloned from EStore
*
* @author Roedy Green, Canadian Mind Products
* @version 1.0 2016-01-25 initial version
* @see ProbeForSkus
* @since 2016-01-25
*/
public enum SkuStore
{
BESTBUYCA( "www.bestbuy.ca", "sku=([A-Z0-9]{8})\"", "Sorry, we couldn’t find any results" )
{
public String buildQueryLink( final String description )
{
return buildBestBuyCaQueryLink( description );
}
},
BESTBUY( "www.bestbuy.com", "skuId=([A-Z0-9]{7,10})\"", "Oops!
We couldn't find anything matching your search" )
{
public String buildQueryLink( final String description )
{
return buildBestBuyComQueryLink( description );
}
},
CANADACOMPUTERS( "www.canadacomputers.com", "Item Code: ([A-Z0-9]{6,6}) ", "We have found 0 active items that match" )
{
public String buildQueryLink( final String description )
{
return buildCanadaComputersQueryLink( description );
}
},
NCIXCA( "www.ncix.com", "additem=([A-Z0-9]{4,12})&", "No Search Results Found" )
{
public String buildQueryLink( final String description )
{
return buildNCIXQueryLink( description );
}
},
NCIXUS( "www.ncixus.com", "sku=([A-Z0-9]{4,9})&", "No Search Results Found" )
{
public String buildQueryLink( final String description )
{
return buildNCIXQueryLink( description );
}
},
NEWEGGCA( "www.newegg.ca", "
Item #: ([A-Z0-9\\- ]{14,18})", " We have found 0 items that match \"" )
{
public String buildQueryLink( final String neweggca )
{
return buildNeweggQueryLink( neweggca );
}
},
NEWEGG( "www.newegg.com", "Item #: ([A-Z0-9\\- ]{14,18})", "we have found 0 active items that match \"" )
{
public String buildQueryLink( final String description )
{
return buildNeweggQueryLink( description );
}
},
TIGERCA( "www.tigerdirect.ca", "EdpNo=([A-Z0-9]{5,13})&", ">0 Results found for "|returned no results" )
{
public String buildQueryLink( final String description )
{
return buildTigerQueryLink( description );
}
},
TIGER( "www.tigerdirect.com", "EdpNo=([A-Z0-9]{5,13})&", ">0 Results found for "|returned no results" )
{
public String buildQueryLink( final String description )
{
return buildTigerQueryLink( description );
}
};
/**
* how long to wait for site to connect in millis. Same for all bookstores. Interprobe time is configurable though.
*/
private static final int CONNECT_TIMEOUT = ( int ) TimeUnit.SECONDS.toMillis( 45 );
/**
* how long to wait for site to respond in millis while reading. Same for all bookstores.
*/
private static final int READ_TIMEOUT = ( int ) TimeUnit.SECONDS.toMillis( 30 );
/**
* domain to go to with http://
*/
private final String website;
/**
* Regex pattern to find the SKU
*/
private final Pattern skuFindingPattern;
/**
* Regex pattern indicating search failure
*/
private final Pattern failPattern;
/**
* constructor
*
* @param website URL of website we link to
* @param skuFindingPattern Regex to find the sku
* @param pattern that indicates search failed.
*/
SkuStore( final String website, final String skuFindingPattern, final String failPattern )
{
this.website = website;
this.skuFindingPattern = Pattern.compile( skuFindingPattern );
this.failPattern = Pattern.compile( failPattern );
}
/**
* link to BestBuy.ca query
*
* @param description, description of the product
*
* @return URLString to link to that product
*/
String buildBestBuyCaQueryLink( final String description )
{
final FastCat sb = new FastCat( 4 );
sb.append( "http://", getHost() );
sb.append( "/Search/SearchResults.aspx?query=" );
try
{
sb.append( URLEncoder.encode( description, "UTF-8" ) );
}
catch ( UnsupportedEncodingException e )
{
err.println( "UTF-8 not supported" );
System.exit( 2 );
}
return sb.toString();
}// /method
/**
* link to BestBuy.com query
*
* @param description, description of the product
*
* @return URLString to link to that product
*/
String buildBestBuyComQueryLink( final String description )
{
final FastCat sb = new FastCat( 20 );
sb.append( "http://", getHost() );
sb.append( "/site/searchpage.jsp" );
sb.append( "?_dyncharset=UTF-8" );
sb.append( "&_dynSessConf=" );
sb.append( "&id=pcat17071" );
sb.append( "&type=page" );
sb.append( "&sc=Global" );
sb.append( "&cp=1" );
sb.append( "&nrp=15" );
sb.append( "&sp=" );
sb.append( "&qp=" );
sb.append( "&list=n" );
sb.append( "&iht=y" );
sb.append( "&usc=All+Categories" );
sb.append( "&ks=960" );
sb.append( "&fs=saas" );
sb.append( "&keys=keys" );
sb.append( "&st=" );
try
{
sb.append( URLEncoder.encode( description, "UTF-8" ) );
}
catch ( UnsupportedEncodingException e )
{
err.println( "UTF-8 not supported" );
System.exit( 2 );
}
return sb.toString();
}// /method
/**
* build an general product areas link to CanadaComputers product
*
* @param description description of product area
*
* @return link starting with http:
*/
String buildCanadaComputersQueryLink( final String description )
{
// take user to page http://www.canadacomputers.com/advanced_search_result.php?keywords=ssd
final FastCat sb = new FastCat( 4 );
sb.append( "http://", getHost() );
sb.append( "/advanced_search_result.php?keywords=" );
try
{
sb.append( URLEncoder.encode( description, "UTF-8" ) );
}
catch ( UnsupportedEncodingException e )
{
err.println( "UTF-8 not supported" );
System.exit( 2 );
}
return sb.toString();
}// /method
/**
* build a general query for NCIX
*
* @param description description of product
*
* @return http:// search query link
*/
String buildNCIXQueryLink( final String description )
{
// http://search.ncix.com/search/q=xxx&qcatid=0
final FastCat sb = new FastCat( 5 );
sb.append( "http://", this.getHost() );
sb.append( "/search/?q=" );
try
{
sb.append( URLEncoder.encode( description, "UTF-8" ) );
}
catch ( UnsupportedEncodingException e )
{
err.println( "UTF-8 not supported" );
System.exit( 2 );
}
sb.append( "&qcatid=0" );
return sb.toString();
}// /method
/**
* build an general product areas link to newegg product
*
* @param description description of product area
*
* @return link starting with http:
*/
String buildNeweggQueryLink( final String description )
{
// http://www.newegg.ca/Product/ProductList.aspx?Submit=ENE&DEPA=0&Order=BESTMATCH&Description=Intel+320+Series+80+GB+SATA-2+3+Gb%2Fs
final FastCat sb = new FastCat( 4 );
sb.append( "http://", getHost() );
sb.append( "/Product/ProductList.aspx?Submit=ENE&DEPA=0&Order=BESTMATCH&Description=" );
try
{
sb.append( URLEncoder.encode( description, "UTF-8" ) );
}
catch ( UnsupportedEncodingException e )
{
err.println( "UTF-8 not supported" );
System.exit( 2 );
}
return sb.toString();
}// /method
/**
* build URL to probe for this product by description in this eestore
*
* @param description English description of product
*
* @return URL string to probe this product
*/
abstract String buildQueryLink( final String description );
/**
* build an general link to tiger/tigerca product area
*
* @param description description of product area.
*
* @return link starting with http:
*/
String buildTigerQueryLink( final String description )
{
// http://www.tigerdirect.com/applications/SearchTools/search.asp?
// keywords=xxx
final FastCat sb = new FastCat( 4 );
sb.append( "http://", getHost() );
sb.append( "/applications/SearchTools/search.asp?keywords=" );
try
{
sb.append( URLEncoder.encode( description, "UTF-8" ) );
}
catch ( UnsupportedEncodingException e )
{
err.println( "UTF-8 not supported" );
System.exit( 2 );
}
return sb.toString();
}// /method
private String getHost()
{
return website;
}// /method
/**
* probe this estore and get the value of the sku for this product
*
* @param description English description of product
*
* @return value of the ske for this product, this store. Null if none.
*/
String probeForSku( final String description )
{
try
{
final String probeUrl = buildQueryLink( description );
final Get get = new Get();
get.setConnectTimeout( CONNECT_TIMEOUT );
get.setReadTimeout( READ_TIMEOUT );
get.setInstanceFollowRedirects( true );
final String big = get.send( new URL( probeUrl ), Get.UTF8 );
final int responseCode = get.getResponseCode();
if ( responseCode != 200 )
{
return null;
}
final Matcher m = skuFindingPattern.matcher( big );
final Matcher mfail = failPattern.matcher( big );
if ( m.find() & m.groupCount() >= 1 && !mfail.find() )
{
return m.group( 1 );
}
else
{
return null;
}
}
catch ( IOException e )
{
return null;
}
}
}