|
|
| 496 |
497 |
|
| 7 | 7 | import com.jbidwatcher.util.http.Http; |
| 8 | 8 | import com.jbidwatcher.util.Externalized; |
| 9 | 9 | import com.jbidwatcher.util.config.ErrorManagement; |
| 10 | | import com.jbidwatcher.util.script.Scripting; |
| 11 | 10 | import com.jbidwatcher.util.StringTools; |
| 12 | 11 | import com.jbidwatcher.util.Currency; |
| 13 | 12 | import com.jbidwatcher.util.UpdateBlocker; |
| 14 | 13 | import com.jbidwatcher.util.config.JConfig; |
| 15 | 14 | import com.jbidwatcher.util.queue.MQFactory; |
| 16 | | import com.jbidwatcher.app.MyJBidwatcher; |
| 15 | import com.jbidwatcher.my.MyJBidwatcher; |
| 17 | 16 | |
| 18 | 17 | import java.net.URLConnection; |
| 19 | 18 | import java.io.IOException; |
| --- | --- | |
| 91 | 90 | mResultHash.put("sign in", AuctionServer.BID_ERROR_CANT_SIGN_IN); |
| 92 | 91 | } |
| 93 | 92 | |
| 93 | /** |
| 94 | * Get the bidding form (with bid key) from the basic bid page. |
| 95 | * |
| 96 | * @param cj - The cookies for the current session. |
| 97 | * @param inEntry - The auction being bid on. |
| 98 | * @param inCurr - The amount to bid. |
| 99 | * @param inQuant - The quantity to bid on (if it's a dutch auction, 1 otherwise). |
| 100 | * |
| 101 | * @return - A Form object containing all the input fields from the bid-confirmation page's form. |
| 102 | * |
| 103 | * @throws BadBidException - If there's some kind of an error on the bid confirmation page. |
| 104 | */ |
| 94 | 105 | public JHTML.Form getBidForm(CookieJar cj, AuctionEntry inEntry, Currency inCurr, int inQuant) throws BadBidException { |
| 95 | 106 | String bidRequest = Externalized.getString("ebayServer.protocol") + Externalized.getString("ebayServer.bidHost") + Externalized.getString("ebayServer.V3file"); |
| 96 | | String bidInfo; |
| 97 | | if(inEntry.isDutch()) { |
| 98 | | bidInfo = Externalized.getString("ebayServer.bidCmd") + "&co_partnerid=" + Externalized.getString("ebayServer.itemCGI") + inEntry.getIdentifier() + |
| 99 | | "&fb=2" + Externalized.getString("ebayServer.quantCGI") + inQuant + |
| 100 | | Externalized.getString("ebayServer.bidCGI") + inCurr.getValue(); |
| 101 | | } else { |
| 102 | | bidInfo = Externalized.getString("ebayServer.bidCmd") + "&co_partnerid=" + Externalized.getString("ebayServer.itemCGI") + inEntry.getIdentifier() + "&fb=2" + |
| 103 | | Externalized.getString("ebayServer.bidCGI") + inCurr.getValue(); |
| 104 | | } |
| 105 | | StringBuffer loadedPage = null; |
| 106 | | JHTML htmlDocument = null; |
| 107 | String bidInfo = getBidInfoURL(inEntry, inCurr, inQuant); |
| 108 | BidFormReturn rval = null; |
| 107 | 109 | |
| 108 | 110 | try { |
| 109 | 111 | String pageName = bidRequest + '?' + bidInfo; |
| 110 | | boolean checked_signon = false; |
| 111 | | boolean checked_reminder = false; |
| 112 | | boolean done = false; |
| 113 | | boolean post = false; |
| 114 | | while (!done) { |
| 115 | | done = true; |
| 116 | 112 | |
| 117 | | if(JConfig.debugging) inEntry.setLastStatus("Loading bid request..."); |
| 118 | | URLConnection huc = cj.getAllCookiesFromPage(pageName, null, post); |
| 119 | | post = false; |
| 120 | | // We failed to load, entirely. Punt. |
| 121 | | if (huc == null) return null; |
| 113 | if (JConfig.debugging) inEntry.setLastStatus("Loading bid request..."); |
| 114 | rval = getBidFormInternal(pageName, inEntry, cj); |
| 122 | 115 | |
| 123 | | loadedPage = Http.receivePage(huc); |
| 124 | | // We failed to load. Punt. |
| 125 | | if (loadedPage == null) { |
| 126 | | return null; |
| 127 | | } else if(JConfig.debugging() && JConfig.queryConfiguration("my.jbidwatcher.id") != null) { |
| 128 | | String result = MyJBidwatcher.getInstance().recognizeBidpage(inEntry, loadedPage); |
| 129 | | // String result = (String) Scripting.rubyMethod("recognize_bidpage", inEntry, loadedPage); |
| 130 | | ErrorManagement.logDebug(result); |
| 131 | | } |
| 116 | if ( !rval.isSuccess() && (cj = checkSignin(inEntry, rval.getDocument())) != null) { |
| 117 | rval = getBidFormInternal(pageName, inEntry, cj); |
| 118 | } |
| 132 | 119 | |
| 133 | | htmlDocument = new JHTML(loadedPage); |
| 134 | | JHTML.Form bidForm = htmlDocument.getFormWithInput("key"); |
| 135 | | if(bidForm != null) { |
| 136 | | if(JConfig.debugging) inEntry.setLastStatus("Done loading bid request, got form..."); |
| 137 | | return bidForm; |
| 138 | | } |
| 120 | if( !rval.isSuccess() && (pageName = checkForWarning(inEntry, rval.getDocument())) != null) { |
| 121 | rval = getBidFormInternal(pageName, inEntry, cj); |
| 122 | } |
| 139 | 123 | |
| 140 | | if(!checked_signon) { |
| 141 | | checked_signon = true; |
| 142 | | String signOn = htmlDocument.getTitle(); |
| 143 | | if (signOn != null) { |
| 144 | | ErrorManagement.logDebug("Checking sign in as bid key load failed!"); |
| 145 | | if (StringTools.startsWithIgnoreCase(signOn, "sign in")) { |
| 146 | | // This means we somehow failed to keep the login in place. Bad news, in the middle of a snipe. |
| 147 | | ErrorManagement.logDebug("Being prompted again for sign in, retrying."); |
| 148 | | if(JConfig.debugging) inEntry.setLastStatus("Not done loading bid request, got re-login request..."); |
| 149 | | mLogin.resetCookie(); |
| 150 | | mLogin.getNecessaryCookie(true); |
| 151 | | if(JConfig.debugging) inEntry.setLastStatus("Done re-logging in, retrying load bid request."); |
| 152 | | done = false; |
| 153 | | } |
| 154 | | } |
| 155 | | } |
| 156 | | |
| 157 | | if(!checked_reminder) { |
| 158 | | if(htmlDocument.grep(Externalized.getString("ebayServer.warningPage")) != null) { |
| 159 | | checked_reminder = true; |
| 160 | | JHTML.Form continueForm = htmlDocument.getFormWithInput("firedFilterId"); |
| 161 | | if(continueForm != null) { |
| 162 | | inEntry.setLastStatus("Trying to 'continue' for the actual bid."); |
| 163 | | pageName = continueForm.getCGI(); |
| 164 | | pageName = pageName.replaceFirst("%[A-F][A-F0-9]%A0", "%A0"); |
| 165 | | done = false; |
| 166 | | post = false; |
| 167 | | } |
| 168 | | } |
| 169 | | } |
| 170 | | } |
| 124 | if (rval.isSuccess()) return rval.getForm(); |
| 171 | 125 | } catch (IOException e) { |
| 172 | 126 | ErrorManagement.handleException("Failure to get the bid key! BID FAILURE!", e); |
| 173 | 127 | } |
| 174 | 128 | |
| 175 | | if(htmlDocument != null) { |
| 176 | | String signOn = htmlDocument.getTitle(); |
| 177 | | if(signOn != null && signOn.equalsIgnoreCase("Sign In")) throw new BadBidException("sign in", AuctionServerInterface.BID_ERROR_CANT_SIGN_IN); |
| 178 | | String errMsg = htmlDocument.grep(mBidResultRegex); |
| 179 | | if(errMsg != null) { |
| 180 | | Matcher bidMatch = mFindBidResult.matcher(errMsg); |
| 181 | | bidMatch.find(); |
| 182 | | String matched_error = bidMatch.group().toLowerCase(); |
| 183 | | throw new BadBidException(matched_error, getMatchedResult(matched_error)); |
| 184 | | } else { |
| 185 | | String amount = htmlDocument.getNextContentAfterRegex("Enter"); |
| 186 | | if (amount != null) { |
| 187 | | String orMore = htmlDocument.getNextContent(); |
| 188 | | if (orMore != null && orMore.indexOf("or more") != -1) { |
| 189 | | throw new BadBidException("Enter " + amount + orMore, ebayServer.BID_ERROR_TOO_LOW); |
| 190 | | } |
| 191 | | } |
| 192 | | } |
| 129 | // If we never got a valid return value (e.g. an exception was thrown early), punt. |
| 130 | if(rval == null) return null; |
| 131 | |
| 132 | if(rval.getDocument() != null) { |
| 133 | checkSignOn(rval.getDocument()); |
| 134 | checkBidErrors(rval.getDocument()); |
| 193 | 135 | } |
| 194 | 136 | |
| 195 | | if(JConfig.scriptingEnabled() && |
| 196 | | JConfig.queryConfiguration("my.jbidwatcher.enabled", "false").equals("true") && |
| 197 | | JConfig.queryConfiguration("my.jbidwatcher.id") != null) { |
| 198 | | String recognize = (String)Scripting.rubyMethod("recognize_bidpage", inEntry, loadedPage); |
| 137 | if(JConfig.queryConfiguration("my.jbidwatcher.enabled", "false").equals("true") && |
| 138 | JConfig.queryConfiguration("my.jbidwatcher.id") != null) { |
| 139 | String recognize = MyJBidwatcher.getInstance().recognizeBidpage(inEntry.getIdentifier(), rval.getBuffer()); |
| 199 | 140 | Integer remote_result = null; |
| 200 | 141 | try { |
| 201 | 142 | remote_result = Integer.parseInt(recognize); |
| --- | --- | |
| 210 | 151 | } |
| 211 | 152 | |
| 212 | 153 | if(JConfig.debugging) inEntry.setLastStatus("Failed to bid. 'Show Last Error' from context menu to see the failure page from the bid attempt."); |
| 213 | | inEntry.setErrorPage(loadedPage); |
| 154 | inEntry.setErrorPage(rval.getBuffer()); |
| 214 | 155 | |
| 215 | 156 | // We don't recognize this error. Damn. Log it and freak. |
| 216 | | ErrorManagement.logFile(bidInfo, loadedPage); |
| 157 | ErrorManagement.logFile(bidInfo, rval.getBuffer()); |
| 217 | 158 | return null; |
| 218 | 159 | } |
| 219 | 160 | |
| 161 | private String checkForWarning(AuctionEntry inEntry, JHTML htmlDocument) throws UnsupportedEncodingException { |
| 162 | String pageName = null; |
| 163 | if (htmlDocument.grep(Externalized.getString("ebayServer.warningPage")) != null) { |
| 164 | JHTML.Form continueForm = htmlDocument.getFormWithInput("firedFilterId"); |
| 165 | if (continueForm != null) { |
| 166 | inEntry.setLastStatus("Trying to 'continue' for the actual bid."); |
| 167 | pageName = continueForm.getCGI(); |
| 168 | pageName = pageName.replaceFirst("%[A-F][A-F0-9]%A0", "%A0"); |
| 169 | } |
| 170 | } |
| 171 | return pageName; |
| 172 | } |
| 173 | |
| 174 | private String getBidInfoURL(AuctionEntry inEntry, Currency inCurr, int inQuant) { |
| 175 | String bidInfo = Externalized.getString("ebayServer.bidCmd") + "&co_partnerid=" + Externalized.getString("ebayServer.itemCGI") + inEntry.getIdentifier() + "&fb=2"; |
| 176 | if(inEntry.isDutch()) { |
| 177 | bidInfo += Externalized.getString("ebayServer.quantCGI") + inQuant; |
| 178 | } |
| 179 | bidInfo += Externalized.getString("ebayServer.bidCGI") + inCurr.getValue(); |
| 180 | return bidInfo; |
| 181 | } |
| 182 | |
| 183 | private CookieJar checkSignin(AuctionEntry inEntry, JHTML htmlDocument) { |
| 184 | String signOn = htmlDocument.getTitle(); |
| 185 | if (signOn != null) { |
| 186 | ErrorManagement.logDebug("Checking sign in as bid key load failed!"); |
| 187 | if (StringTools.startsWithIgnoreCase(signOn, "sign in")) { |
| 188 | // This means we somehow failed to keep the login in place. Bad news, in the middle of a snipe. |
| 189 | ErrorManagement.logDebug("Being prompted again for sign in, retrying."); |
| 190 | if(JConfig.debugging) inEntry.setLastStatus("Not done loading bid request, got re-login request..."); |
| 191 | CookieJar cj = mLogin.getSignInCookie(null); |
| 192 | if(JConfig.debugging) inEntry.setLastStatus("Done re-logging in, retrying load bid request."); |
| 193 | return cj; |
| 194 | } |
| 195 | } |
| 196 | return null; |
| 197 | } |
| 198 | |
| 199 | private class BidFormReturn { |
| 200 | private boolean mSuccess; |
| 201 | private JHTML.Form mForm; |
| 202 | private JHTML mDocument; |
| 203 | private StringBuffer mBuffer; |
| 204 | |
| 205 | public boolean isSuccess() { return mSuccess; } |
| 206 | public JHTML.Form getForm() { return mForm; } |
| 207 | public JHTML getDocument() { return mDocument; } |
| 208 | public StringBuffer getBuffer() { return mBuffer; } |
| 209 | |
| 210 | private BidFormReturn(boolean success, JHTML.Form form, JHTML document, StringBuffer buffer) { |
| 211 | mSuccess = success; |
| 212 | mForm = form; |
| 213 | mDocument = document; |
| 214 | mBuffer = buffer; |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | private BidFormReturn getBidFormInternal(String pageName, AuctionEntry inEntry, CookieJar cj) throws IOException { |
| 219 | URLConnection huc = cj.getAllCookiesFromPage(pageName, null, false); |
| 220 | StringBuffer loadedPage; |
| 221 | |
| 222 | // If we failed to load, punt. Treat it as success, but with a null form result. |
| 223 | if (huc == null || (loadedPage = Http.receivePage(huc)) == null) { |
| 224 | return new BidFormReturn(true, null, null, null); |
| 225 | } |
| 226 | |
| 227 | JHTML htmlDocument = new JHTML(loadedPage); |
| 228 | JHTML.Form bidForm = htmlDocument.getFormWithInput("key"); |
| 229 | |
| 230 | if (bidForm != null) { |
| 231 | if (JConfig.debugging) inEntry.setLastStatus("Done loading bid request, got form..."); |
| 232 | return new BidFormReturn(true, bidForm, htmlDocument, loadedPage); |
| 233 | } |
| 234 | return new BidFormReturn(false, null, htmlDocument, loadedPage); |
| 235 | } |
| 236 | |
| 237 | private void checkBidErrors(JHTML htmlDocument) throws BadBidException { |
| 238 | String errMsg = htmlDocument.grep(mBidResultRegex); |
| 239 | if(errMsg != null) { |
| 240 | Matcher bidMatch = mFindBidResult.matcher(errMsg); |
| 241 | bidMatch.find(); |
| 242 | String matched_error = bidMatch.group().toLowerCase(); |
| 243 | throw new BadBidException(matched_error, getMatchedResult(matched_error)); |
| 244 | } else { |
| 245 | String amount = htmlDocument.getNextContentAfterRegex("Enter"); |
| 246 | if (amount != null) { |
| 247 | String orMore = htmlDocument.getNextContent(); |
| 248 | if (orMore != null && orMore.indexOf("or more") != -1) { |
| 249 | throw new BadBidException("Enter " + amount + orMore, ebayServer.BID_ERROR_TOO_LOW); |
| 250 | } |
| 251 | } |
| 252 | } |
| 253 | } |
| 254 | |
| 255 | private void checkSignOn(JHTML htmlDocument) throws BadBidException { |
| 256 | String signOn = htmlDocument.getTitle(); |
| 257 | if(signOn != null && signOn.equalsIgnoreCase("Sign In")) throw new BadBidException("sign in", AuctionServerInterface.BID_ERROR_CANT_SIGN_IN); |
| 258 | } |
| 259 | |
| 220 | 260 | private Integer getMatchedResult(String matched_text) { |
| 221 | 261 | for (String regex : mResultHash.keySet()) { |
| 222 | 262 | String hacked = "(?msi).*" + regex.replace(" ", "\\s+") + ".*"; |