package com.jbidwatcher.auction;
/*
* Copyright (c) 2000-2007, CyberFOX Software, Inc. All Rights Reserved.
*
* Developed by mrs (Morgan Schweers)
*/
/*
* @brief Generic auction information, generally information that
* needed to be retrieved.
*
* Program-specific information (next update time, what auction
* server, etc.) is stored in AuctionEntry
*/
import com.jbidwatcher.util.Currency;
import com.jbidwatcher.util.config.*;
import com.jbidwatcher.util.*;
import com.jbidwatcher.util.db.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class AuctionInfo extends AuctionCore {
private String potentialThumbnail = null;
protected Seller mSeller;
protected GZip mLoadedPage = null;
/**
* @brief Empty constructor, for ActiveRecord.
*
*/
public AuctionInfo() { }
static AuctionInfo findByIdOrIdentifier(String id, String identifier) {
AuctionInfo ai = null;
if(id != null) {
ai = find(id);
}
if (ai == null && identifier != null) {
ai = findByIdentifier(identifier);
}
return ai;
}
public void setThumbnail(String thumbPath) {
if(thumbPath == null) setNoThumbnail(true);
mThumbnailPath = thumbPath;
}
public void save() {
String outPath = JConfig.queryConfiguration("auctions.savepath");
if (outPath != null && outPath.length() != 0) {
if (JConfig.queryConfiguration("store.auctionHTML", "true").equals("true")) {
String filePath = outPath + System.getProperty("file.separator") + getIdentifier() + ".html.gz";
if (mLoadedPage != null) {
mLoadedPage.save(filePath);
}
}
}
mLoadedPage = null;
}
private GZip loadFile(File fp) {
GZip localZip = new GZip();
if(fp.exists()) {
// Okay, I don't allow loading auction data that's over 512K. Duh.
if(fp.length() < 512 * 1024) {
try {
JConfig.log().logDebug("Loading from backing page (file is " + fp.length() + " bytes)!");
localZip.load(fp);
} catch(IOException ioe) {
JConfig.log().handleException("Couldn't read " + fp.getName(), ioe);
return null;
}
return localZip;
} else {
JConfig.log().logDebug("Can't load " + fp.getName() + ", file is too large.");
}
}
return null;
}
void setRealContent(StringBuffer changedContent, boolean final_data) {
if(changedContent != null) {
byte[] localBytes = changedContent.toString().getBytes();
setRealContent(localBytes, final_data);
}
}
void setRealContent(byte[] changedContent, boolean final_data) {
String outPath = JConfig.queryConfiguration("auctions.savepath");
if(changedContent != null) {
mLoadedPage = new GZip();
mLoadedPage.setData(changedContent);
if(outPath != null && outPath.length() != 0) {
if(final_data) {
String filePath = outPath + System.getProperty("file.separator") + getIdentifier() + ".html.gz";
mLoadedPage.save(filePath);
mLoadedPage = null;
}
}
}
}
GZip getRealContent() {
File fp = JConfig.getContentFile(getIdentifier());
if(fp != null) return loadFile(fp);
return mLoadedPage;
}
public void setContent(StringBuffer inContent, boolean final_data) {
setRealContent(inContent, final_data);
}
protected StringBuffer getContent() {
StringBuffer sb;
if(mLoadedPage != null) {
StringBuffer outSB = mLoadedPage.getUncompressedData(false);
if(outSB == null) outSB = new StringBuffer("mLoadedPage.getUncompressedData is null");
sb = outSB;
} else {
JConfig.log().logDebug("mLoadedPage is null, returning the 'real' cached copy!");
GZip gz = getRealContent();
if(gz != null) {
sb = gz.getUncompressedData();
JConfig.log().logDebug("Turned the uncompressed data into a StringBuffer!");
if(sb == null) JConfig.log().logDebug(" Failed to uncompress for id " + getIdentifier());
} else {
sb = new StringBuffer("Error getting real content.");
}
}
return(sb);
}
public String getSellerName() {
refreshSeller();
return mSeller != null ? (mSeller.getSeller()) : "(unknown)";
}
private void refreshSeller() {
if (mSeller == null) {
String seller_id = get("seller_id");
if (seller_id != null) mSeller = Seller.findFirstBy("id", seller_id);
}
}
public Seller getSeller() {
refreshSeller();
return mSeller;
}
public String getPositiveFeedbackPercentage() {
refreshSeller();
if (mSeller != null) return mSeller.getPositivePercentage();
return "n/a";
}
public int getFeedbackScore() {
refreshSeller();
if (mSeller != null) return mSeller.getFeedback();
return 0;
}
protected void setSellerName(String sellerName) {
if(sellerName == null || sellerName.length() == 0) return;
if(mSeller == null) {
mSeller = Seller.makeSeller(sellerName.trim());
} else {
mSeller = mSeller.makeSeller(sellerName, mSeller);
}
Integer seller_id = mSeller.getId();
if(seller_id == null || seller_id == 0) {
String raw_id = mSeller.saveDB();
if (raw_id != null && raw_id.length() != 0) seller_id = Integer.parseInt(raw_id);
}
setInteger("seller_id", seller_id);
}
public void setIdentifier(String id) { setString("identifier", id); }
public void setHighBidder(String highBidder) { setString("highBidder", highBidder); }
protected void setTitle(String title) { setString("title", title); }
// protected void setHighBidderEmail(String highBidderEmail) { setString("highBidderEmail", highBidderEmail); }
protected void setItemLocation(String itemLocation) { setString("itemLocation", itemLocation); }
protected void setInsuranceOptional(boolean insuranceOptional) { setBoolean("insuranceOptional", insuranceOptional); }
protected void setFixedPrice(boolean fixedPrice) { setBoolean("fixedPrice", fixedPrice); }
protected void setNoThumbnail(boolean noThumbnail) { setBoolean("noThumbnail", noThumbnail); }
protected void setCurBid(Currency curBid) { setMonetary("curBid", curBid); }
protected void setMinBid(Currency minBid) { setMonetary("minBid", minBid); }
protected void setShipping(Currency shipping) { setMonetary("shipping", shipping); }
protected void setInsurance(Currency insurance) { setMonetary("insurance", insurance); }
protected void setUSCur(Currency USCur) { setMonetary("us_cur", USCur, false); }
protected void setBuyNowUS(Currency buyNowUS) { setMonetary("buy_now_us", buyNowUS, false); }
protected void setBuyNow(Currency buyNow) { setMonetary("buy_now", buyNow); }
protected void setEnd(Date end) {
if(end == null || end.equals(Constants.FAR_FUTURE)) {
end = null;
}
setDate("end", end);
}
public void setNumBids(int numBids) { setInteger("numBids", numBids); }
public void setPrivate(boolean isPrivate) { setBoolean("private", isPrivate); }
protected void setPaypal(boolean paypal) { setBoolean("paypal", paypal); }
protected void setEnded(boolean ended) { setBoolean("ended", ended); }
public void setThumbnailURL(String url) {
setNoThumbnail(false);
potentialThumbnail = url;
}
public String getThumbnailURL() {
if (potentialThumbnail != null) return potentialThumbnail;
return getThumbnailById(getIdentifier());
}
public String getAlternateSiteThumbnail() {
return getThumbnailById(getIdentifier() + "6464");
}
private static String getThumbnailById(String id) {
return "http://thumbs.ebaystatic.com/pict/" + id + ".jpg";
}
private static Table sDB = null;
protected static String getTableName() { return "auctions"; }
protected Table getDatabase() { return getRealDatabase(); }
private static Table getRealDatabase() {
if (sDB == null) {
sDB = openDB(getTableName());
}
return sDB;
}
public String saveDB() {
// Look for columns of type: {foo}_id
// For each of those, introspect for 'm{Foo}'.
// For each non-null of those, call 'saveDB' on it.
// Store the result of that call as '{foo}_id'.
if(mSeller != null) {
String seller_id = mSeller.saveDB();
if(seller_id != null) set("seller_id", seller_id);
}
return super.saveDB();
}
public static AuctionInfo find(String id) {
return findFirstBy("id", id);
}
public static AuctionInfo findFirstBy(String key, String value) {
return (AuctionInfo) ActiveRecord.findFirstBy(AuctionInfo.class, key, value);
}
public static AuctionInfo findByIdentifier(String identifier) {
return (AuctionInfo) ActiveRecord.findFirstBySQL(AuctionInfo.class, "SELECT * FROM auctions WHERE id IN (SELECT Max(id) FROM auctions WHERE identifier = '" + identifier + "')");
}
public static int count() {
return ActiveRecord.count(AuctionInfo.class);
}
public static int uniqueCount() {
return getRealDatabase().countBySQL("SELECT COUNT(DISTINCT(identifier)) FROM auctions WHERE identifier IS NOT NULL");
}
public static boolean deleteAll(List<Integer> toDelete) {
if(toDelete.isEmpty()) return true;
// TODO - Replace with Guava?
String auctions = buildCSL(toDelete);
return getRealDatabase().deleteBy("id IN (" + auctions + ")");
}
public static List<AuctionInfo> findAllByIds(List<? extends Object> toFind) {
if(toFind.isEmpty()) return new ArrayList<AuctionInfo>(0);
String auctions = buildCSL(toFind);
return (List<AuctionInfo>) ActiveRecord.findAllBySQL(AuctionInfo.class, "SELECT * FROM auctions WHERE id IN (" + auctions + ")");
}
private static String buildCSL(List<? extends Object> toDelete) {
StringBuilder ids = new StringBuilder("");
boolean first = true;
for (Object id : toDelete) {
if (!first) {
ids.append(", ");
}
ids.append(id);
first = false;
}
return ids.toString();
}
@SuppressWarnings({"unchecked"})
public static List<AuctionInfo> findLostAuctions() {
List<AuctionInfo> resultSet;
try {
resultSet = (List<AuctionInfo>) findAllBySQL(AuctionInfo.class, "SELECT * FROM auctions WHERE identifier NOT IN (SELECT DISTINCT(identifier) FROM entries)");
} catch(Exception e) {
JConfig.log().handleDebugException("Failed to find lost auctions.", e);
resultSet = null;
}
return resultSet;
}
}