package com.disruptiontheory.eggfetcher; import java.util.ArrayList; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; public class EggFetcher { //the number of products returned this query int returnedProductCount = 0; public void GetProductsByBrand(int brandId) { //the current page we're on int pageNum = 1; //the number of products per page int pageSize = 0; //the number of products that there are for this query //this was only used for output / debug purposes, so I've since commented it out. But it can be restored for use as needed //int totalProductCount = 0; //the result of the query, in string format String queryResult = ""; //the products returned in this query ArrayList<NeweggProduct> returnedProducts = new ArrayList<NeweggProduct>(); //query newegg for the first set of information, passing only the brand we want //(page number should just be "1" or default at this point) queryResult = EggFetcher.QueryNewegg(QueryData.SlimData(brandId, pageNum)); //we need to get the paginationInfo from the result, and then the number of items per page from that String paginationInfo = (String) JSONhandler.getJSONValue(queryResult, "PaginationInfo"); pageSize = Integer.parseInt(JSONhandler.getJSONValue(paginationInfo, "PageSize").toString()); //totalProductCount = Integer.parseInt(JSONhandler.getJSONValue(paginationInfo, "TotalCount").toString()); //System.out.println("Brand " + brandId + " has " + totalProductCount + " products, showing " + pageSize + " products per page."); //the NavigationContentList holds a NavigationItemList, which we need in order to get the categories String navigateContentList = JSONhandler.getJSONValue(queryResult, "NavigationContentList"); //But if it returns empty, or null, then this query is likely unsupported, and we're not going to get any information, so we have to return empty-handed if(navigateContentList.equalsIgnoreCase("")) { return; } //get the categories that this brand has products in //ArrayList<Integer> brandCats = GetBrandCats(JSONhandler.getJSONValue(navigateContentList, "NavigationItemList")); ArrayList<Brand> brandCats = GetBrandCats(JSONhandler.getJSONValue(navigateContentList, "NavigationItemList")); //loop through each of those categories, get the products in it, and then add those products to the list of returned products for this query for(Brand brand : brandCats) { returnedProducts.addAll(GetProductsFromCategory(brand, pageSize, brandId)); } //System.out.println("==========================PRODUCT LIST=========================="); try { //prep a mysql string for execution //it would be better to pass cleaner data to the databasehandler, which may get done in a future update //when doing so, should also change to INSERT / UPDATE, rather than ignoring existing entries String outputString = "INSERT IGNORE INTO `NeweggProducts` (`NeweggItemNumber`, `brand`, `model`, `reviewcount`, `averagerating`) VALUES "; //loop through each product and format it to a VALUE entry for the list, according to a defined function for(NeweggProduct product : returnedProducts) { outputString += product.toMySQLInsert() + ","; } //remove the trailing delimiter outputString = outputString.substring(0, outputString.length() - 1); //call the function to insert this data to the database if(DatabaseHandler.InsertNeweggProducts(outputString) == true) { //if the product insert went off without erroring, //take the finished list of products and compute the average brand rating from it DatabaseHandler.CompileBrandRating(brandId); } } catch (Exception e) { e.printStackTrace(); } } //get all of the products in a given category (by category id) //pass the brand ID in so that the prouducts don't have to do extra queries when attaching that information to themselves public ArrayList<NeweggProduct> GetProductsFromCategory(Brand brand, int pageSize, int brandId) { //the id of the category we're working with int catId = brand.id; //the number of products in the current category int productCount = brand.ItemCount; //the number of products that we have queried, in total, during this query returnedProductCount = 0; //the products returned in this query ArrayList<NeweggProduct> returnedProducts = new ArrayList<NeweggProduct>(); //the current page number of this query int pageNum = 1; //the JSON-formatted string we get back from Newegg String queryResult; //while there are still products to be queried in this category while(returnedProductCount < productCount) { //get the products on this page in this category from newegg queryResult = EggFetcher.QueryNewegg(QueryData.SlimData(brandId, pageNum, catId)); //get just the products from the results of the query String results = JSONhandler.getJSONValue(queryResult, "ProductListItems"); //if there is no productlistitems, or the json query doesn't work for any other reason, close out of this gracefully if(results == "") { break; } //extract the products from the result data //the returnedProductCount will be incremented by however many products this returns: ArrayList<NeweggProduct> queryProducts = GetProducts(brandId, results); //add the resulting products to the list of products to return returnedProducts.addAll(queryProducts); //incremement the number of the page to be queried pageNum++; } return returnedProducts; } public ArrayList<NeweggProduct> GetProducts(int brandId, String productsJSON) { int reviewCount = 0; int productRating = 0; String itemNumber = ""; String productModel = ""; ArrayList<NeweggProduct> resultProducts = new ArrayList<NeweggProduct>(); JSONArray jarr = (JSONArray) JSONValue.parse(productsJSON); for (Object productEntry : jarr) { returnedProductCount++; JSONObject product = (JSONObject) productEntry; JSONObject productReviews = (JSONObject) JSONValue.parse(product.get("ReviewSummary").toString()); String revCnt = productReviews.get("TotalReviews").toString().replace("[", "").replace("]", "").replace(",", ""); if (revCnt.equalsIgnoreCase("") == false) { reviewCount = Integer.parseInt(revCnt); if(reviewCount <= 0) { continue; } productRating = Integer.parseInt(productReviews.get("Rating").toString()); itemNumber = product.get("NeweggItemNumber").toString(); productModel = product.get("Model").toString(); resultProducts.add(new NeweggProduct(itemNumber, productModel, brandId, reviewCount, productRating)); } } //System.out.println("Sending back " + resultProducts.size() + " products."); return resultProducts; } public static ArrayList<Brand> GetBrandCats(String navigationItemList) { ArrayList<Brand> resultList = new ArrayList<Brand>(); //NavigationItemList array contains "ItemCount" and "CategoryId" and "SubCategoryId" for what need to be searched for each brand... JSONArray navItems = (JSONArray) JSONValue.parse(navigationItemList); for(Object navEntry : navItems) { JSONObject navItem = (JSONObject) navEntry; int catId = Integer.parseInt(navItem.get("CategoryId").toString()); int itemCount = Integer.parseInt(navItem.get("ItemCount").toString()); resultList.add(new Brand(catId, itemCount)); } return resultList; } public static String QueryNewegg(String queryData) { return WebClient.QueryAndGetJSON("http://www.ows.newegg.com/Search.egg/Advanced", queryData); } public static String GetBrandName(int brandId) { //get an item number from the database by doing //"SELECT NeweggItemNumber FROM NeweggProducts WHERE brand = " + brandId + " LIMIT 1" //do a (get?) query against //http://www.ows.newegg.com/Products.egg/{ItemNumber}/Specification //using the grabbed item number return "Unknown Name"; } }