First set of changes towards a massive refactoring of the AuctionServer class, to be more specific, more testable, and more sane.
- A jbidwatcher/trunk/src/com/jbidwatcher/auction/server/AuctionServerInterface.java
- M jbidwatcher/trunk/src/com/jbidwatcher/auction/AuctionActionImpl.java view
- M jbidwatcher/trunk/src/com/jbidwatcher/auction/AuctionBuy.java view
- M jbidwatcher/trunk/src/com/jbidwatcher/auction/AuctionsManager.java view
- M jbidwatcher/trunk/src/com/jbidwatcher/auction/Snipe.java view
- M jbidwatcher/trunk/src/com/jbidwatcher/auction/server/AuctionServer.java view
- M jbidwatcher/trunk/src/com/jbidwatcher/auction/server/AuctionServerManager.java view
- M jbidwatcher/trunk/src/com/jbidwatcher/auction/server/ebay/ebayServer.java view
- M jbidwatcher/trunk/src/com/jbidwatcher/webserver/JBidProxy.java view
- M jbidwatcher/trunk/test/com/jbidwatcher/auction/MockAuctionServer.java view
| 24 | 48 | |
|---|---|---|
| 9 | 9 | import com.jbidwatcher.util.Currency; |
| 10 | 10 | import com.jbidwatcher.FilterManager; |
| 11 | 11 | import com.jbidwatcher.auction.server.AuctionServer; |
| 12 | import com.jbidwatcher.auction.server.AuctionServerInterface; | |
| 12 | 13 | |
| 13 | 14 | /** |
| 14 | 15 | * Created by IntelliJ IDEA. |
| --- | --- | |
| 59 | 60 | public Currency getAmount() { return m_amount; } |
| 60 | 61 | public int getQuantity() { return m_quant; } |
| 61 | 62 | public boolean isSuccessful() { |
| 62 | return (m_result == AuctionServer.BID_WINNING || | |
| 63 | m_result == AuctionServer.BID_DUTCH_CONFIRMED || | |
| 64 | m_result == AuctionServer.BID_SELFWIN); | |
| 63 | return (m_result == AuctionServerInterface.BID_WINNING || | |
| 64 | m_result == AuctionServerInterface.BID_DUTCH_CONFIRMED || | |
| 65 | m_result == AuctionServerInterface.BID_SELFWIN); | |
| 65 | 66 | } |
| 66 | 67 | |
| 67 | 68 | public String getBidResult(Currency bidAmount, int bidResult) { |
| 68 | 69 | String bidResultString; |
| 69 | 70 | |
| 70 | 71 | switch (bidResult) { |
| 71 | case AuctionServer.BID_ERROR_UNKNOWN: | |
| 72 | case AuctionServerInterface.BID_ERROR_UNKNOWN: | |
| 72 | 73 | bidResultString = "Bidding " + bidAmount + " apparently failed for an unknown reason. Check the auction in the browser, to see if the bid went through anyway."; |
| 73 | 74 | break; |
| 74 | case AuctionServer.BID_ERROR_ENDED: | |
| 75 | case AuctionServer.BID_ERROR_CANNOT: | |
| 75 | case AuctionServerInterface.BID_ERROR_ENDED: | |
| 76 | case AuctionServerInterface.BID_ERROR_CANNOT: | |
| 76 | 77 | bidResultString = "Bidding apparently failed, as the auction cannot be bid on anymore (probably ended)!"; |
| 77 | 78 | break; |
| 78 | case AuctionServer.BID_DUTCH_CONFIRMED: | |
| 79 | case AuctionServerInterface.BID_DUTCH_CONFIRMED: | |
| 79 | 80 | bidResultString = "Your dutch bid was confirmed, and you are in the list of high bidders!"; |
| 80 | 81 | break; |
| 81 | case AuctionServer.BID_ERROR_BANNED: | |
| 82 | case AuctionServerInterface.BID_ERROR_BANNED: | |
| 82 | 83 | bidResultString = "Your bid failed, as you are disallowed from bidding on this seller's items."; |
| 83 | 84 | break; |
| 84 | case AuctionServer.BID_ERROR_TOO_LOW: | |
| 85 | case AuctionServerInterface.BID_ERROR_TOO_LOW: | |
| 85 | 86 | bidResultString = "Your bid was too low, and was not accepted."; |
| 86 | 87 | break; |
| 87 | case AuctionServer.BID_ERROR_TOO_LOW_SELF: | |
| 88 | case AuctionServerInterface.BID_ERROR_TOO_LOW_SELF: | |
| 88 | 89 | bidResultString = "Your bid was below or equal to your previous high bid, and was not accepted."; |
| 89 | 90 | break; |
| 90 | case AuctionServer.BID_ERROR_RESERVE_NOT_MET: | |
| 91 | case AuctionServerInterface.BID_ERROR_RESERVE_NOT_MET: | |
| 91 | 92 | bidResultString = "Your bid was successful, but it did not meet the reserve price."; |
| 92 | 93 | break; |
| 93 | case AuctionServer.BID_ERROR_AMOUNT: | |
| 94 | case AuctionServerInterface.BID_ERROR_AMOUNT: | |
| 94 | 95 | bidResultString = "Bidding apparently failed, because of an an invalid amount (" + bidAmount + ")."; |
| 95 | 96 | break; |
| 96 | case AuctionServer.BID_ERROR_OUTBID: | |
| 97 | case AuctionServerInterface.BID_ERROR_OUTBID: | |
| 97 | 98 | bidResultString = "Your bid for " + bidAmount + " was submitted, but someone else's bid is still higher."; |
| 98 | 99 | break; |
| 99 | case AuctionServer.BID_ERROR_CONNECTION: | |
| 100 | case AuctionServerInterface.BID_ERROR_CONNECTION: | |
| 100 | 101 | bidResultString = "Bid failed due to connection problem. Probably a timeout trying to reach eBay."; |
| 101 | 102 | break; |
| 102 | 103 | case AuctionServer.BID_ERROR_AUCTION_GONE: |
| 103 | 104 | bidResultString = "Your bid failed because the item was removed from JBidwatcher before the bid executed."; |
| 104 | 105 | break; |
| 105 | case AuctionServer.BID_WINNING: | |
| 106 | case AuctionServer.BID_SELFWIN: | |
| 106 | case AuctionServerInterface.BID_WINNING: | |
| 107 | case AuctionServerInterface.BID_SELFWIN: | |
| 107 | 108 | bidResultString = "Congratulations! You have the high bid with " + bidAmount + '.'; |
| 108 | 109 | break; |
| 109 | 110 | case AuctionServer.BID_ERROR_ACCOUNT_SUSPENDED: |
| 24 | 48 | |
|---|---|---|
| 8 | 8 | |
| 9 | 9 | import com.jbidwatcher.util.Currency; |
| 10 | 10 | import com.jbidwatcher.auction.server.AuctionServer; |
| 11 | import com.jbidwatcher.auction.server.AuctionServerInterface; | |
| 11 | 12 | |
| 12 | 13 | public class AuctionBuy extends AuctionActionImpl { |
| 13 | 14 | public AuctionBuy(String id, Currency amount, int quantity) { |
| --- | --- | |
| 26 | 27 | String bidResultString; |
| 27 | 28 | |
| 28 | 29 | switch (bidResult) { |
| 29 | case AuctionServer.BID_ERROR_UNKNOWN: | |
| 30 | case AuctionServerInterface.BID_ERROR_UNKNOWN: | |
| 30 | 31 | bidResultString = "Purchasing " + bidAmount + " apparently failed for an unknown reason. Check the auction in the browser, to see if it went through anyway."; |
| 31 | 32 | break; |
| 32 | case AuctionServer.BID_ERROR_ENDED: | |
| 33 | case AuctionServer.BID_ERROR_CANNOT: | |
| 33 | case AuctionServerInterface.BID_ERROR_ENDED: | |
| 34 | case AuctionServerInterface.BID_ERROR_CANNOT: | |
| 34 | 35 | bidResultString = "Purchasing apparently failed, as the auction cannot be bought from anymore (probably ended)!"; |
| 35 | 36 | break; |
| 36 | case AuctionServer.BID_ERROR_BANNED: | |
| 37 | case AuctionServerInterface.BID_ERROR_BANNED: | |
| 37 | 38 | bidResultString = "Your purchase failed, as you are disallowed from buying this seller's items."; |
| 38 | 39 | break; |
| 39 | case AuctionServer.BID_ERROR_CONNECTION: | |
| 40 | case AuctionServerInterface.BID_ERROR_CONNECTION: | |
| 40 | 41 | bidResultString = "Purchase failed due to connection problem. Probably a timeout trying to reach eBay."; |
| 41 | 42 | break; |
| 42 | 43 | case AuctionServer.BID_ERROR_AUCTION_GONE: |
| 24 | 48 | |
|---|---|---|
| 22 | 22 | import com.jbidwatcher.*; |
| 23 | 23 | import com.jbidwatcher.auction.server.AuctionServerManager; |
| 24 | 24 | import com.jbidwatcher.auction.server.AuctionServer; |
| 25 | import com.jbidwatcher.auction.server.AuctionServerInterface; | |
| 25 | 26 | import com.jbidwatcher.util.ErrorManagement; |
| 26 | 27 | |
| 27 | 28 | import java.io.*; |
| --- | --- | |
| 321 | 322 | public static String stripId(String id) { |
| 322 | 323 | String strippedId = id; |
| 323 | 324 | if(id.startsWith("http")) { |
| 324 | AuctionServer aucServ = AuctionServerManager.getInstance().getServerForUrlString(id); | |
| 325 | AuctionServerInterface aucServ = AuctionServerManager.getInstance().getServerForUrlString(id); | |
| 325 | 326 | strippedId = aucServ.extractIdentifierFromURLString(id); |
| 326 | 327 | } |
| 327 | 328 | |
| 47 | 48 | |
|---|---|---|
| 15 | 15 | import com.jbidwatcher.util.http.CookieJar; |
| 16 | 16 | import com.jbidwatcher.util.ErrorManagement; |
| 17 | 17 | import com.jbidwatcher.auction.server.AuctionServer; |
| 18 | import com.jbidwatcher.auction.server.AuctionServerInterface; | |
| 18 | 19 | import com.jbidwatcher.auction.Auctions; |
| 19 | 20 | import com.jbidwatcher.auction.AuctionEntry; |
| 20 | 21 | |
| --- | --- | |
| 124 | 125 | |
| 125 | 126 | public static String getSnipeResult(int snipeResult, String aucTitle, AuctionEntry aeFire) { |
| 126 | 127 | String snipeOutput; |
| 127 | if(snipeResult == AuctionServer.BID_WINNING || snipeResult == AuctionServer.BID_SELFWIN) { | |
| 128 | if(snipeResult == AuctionServerInterface.BID_WINNING || snipeResult == AuctionServerInterface.BID_SELFWIN) { | |
| 128 | 129 | snipeOutput = "Successfully sniped a high bid on " + aucTitle + '!'; |
| 129 | } else if(snipeResult == AuctionServer.BID_DUTCH_CONFIRMED) { | |
| 130 | } else if(snipeResult == AuctionServerInterface.BID_DUTCH_CONFIRMED) { | |
| 130 | 131 | snipeOutput = "Successfully sniped a high dutch bid on " + aucTitle + '!'; |
| 131 | 132 | } else { |
| 132 | 133 | switch(snipeResult) { |
| 133 | case AuctionServer.BID_ERROR_UNKNOWN: | |
| 134 | case AuctionServerInterface.BID_ERROR_UNKNOWN: | |
| 134 | 135 | snipeOutput = "Unknown error sniping on " + aucTitle; |
| 135 | 136 | break; |
| 136 | case AuctionServer.BID_ERROR_ENDED: | |
| 137 | case AuctionServer.BID_ERROR_CANNOT: | |
| 137 | case AuctionServerInterface.BID_ERROR_ENDED: | |
| 138 | case AuctionServerInterface.BID_ERROR_CANNOT: | |
| 138 | 139 | snipeOutput = "Snipe apparently failed, as the auction cannot be bid on anymore: " + aucTitle; |
| 139 | 140 | break; |
| 140 | case AuctionServer.BID_ERROR_BANNED: | |
| 141 | case AuctionServerInterface.BID_ERROR_BANNED: | |
| 141 | 142 | snipeOutput = "Snipe failed, as you are disallowed from bidding on " + aeFire.getSeller() + "'s items."; |
| 142 | 143 | break; |
| 143 | case AuctionServer.BID_ERROR_TOO_LOW: | |
| 144 | case AuctionServerInterface.BID_ERROR_TOO_LOW: | |
| 144 | 145 | snipeOutput = "Snipe was too low, and was not accepted."; |
| 145 | 146 | break; |
| 146 | case AuctionServer.BID_ERROR_TOO_LOW_SELF: | |
| 147 | case AuctionServerInterface.BID_ERROR_TOO_LOW_SELF: | |
| 147 | 148 | snipeOutput = "Your bid was below or equal to your previous high bid, and was not accepted."; |
| 148 | 149 | break; |
| 149 | case AuctionServer.BID_ERROR_RESERVE_NOT_MET: | |
| 150 | case AuctionServerInterface.BID_ERROR_RESERVE_NOT_MET: | |
| 150 | 151 | snipeOutput = "Your snipe was successful, but it did not meet the reserve price."; |
| 151 | 152 | break; |
| 152 | case AuctionServer.BID_ERROR_AMOUNT: | |
| 153 | case AuctionServerInterface.BID_ERROR_AMOUNT: | |
| 153 | 154 | snipeOutput = "There is an error with the amount for the snipe on " + aucTitle + " (Probably snipe too low vs. current bids)."; |
| 154 | 155 | break; |
| 155 | case AuctionServer.BID_ERROR_OUTBID: | |
| 156 | case AuctionServerInterface.BID_ERROR_OUTBID: | |
| 156 | 157 | snipeOutput = "You have been outbid in your snipe on " + aucTitle; |
| 157 | 158 | break; |
| 158 | case AuctionServer.BID_ERROR_CONNECTION: | |
| 159 | case AuctionServerInterface.BID_ERROR_CONNECTION: | |
| 159 | 160 | snipeOutput = "Snipe failed due to connection problem. Probably a timeout trying to reach eBay."; |
| 160 | 161 | break; |
| 161 | 162 | case AuctionServer.BID_ERROR_AUCTION_GONE: |
| --- | --- | |
| 173 | 174 | case AuctionServer.BID_ERROR_REQUIREMENTS_NOT_MET: |
| 174 | 175 | snipeOutput = "You don't meet some requirement the seller has set for the item. Check the item details for more information."; |
| 175 | 176 | break; |
| 176 | case AuctionServer.BID_ERROR_MULTI: | |
| 177 | case AuctionServerInterface.BID_ERROR_MULTI: | |
| 177 | 178 | snipeOutput = "There is a problem with the multisnipe, an earlier entry hasn't finished updating. Trying again shortly."; |
| 178 | 179 | break; |
| 179 | 180 | default: |
| 24 | 48 | |
|---|---|---|
| 40 | 40 | import java.text.SimpleDateFormat; |
| 41 | 41 | |
| 42 | 42 | |
| 43 | public abstract class AuctionServer implements XMLSerialize { | |
| 44 | public static final int BID_ERROR_UNKNOWN=-1; | |
| 45 | public static final int BID_ERROR_CANNOT=1; | |
| 46 | public static final int BID_ERROR_AMOUNT=2; | |
| 47 | public static final int BID_ERROR_OUTBID=3; | |
| 48 | public static final int BID_WINNING=4; | |
| 49 | public static final int BID_SELFWIN=5; | |
| 50 | public static final int BID_DUTCH_CONFIRMED=6; | |
| 51 | public static final int BID_ERROR_MULTI=7; | |
| 52 | public static final int BID_ERROR_TOO_LOW=8; | |
| 53 | public static final int BID_ERROR_ENDED=9; | |
| 54 | public static final int BID_ERROR_BANNED=10; | |
| 55 | public static final int BID_ERROR_RESERVE_NOT_MET=11; | |
| 56 | public static final int BID_ERROR_CONNECTION=12; | |
| 57 | public static final int BID_ERROR_TOO_LOW_SELF = 13; // You can't bid that low against yourself... | |
| 58 | public static final int BID_ERROR_AUCTION_GONE = 14; // Auction vanished between bid creation and submission. | |
| 59 | public static final int BID_ERROR_NOT_BIN = 15; // Trying to 'Buy' an item that isn't a BIN/Fixed Price listing. | |
| 60 | public static final int BID_BOUGHT_ITEM = 16; // Successfully bought an item via BIN. | |
| 61 | public static final int BID_ERROR_ACCOUNT_SUSPENDED = 17; // Your account has been (!) suspended, you can't bid. | |
| 62 | public static final int BID_ERROR_CANT_SIGN_IN = 18; // We tried to get bid pages, but it kept asking for login. | |
| 63 | public static final int BID_ERROR_WONT_SHIP = 19; // You are registered in a country to which the seller doesn't ship. | |
| 64 | public static final int BID_ERROR_REQUIREMENTS_NOT_MET = 20; // This seller has set buyer requirements for this item and only sells to buyers who meet those requirements. | |
| 43 | public abstract class AuctionServer implements XMLSerialize, AuctionServerInterface { | |
| 65 | 44 | |
| 66 | 45 | protected String siteId = null; /**< The human-readable name of an auction server. */ |
| 67 | 46 | private String userCfgString=null; |
| --- | --- | |
| 72 | 51 | private static final int YEAR_BASE = 1990; |
| 73 | 52 | private static GregorianCalendar midpointDate = new GregorianCalendar(YEAR_BASE, Calendar.JANUARY, 1); |
| 74 | 53 | private static final int HIGHBIT_ASCII = 0x80; |
| 75 | public static final String UPDATE_LOGIN_COOKIE = "Update login cookie"; | |
| 76 | 54 | |
| 77 | public abstract StringBuffer getAuctionViaAffiliate(CookieJar cj, AuctionEntry ae, String id) throws CookieJar.CookieException; | |
| 78 | public abstract int buy(AuctionEntry ae, int quantity); | |
| 55 | protected abstract StringBuffer getAuction(AuctionEntry ae, String id); | |
| 56 | ||
| 79 | 57 | public abstract long getSnipePadding(); |
| 80 | 58 | |
| 81 | 59 | /*!@class BadBidException |
| --- | --- | |
| 102 | 80 | } |
| 103 | 81 | } |
| 104 | 82 | |
| 105 | protected final Set<AuctionEntry> _aucList = new TreeSet<AuctionEntry>(new AuctionEntry.AuctionComparator()); /**< The list of auctions that this server is holding onto. */ | |
| 106 | ||
| 107 | protected long _pageRequestTime=0; /**< The full amount of time it takes to request a single page from this site. */ | |
| 108 | protected long _affRequestTime=0; /**< The amount of time it takes to request an item via their affiliate program. */ | |
| 83 | protected final Set<AuctionEntry> _aucList = new TreeSet<AuctionEntry>(new AuctionEntry.AuctionComparator()); | |
| 84 | /**< The amount of time it takes to request an item via their affiliate program. */ | |
| 109 | 85 | protected long _officialServerTimeDelta=0; |
| 110 | 86 | protected TimeZone _officialServerTimeZone = null; |
| 111 | public abstract String extractIdentifierFromURLString(String urlStyle); | |
| 87 | ||
| 112 | 88 | public abstract CookieJar getNecessaryCookie(boolean force); |
| 113 | 89 | public abstract CookieJar getSignInCookie(CookieJar old_cj); |
| 114 | 90 | public abstract void safeGetAffiliate(CookieJar cj, AuctionEntry inEntry) throws CookieJar.CookieException; |
| 115 | 91 | public abstract JHTML.Form getBidForm(CookieJar cj, AuctionEntry inEntry, com.jbidwatcher.util.Currency inCurr, int inQuant) throws BadBidException; |
| 116 | public abstract int bid(AuctionEntry inEntry, Currency inBid, int inQuantity); | |
| 92 | ||
| 117 | 93 | public abstract int placeFinalBid(CookieJar cj, JHTML.Form bidForm, AuctionEntry inEntry, Currency inBid, int inQuantity); |
| 118 | public abstract boolean checkIfIdentifierIsHandled(String auctionId); | |
| 94 | ||
| 119 | 95 | public abstract void establishMenu(); |
| 120 | 96 | public abstract JConfigTab getConfigurationTab(); |
| 121 | 97 | public abstract void cancelSearches(); |
| 122 | 98 | public abstract void addSearches(SearchManagerInterface searchManager); |
| 123 | public abstract Currency getMinimumBidIncrement(Currency currentBid, int bidCount); | |
| 99 | ||
| 124 | 100 | public abstract boolean isHighDutch(AuctionEntry inAE); |
| 125 | 101 | public abstract void updateHighBid(AuctionEntry ae); |
| 126 | 102 | |
| --- | --- | |
| 131 | 107 | */ |
| 132 | 108 | protected abstract Date getOfficialTime(); |
| 133 | 109 | |
| 134 | /** | |
| 135 | * @brief Get the URL (in String form that a browser can view with) for a given item ID on this auction server. | |
| 136 | * | |
| 137 | * @param itemID - The item to retrieve the URL for. | |
| 138 | * | |
| 139 | * @return - A String with the full URL of the item description on the auction server. | |
| 140 | */ | |
| 141 | public abstract String getBrowsableURLFromItem(String itemID); | |
| 142 | ||
| 143 | /** | |
| 110 | /** | |
| 144 | 111 | * @brief Get the string-form URL for a given item ID on this |
| 145 | 112 | * auction server, for when we aren't browsing. |
| 146 | 113 | * |
| --- | --- | |
| 268 | 235 | // Generalized logic |
| 269 | 236 | // ----------------- |
| 270 | 237 | |
| 271 | /** | |
| 272 | * @brief Add an auction to this server, based on item ID. | |
| 273 | * | |
| 274 | * @param itemId - The auction item to add. | |
| 275 | * | |
| 276 | * @return - The underlying 'AuctionInfo' object that contains all | |
| 277 | * the basic accessors for auction data. | |
| 278 | */ | |
| 279 | 238 | public AuctionInfo addAuction(String itemId) { |
| 280 | 239 | URL auctionURL = getURLFromItem(itemId); |
| 281 | 240 | return( addAuction(auctionURL, itemId)); |
| --- | --- | |
| 292 | 251 | } |
| 293 | 252 | } |
| 294 | 253 | |
| 295 | /** | |
| 296 | * @brief Get the human-readable auction site name for this server. | |
| 297 | * | |
| 298 | * @return - A String with the human-readable auction site name. | |
| 299 | */ | |
| 300 | 254 | public String getName() { |
| 301 | 255 | return siteId; |
| 302 | 256 | } |
| --- | --- | |
| 505 | 459 | } |
| 506 | 460 | } |
| 507 | 461 | |
| 508 | /** | |
| 509 | * @brief Returns the amount of time it takes to retrieve a page | |
| 510 | * from the auction server. | |
| 511 | * | |
| 512 | * @return The amount of milliseconds it takes to get a simple page | |
| 513 | * from the auction server. | |
| 514 | */ | |
| 515 | public long getPageRequestTime() { | |
| 516 | return _pageRequestTime; | |
| 517 | } | |
| 518 | ||
| 519 | /** | |
| 520 | * @brief Returns the amount of time it takes to retrieve an item | |
| 521 | * from the auction server via their affiliate program. | |
| 522 | * | |
| 523 | * @return The amount of milliseconds it takes to get an item | |
| 524 | * from the auction server via their affiliate server. | |
| 525 | */ | |
| 526 | public long getAffiliateRequestTime() { | |
| 527 | return _affRequestTime; | |
| 528 | } | |
| 529 | ||
| 530 | /** | |
| 531 | * @brief Returns the difference in time between the local machine's | |
| 532 | * normalized time, and the auction site's normalized time. | |
| 533 | * | |
| 534 | * @return The amount of milliseconds off the server time is from | |
| 535 | * local time. | |
| 536 | */ | |
| 537 | 462 | public long getOfficialServerTimeDelta() { |
| 538 | 463 | return _officialServerTimeDelta; |
| 539 | 464 | } |
| 540 | 465 | |
| 541 | /** | |
| 542 | * @brief Retrieve what time zone the server is in. | |
| 543 | * | |
| 544 | * @return - The time zone of the auction server. | |
| 545 | */ | |
| 546 | 466 | public TimeZone getOfficialServerTimeZone() { |
| 547 | 467 | return _officialServerTimeZone; |
| 548 | 468 | } |
| 549 | 469 | |
| 550 | /** | |
| 551 | * @brief Load an auction, and return it. It really doesn't 'add' | |
| 552 | * anything... | |
| 553 | * | |
| 554 | * @param auctionURL - The URL to the item description to add. | |
| 555 | * @param item_id - The item ID to add. | |
| 556 | * | |
| 557 | * @return - An AuctionInfo low-level generic Auction object. | |
| 558 | */ | |
| 559 | 470 | public AuctionInfo addAuction(URL auctionURL, String item_id) { |
| 560 | SpecificAuction newAuction = (SpecificAuction) loadAuction(auctionURL, item_id, null, true); | |
| 471 | SpecificAuction newAuction = (SpecificAuction) loadAuction(auctionURL, item_id, null); | |
| 561 | 472 | |
| 562 | 473 | return(newAuction); |
| 563 | 474 | } |
| --- | --- | |
| 595 | 506 | |
| 596 | 507 | static long s_last_updated = 0; |
| 597 | 508 | |
| 598 | public AuctionInfo loadAuction(URL auctionURL, String item_id, AuctionEntry ae) { | |
| 599 | return loadAuction(auctionURL, item_id, ae, false); | |
| 600 | } | |
| 601 | ||
| 602 | 509 | private void markCommunicationError(AuctionEntry ae) { |
| 603 | 510 | if (ae != null) { |
| 604 | 511 | MQFactory.getConcrete("Swing").enqueue("LINK DOWN Communications failure talking to the server during item #" + ae.getIdentifier() + "( " + ae.getTitle() + " )"); |
| --- | --- | |
| 615 | 522 | * @param auctionURL - The URL to load the auction from. |
| 616 | 523 | * @param item_id - The item # to associate this returned info with. |
| 617 | 524 | * @param ae - An object to notify when an error occurs. |
| 618 | * @param viaAffiliate - Whether to load via an affiliate link or not. | |
| 619 | * | |
| 620 | 525 | * @return - An object containing the information extracted from the auction. |
| 621 | 526 | */ |
| 622 | public AuctionInfo loadAuction(URL auctionURL, String item_id, AuctionEntry ae, boolean viaAffiliate) { | |
| 623 | SpecificAuction curAuction = getNewSpecificAuction(); | |
| 527 | public AuctionInfo loadAuction(URL auctionURL, String item_id, AuctionEntry ae) { | |
| 528 | StringBuffer sb = getAuction(ae, item_id); | |
| 624 | 529 | |
| 625 | if(item_id != null) { | |
| 626 | curAuction.setIdentifier(item_id); | |
| 627 | } | |
| 628 | StringBuffer sb = null; | |
| 629 | ||
| 630 | if(viaAffiliate) { | |
| 530 | if (sb == null) { | |
| 631 | 531 | try { |
| 632 | long pre = System.currentTimeMillis(); | |
| 633 | sb = getAuctionViaAffiliate(getNecessaryCookie(false), ae, item_id); | |
| 634 | long post = System.currentTimeMillis(); | |
| 635 | _affRequestTime = (post - pre); | |
| 636 | if(sb == null) viaAffiliate = false; | |
| 637 | } catch (CookieJar.CookieException e) { | |
| 638 | // This failed... Let's retry with a normal get... | |
| 639 | viaAffiliate = false; | |
| 532 | sb = getAuction(auctionURL); | |
| 533 | } catch (FileNotFoundException ignored) { | |
| 534 | // Just get out. The item no longer exists on the auction | |
| 535 | // server, so we shouldn't be trying any of the rest. The | |
| 536 | // Error should have been logged at the lower level, so just | |
| 537 | // punt. It's not a communications error, either. | |
| 538 | return null; | |
| 539 | } catch (Exception catchall) { | |
| 540 | if (JConfig.debugging()) { | |
| 541 | ErrorManagement.handleException("Some unexpected error occurred during loading the auction.", catchall); | |
| 542 | } | |
| 640 | 543 | } |
| 641 | 544 | } |
| 642 | 545 | |
| 643 | try { | |
| 644 | if(!viaAffiliate) { | |
| 645 | if (JConfig.queryConfiguration("timesync.enabled", "true").equals("true")) { | |
| 646 | long pre = System.currentTimeMillis(); | |
| 647 | sb = getAuction(auctionURL); | |
| 648 | long post = System.currentTimeMillis(); | |
| 649 | _pageRequestTime = (post - pre); | |
| 650 | } else /* TimeSync disabled */ | |
| 651 | sb = getAuction(auctionURL); | |
| 652 | } | |
| 653 | if(sb != null) { | |
| 654 | curAuction.setContent(sb, false); | |
| 655 | } | |
| 656 | } catch(FileNotFoundException ignored) { | |
| 657 | // Just get out. The item no longer exists on the auction | |
| 658 | // server, so we shouldn't be trying any of the rest. The | |
| 659 | // Error should have been logged at the lower level, so just | |
| 660 | // punt. It's not a communications error, either. | |
| 661 | return null; | |
| 662 | } catch(Exception catchall) { | |
| 663 | if(JConfig.debugging()) ErrorManagement.handleException("Some unexpected error occurred during loading the auction.", catchall); | |
| 664 | sb = null; | |
| 546 | SpecificAuction curAuction = null; | |
| 547 | if(sb != null) { | |
| 548 | curAuction = doParse(sb, ae, item_id); | |
| 665 | 549 | } |
| 666 | boolean successfulParse = true; | |
| 667 | 550 | |
| 668 | if(sb == null) { | |
| 669 | checkLogError(ae); | |
| 670 | successfulParse = false; | |
| 551 | if(curAuction == null) { | |
| 552 | noteRetrieveError(ae); | |
| 671 | 553 | } |
| 554 | return curAuction; | |
| 555 | } | |
| 672 | 556 | |
| 673 | if(successfulParse) { | |
| 674 | successfulParse = curAuction.preParseAuction(); | |
| 675 | if(successfulParse) { | |
| 676 | successfulParse = curAuction.parseAuction(ae); | |
| 677 | } else { | |
| 678 | ErrorManagement.logMessage("Bad Parse!"); | |
| 679 | checkLogError(ae); | |
| 680 | } | |
| 557 | private SpecificAuction doParse(StringBuffer sb, AuctionEntry ae, String item_id) { | |
| 558 | SpecificAuction curAuction = getNewSpecificAuction(); | |
| 559 | ||
| 560 | if (item_id != null) { | |
| 561 | curAuction.setIdentifier(item_id); | |
| 681 | 562 | } |
| 563 | curAuction.setContent(sb, false); | |
| 564 | String error = null; | |
| 565 | if (curAuction.preParseAuction()) { | |
| 566 | if (curAuction.parseAuction(ae)) { | |
| 567 | curAuction.save(); | |
| 568 | } else error = "Bad Parse!"; | |
| 569 | } else error = "Bad pre-parse!"; | |
| 682 | 570 | |
| 683 | if(!successfulParse) { | |
| 684 | // Whoops! Bad thing happened on the way to loading the auction! | |
| 685 | ErrorManagement.logDebug("Failed to parse auction! Bad return result from auction server."); | |
| 686 | // Only retry the login cookie once every ten minutes of these errors. | |
| 687 | if( (s_last_updated + Constants.ONE_MINUTE * 10) > System.currentTimeMillis()) { | |
| 688 | s_last_updated = System.currentTimeMillis(); | |
| 689 | MQFactory.getConcrete(siteId).enqueue(new AuctionQObject(AuctionQObject.MENU_CMD, UPDATE_LOGIN_COOKIE, null)); //$NON-NLS-1$ //$NON-NLS-2$ | |
| 690 | } | |
| 691 | curAuction = null; | |
| 571 | if(error != null) { | |
| 572 | ErrorManagement.logMessage(error); | |
| 573 | checkLogError(ae); | |
| 692 | 574 | } |
| 575 | return curAuction; | |
| 576 | } | |
| 693 | 577 | |
| 694 | if(curAuction != null) { | |
| 695 | curAuction.save(); | |
| 578 | private void noteRetrieveError(AuctionEntry ae) { | |
| 579 | checkLogError(ae); | |
| 580 | // Whoops! Bad thing happened on the way to loading the auction! | |
| 581 | ErrorManagement.logDebug("Failed to parse auction! Bad return result from auction server."); | |
| 582 | // Only retry the login cookie once every ten minutes of these errors. | |
| 583 | if ((s_last_updated + Constants.ONE_MINUTE * 10) > System.currentTimeMillis()) { | |
| 584 | s_last_updated = System.currentTimeMillis(); | |
| 585 | MQFactory.getConcrete(siteId).enqueue(new AuctionQObject(AuctionQObject.MENU_CMD, UPDATE_LOGIN_COOKIE, null)); //$NON-NLS-1$ //$NON-NLS-2$ | |
| 696 | 586 | } |
| 697 | return(curAuction); | |
| 698 | 587 | } |
| 699 | 588 | |
| 700 | 589 | private void checkLogError(AuctionEntry ae) { |
| --- | --- | |
| 800 | 689 | } else { |
| 801 | 690 | // This is bad... |
| 802 | 691 | ErrorManagement.logMessage(siteId + ": Error, can't accurately set delta to server's official time."); |
| 803 | // This should be LOGGED! -- FIXME -- mrs: 13-February-2001 19:59 | |
| 804 | _pageRequestTime = 0; | |
| 805 | 692 | _officialServerTimeDelta = 0; |
| 806 | 693 | return false; |
| 807 | 694 | } |
| 24 | 48 | |
|---|---|---|
| 123 | 123 | String cmd = (String)deQ; |
| 124 | 124 | |
| 125 | 125 | if(cmd.equals("TIMECHECK")) { |
| 126 | AuctionServer defaultServer = getDefaultServer(); | |
| 126 | AuctionServerInterface defaultServer = getDefaultServer(); | |
| 127 | 127 | |
| 128 | 128 | defaultServer.reloadTimeNow(); |
| 129 | 129 | |
| --- | --- | |
| 150 | 150 | } |
| 151 | 151 | |
| 152 | 152 | public String getDefaultServerTime() { |
| 153 | AuctionServer defaultServer = getDefaultServer(); | |
| 153 | AuctionServerInterface defaultServer = getDefaultServer(); | |
| 154 | 154 | return defaultServer.getTime(); |
| 155 | 155 | } |
| 156 | 156 | |
| 37 | 48 | |
|---|---|---|
| 31 | 31 | import com.jbidwatcher.auction.*; |
| 32 | 32 | import com.jbidwatcher.auction.server.AuctionServerManager; |
| 33 | 33 | import com.jbidwatcher.auction.server.AuctionServer; |
| 34 | import com.jbidwatcher.auction.server.AuctionServerInterface; | |
| 34 | 35 | import com.jbidwatcher.TimerHandler; |
| 35 | 36 | import com.jbidwatcher.Constants; |
| 36 | 37 | import com.jbidwatcher.auction.ThumbnailManager; |
| --- | --- | |
| 124 | 125 | private Map<String, AuctionQObject> snipeMap = new HashMap<String, AuctionQObject>(); |
| 125 | 126 | private String mBadPassword = null; |
| 126 | 127 | private String mBadUsername = null; |
| 128 | /**< The full amount of time it takes to request a single page from this site. */ | |
| 129 | protected long _affRequestTime=0; | |
| 130 | /**< The list of auctions that this server is holding onto. */ | |
| 127 | 131 | |
| 132 | protected long _pageRequestTime=0; | |
| 133 | ||
| 128 | 134 | { |
| 129 | 135 | loadStrings(); |
| 130 | 136 | } |
| --- | --- | |
| 857 | 863 | } |
| 858 | 864 | |
| 859 | 865 | Auctions.endBlocking(); |
| 866 | ||
| 867 | // If we couldn't get a number, clear the page request time. | |
| 868 | if(result == null) _pageRequestTime = 0; | |
| 860 | 869 | return result; |
| 861 | 870 | } |
| 862 | 871 | |
| --- | --- | |
| 1056 | 1065 | return 1; |
| 1057 | 1066 | } |
| 1058 | 1067 | |
| 1059 | public StringBuffer getAuctionViaAffiliate(CookieJar cj, AuctionEntry ae, String id) throws CookieJar.CookieException { | |
| 1068 | public StringBuffer getAuction(AuctionEntry ae, String id) { | |
| 1069 | CookieJar cj = getCookie(); | |
| 1060 | 1070 | long end_time = 1; |
| 1071 | // TODO -- Replace with a global lookup for auction entry by id. | |
| 1061 | 1072 | if(ae != null) { |
| 1062 | 1073 | Date end = ae.getEndDate(); |
| 1063 | 1074 | if(end != null) end_time = end.getTime(); |
| 1064 | 1075 | } |
| 1065 | 1076 | StringBuffer sb = null; |
| 1066 | if(JBConfig.doAffiliate(end_time)) { | |
| 1067 | sb = AffiliateRetrieve.getAuctionViaAffiliate(cj, id); | |
| 1077 | if(cj != null && allowAffiliate() && JBConfig.doAffiliate(end_time)) { | |
| 1078 | try { | |
| 1079 | long pre = System.currentTimeMillis(); | |
| 1080 | sb = AffiliateRetrieve.getAuctionViaAffiliate(cj, id); | |
| 1081 | long post = System.currentTimeMillis(); | |
| 1082 | _affRequestTime = (post - pre); | |
| 1083 | } catch(CookieJar.CookieException cje) { | |
| 1084 | // Cookie failure... Ignore it and do a regular get. | |
| 1085 | } | |
| 1068 | 1086 | } |
| 1069 | 1087 | |
| 1070 | 1088 | if(sb == null || sb.indexOf("eBay item") == -1) { |
| 1071 | 1089 | try { |
| 1090 | long pre = System.currentTimeMillis(); | |
| 1072 | 1091 | sb = getAuction(getURLFromItem(id)); |
| 1092 | long post = System.currentTimeMillis(); | |
| 1093 | if (JConfig.queryConfiguration("timesync.enabled", "true").equals("true")) { | |
| 1094 | _pageRequestTime = (post - pre); | |
| 1095 | } | |
| 1073 | 1096 | } catch (FileNotFoundException ignored) { |
| 1074 | 1097 | sb = null; |
| 1075 | 1098 | } |
| --- | --- | |
| 1078 | 1101 | return sb; |
| 1079 | 1102 | } |
| 1080 | 1103 | |
| 1104 | public long getPageRequestTime() { | |
| 1105 | return _pageRequestTime; | |
| 1106 | } | |
| 1107 | ||
| 1108 | private boolean allowAffiliate() { | |
| 1109 | ErrorManagement.logDebug("NOT allowing affiliate mode."); | |
| 1110 | return false; | |
| 1111 | } | |
| 1112 | ||
| 1113 | private CookieJar getCookie() { | |
| 1114 | ErrorManagement.logDebug("NOT getting cookie."); | |
| 1115 | return null; | |
| 1116 | } | |
| 1117 | ||
| 1081 | 1118 | public int buy(AuctionEntry ae, int quantity) { |
| 1082 | 1119 | String buyRequest = "http://offer.ebay.com/ws/eBayISAPI.dll?MfcISAPICommand=BinConfirm&fb=1&co_partnerid=&item=" + ae.getIdentifier() + "&quantity=" + quantity; |
| 1083 | 1120 | |
| 1084 | 1121 | // This updates the cookies with the affiliate information, if it's not a test auction. |
| 1085 | 1122 | if(ae.getTitle().toLowerCase().indexOf("test") == -1) { |
| 1086 | 1123 | if(JBConfig.doAffiliate(ae.getEndDate().getTime())) { |
| 1087 | try { | |
| 1088 | getAuctionViaAffiliate(getNecessaryCookie(false), ae, ae.getIdentifier()); | |
| 1089 | } catch (CookieJar.CookieException ignore) { | |
| 1090 | // Ignore, it doesn't matter for this call. | |
| 1091 | } | |
| 1124 | // Ignoring the result as it's just called to trigger affiliate mode. | |
| 1125 | getAuction(ae, ae.getIdentifier()); | |
| 1092 | 1126 | } |
| 1093 | 1127 | } |
| 1094 | 1128 | |
| --- | --- | |
| 1191 | 1225 | if(inEntry.getTitle().toLowerCase().indexOf("test") == -1) { |
| 1192 | 1226 | if(JBConfig.doAffiliate(inEntry.getEndDate().getTime())) { |
| 1193 | 1227 | if(JConfig.debugging) inEntry.setLastStatus("Loading item..."); |
| 1194 | getAuctionViaAffiliate(cj, inEntry, inEntry.getIdentifier()); | |
| 1228 | getAuction(inEntry, inEntry.getIdentifier()); | |
| 1195 | 1229 | if(JConfig.debugging) inEntry.setLastStatus("Done loading item..."); |
| 1196 | 1230 | } |
| 1197 | 1231 | } |
| --- | --- | |
| 1558 | 1592 | /** |
| 1559 | 1593 | * Does this look like an auction server item URL? |
| 1560 | 1594 | */ |
| 1561 | AuctionServer aucServ = AuctionServerManager.getInstance().getServerForUrlString(url); | |
| 1595 | AuctionServerInterface aucServ = AuctionServerManager.getInstance().getServerForUrlString(url); | |
| 1562 | 1596 | String hasId = aucServ.extractIdentifierFromURLString(url); |
| 1563 | 1597 | |
| 1564 | 1598 | if (hasId != null) { |
| --- | --- | |
| 2778 | 2812 | } |
| 2779 | 2813 | } |
| 2780 | 2814 | } |
| 2815 | ||
| 2816 | /** | |
| 2817 | * @brief Returns the amount of time it takes to retrieve an item | |
| 2818 | * from the auction server via their affiliate program. | |
| 2819 | * | |
| 2820 | * @return The amount of milliseconds it takes to get an item | |
| 2821 | * from the auction server via their affiliate server. | |
| 2822 | */ | |
| 2823 | public long getAffiliateRequestTime() { | |
| 2824 | return _affRequestTime; | |
| 2825 | } | |
| 2781 | 2826 | } |
| 39 | 48 | |
|---|---|---|
| 341 | 341 | try { |
| 342 | 342 | boolean got = false; |
| 343 | 343 | if(JConfig.queryConfiguration("server.browseAffiliate", "true").equals("true")) { |
| 344 | try { | |
| 345 | StringBuffer sb = aucServ.getAuctionViaAffiliate(aucServ.getNecessaryCookie(false), ae, ae.getIdentifier()); | |
| 346 | if(sb != null) { | |
| 347 | sbOut.append(sb); | |
| 348 | got = true; | |
| 349 | } | |
| 350 | } catch (CookieJar.CookieException ignored) { | |
| 351 | // Ignore it, because 'got' will be false, and the right thing will happen. | |
| 344 | StringBuffer sb = aucServ.getAuction(AuctionServer.getURLFromString(aucServ.getStringURLFromItem(ae.getIdentifier()))); | |
| 345 | if (sb != null) { | |
| 346 | sbOut.append(sb); | |
| 347 | got = true; | |
| 352 | 348 | } |
| 353 | 349 | } |
| 354 | 350 | if(!got) { |
| 28 | 48 | |
|---|---|---|
| 16 | 16 | import java.io.FileNotFoundException; |
| 17 | 17 | |
| 18 | 18 | public class MockAuctionServer extends AuctionServer { |
| 19 | /**< The full amount of time it takes to request a single page from this site. */ | |
| 20 | protected long _affRequestTime=0; | |
| 21 | /**< The list of auctions that this server is holding onto. */ | |
| 22 | ||
| 23 | protected long _pageRequestTime=0; | |
| 24 | ||
| 19 | 25 | public MockAuctionServer() { |
| 20 | 26 | siteId = "testBay"; |
| 21 | 27 | } |
| --- | --- | |
| 41 | 47 | } |
| 42 | 48 | } |
| 43 | 49 | |
| 44 | public StringBuffer getAuctionViaAffiliate(CookieJar cj, AuctionEntry ae, String id) throws CookieJar.CookieException { | |
| 45 | addCall("getAuctionViaAffiliate"); | |
| 50 | public StringBuffer getAuction(AuctionEntry ae, String id) { | |
| 51 | addCall("getAuction"); | |
| 46 | 52 | StringBuffer sb = null; |
| 47 | 53 | try { |
| 48 | 54 | sb = getAuction(getURLFromItem(id)); |
| --- | --- | |
| 142 | 148 | return "http://www.jbidwatcher.com"; |
| 143 | 149 | } |
| 144 | 150 | |
| 151 | public long getPageRequestTime() { | |
| 152 | return 0; //To change body of implemented methods use File | Settings | File Templates. | |
| 153 | } | |
| 154 | ||
| 145 | 155 | public String getStringURLFromItem(String itemID) { |
| 146 | 156 | TestCase.fail("Unexpected function called!"); |
| 147 | 157 | return "http://www.jbidwatcher.com"; |
| --- | --- | |
| 172 | 182 | addCall("checkIfSiteNameHandled"); |
| 173 | 183 | return true; |
| 174 | 184 | } |
| 185 | ||
| 186 | /** | |
| 187 | * @brief Returns the amount of time it takes to retrieve an item | |
| 188 | * from the auction server via their affiliate program. | |
| 189 | * | |
| 190 | * @return The amount of milliseconds it takes to get an item | |
| 191 | * from the auction server via their affiliate server. | |
| 192 | */ | |
| 193 | public long getAffiliateRequestTime() { | |
| 194 | return _affRequestTime; | |
| 195 | } | |
| 175 | 196 | } |
