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