From 08d22a12fedcec1207aaa54187751c459711a2aa Mon Sep 17 00:00:00 2001 From: Rogiel Date: Tue, 17 Jan 2012 12:28:22 -0200 Subject: [PATCH] Implements CaptchaTrader service --- .../rogiel/httpchannel/captcha/Captcha.java | 42 ++- .../httpchannel/captcha/CaptchaResolver.java | 19 -- .../httpchannel/captcha/CaptchaService.java | 45 ++- .../httpchannel/captcha/ImageCaptcha.java | 66 ++++- .../captcha/ImageCaptchaService.java | 24 +- ...AuthenticationCaptchaServiceException.java | 49 ++++ .../exception/CaptchaServiceException.java | 50 ++++ .../InvalidCaptchaServiceException.java | 49 ++++ .../UnsolvableCaptchaServiceException.java | 49 ++++ .../httpchannel/service/AbstractService.java | 32 ++- .../httpchannel/service/Authenticator.java | 14 +- .../httpchannel/service/DownloadChannel.java | 9 - .../httpchannel/service/Downloader.java | 55 +++- .../httpchannel/service/HttpChannel.java | 23 ++ .../rogiel/httpchannel/service/Service.java | 11 +- .../httpchannel/service/UploadChannel.java | 10 - .../rogiel/httpchannel/service/Uploader.java | 15 +- .../exception/InvalidCaptchaException.java | 4 +- ...on.java => NoCaptchaServiceException.java} | 14 +- .../httpchannel-captcha-captchatrader/pom.xml | 49 ++++ .../java/com/captchatrader/CaptchaTrader.java | 207 ++++++++++++++ .../com/captchatrader/ResolvedCaptcha.java | 40 +++ .../ApplicationKeyDisabledException.java | 57 ++++ .../exception/CaptchaTraderException.java | 57 ++++ .../exception/ConnectionLimitException.java | 57 ++++ .../exception/DailyLimitException.java | 57 ++++ .../exception/ImageTooLargeException.java | 57 ++++ .../exception/IncorrectRespondsException.java | 57 ++++ .../InsuficientCreditsException.java | 57 ++++ .../exception/InternalErrorException.java | 57 ++++ .../InvalidApplicationKeyException.java | 57 ++++ .../exception/InvalidParametersException.java | 57 ++++ .../exception/InvalidTicketException.java | 57 ++++ .../exception/InvalidURLException.java | 57 ++++ .../exception/InvalidUserException.java | 57 ++++ .../exception/NotAnImageException.java | 57 ++++ .../exception/SubmissionErrorException.java | 57 ++++ .../exception/UserNotValidatedException.java | 57 ++++ .../captcha/impl/CaptchaTraderService.java | 117 ++++++++ .../com/captchatrader/CaptchaTraderTest.java | 42 +++ .../httpchannel-captcha-recaptcha/pom.xml | 24 -- .../captcha/impl/AjaxReCaptchaService.java | 36 --- .../captcha/impl/BaseReCaptchaService.java | 34 --- .../impl/EmbeddedReCaptchaService.java | 41 --- .../httpchannel/captcha/impl/ReCaptcha.java | 15 - .../impl/AjaxReCaptchaServiceTest.java | 25 -- httpchannel-captcha/pom.xml | 9 +- .../src/test/resources/.gitignore | 1 + .../httpchannel-service-depositfiles/pom.xml | 7 - .../service/impl/DepositFilesService.java | 29 +- .../httpchannel-service-filesonic/pom.xml | 13 + .../httpchannel/filesonic/FileSonicAPI.java | 56 ++++ .../httpchannel/filesonic/xml/FSAPI.java | 12 + .../filesonic/xml/FSGetUploadURL.java | 40 +++ .../httpchannel/filesonic/xml/FSResponse.java | 21 ++ .../httpchannel/filesonic/xml/FSUpload.java | 25 ++ .../service/impl/FileSonicService.java | 206 ++++++++++++++ .../com.rogiel.httpchannel.service.Service | 1 + .../service/impl/HotFileService.java | 49 +--- .../service/impl/MegaUploadService.java | 8 +- .../service/impl/MultiUploadService.java | 5 + .../httpchannel-service-uploadhere/pom.xml | 7 - .../service/impl/UploadHereService.java | 30 +- .../httpchannel-service-uploadking/pom.xml | 40 +-- .../service/impl/UploadKingService.java | 31 ++- .../service/impl/UploadKingServiceTest.java | 43 ++- .../httpchannel-service-zshare/pom.xml | 13 + .../service/impl/ZShareService.java | 262 ++++++++++++++++++ .../impl/ZShareUploaderConfiguration.java | 28 ++ .../com.rogiel.httpchannel.service.Service | 1 + .../src/test/resources/upload-test-file.txt | 3 + httpchannel-util/pom.xml | 7 - .../AbstractHTMLImageCaptchaService.java | 26 -- .../captcha/AbstractImageCaptcha.java | 47 ---- .../captcha/AbstractImageCaptchaService.java | 41 --- .../captcha/ReCaptchaExtractor.java | 58 ++++ .../service/AbstractHttpDownloader.java | 5 + .../service/AbstractHttpService.java | 1 + .../service/channel/LinkedUploadChannel.java | 6 + .../httpchannel/util/ExceptionUtils.java | 27 ++ pom.xml | 13 + 81 files changed, 2750 insertions(+), 543 deletions(-) delete mode 100644 httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/CaptchaResolver.java create mode 100644 httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/AuthenticationCaptchaServiceException.java create mode 100644 httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/CaptchaServiceException.java create mode 100644 httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/InvalidCaptchaServiceException.java create mode 100644 httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/UnsolvableCaptchaServiceException.java create mode 100644 httpchannel-api/src/main/java/com/rogiel/httpchannel/service/HttpChannel.java rename httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/{UnresolvedCaptchaException.java => NoCaptchaServiceException.java} (74%) create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/pom.xml create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/CaptchaTrader.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/ResolvedCaptcha.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ApplicationKeyDisabledException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/CaptchaTraderException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ConnectionLimitException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/DailyLimitException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ImageTooLargeException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/IncorrectRespondsException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InsuficientCreditsException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InternalErrorException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidApplicationKeyException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidParametersException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidTicketException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidURLException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidUserException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/NotAnImageException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/SubmissionErrorException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/UserNotValidatedException.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/rogiel/httpchannel/captcha/impl/CaptchaTraderService.java create mode 100644 httpchannel-captcha/httpchannel-captcha-captchatrader/src/test/java/com/captchatrader/CaptchaTraderTest.java delete mode 100644 httpchannel-captcha/httpchannel-captcha-recaptcha/pom.xml delete mode 100644 httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/AjaxReCaptchaService.java delete mode 100644 httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/BaseReCaptchaService.java delete mode 100644 httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/EmbeddedReCaptchaService.java delete mode 100644 httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/ReCaptcha.java delete mode 100644 httpchannel-captcha/httpchannel-captcha-recaptcha/src/test/java/com/rogiel/httpchannel/captcha/impl/AjaxReCaptchaServiceTest.java create mode 100644 httpchannel-captcha/src/test/resources/.gitignore create mode 100644 httpchannel-service/httpchannel-service-filesonic/pom.xml create mode 100644 httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/FileSonicAPI.java create mode 100644 httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSAPI.java create mode 100644 httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSGetUploadURL.java create mode 100644 httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSResponse.java create mode 100644 httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSUpload.java create mode 100644 httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/service/impl/FileSonicService.java create mode 100644 httpchannel-service/httpchannel-service-filesonic/src/main/resources/META-INF/services/com.rogiel.httpchannel.service.Service create mode 100644 httpchannel-service/httpchannel-service-zshare/pom.xml create mode 100644 httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareService.java create mode 100644 httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareUploaderConfiguration.java create mode 100644 httpchannel-service/httpchannel-service-zshare/src/main/resources/META-INF/services/com.rogiel.httpchannel.service.Service create mode 100644 httpchannel-service/httpchannel-service-zshare/src/test/resources/upload-test-file.txt delete mode 100644 httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractHTMLImageCaptchaService.java delete mode 100644 httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractImageCaptcha.java delete mode 100644 httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractImageCaptchaService.java create mode 100644 httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/ReCaptchaExtractor.java create mode 100644 httpchannel-util/src/main/java/com/rogiel/httpchannel/util/ExceptionUtils.java diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/Captcha.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/Captcha.java index 2ce6aa4..cb12d5a 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/Captcha.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/Captcha.java @@ -9,25 +9,45 @@ package com.rogiel.httpchannel.captcha; */ public interface Captcha { /** - * Sets the captcha answer - * + * @return the captcha ID + */ + String getID(); + + /** + * @return the resolved captcha answer + */ + String getAnswer(); + + /** * @param answer * the captcha answer */ void setAnswer(String answer); /** - * Returns the captcha answer. null if the service was not able - * to resolve it automatically. In such case, {@link #setAnswer(String)} - * must be used to set the correct answer. - * - * @return the captcha answer + * @return true if the captcha was resolved and + * {@link #getAnswer()} will not return null. */ - String getAnswer(); + boolean isResolved(); /** - * @return true if, and only if, the service was able to - * automatically resolve the captcha result + * Get this CAPTCHA's attachment. + *

+ * Important note: Attachments are for {@link CaptchaService} + * implementations usage! You should not touch any of the attachments! + * + * @return the attachment */ - boolean wasAutomaticallyResolved(); + Object getAttachment(); + + /** + * Sets this CAPTCHA's attachment. + *

+ * Important note: Attachments are for {@link CaptchaService} + * implementations usage! You should not touch any of the attachments! + * + * @param attachment + * the attachment + */ + void setAttachment(Object attachment); } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/CaptchaResolver.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/CaptchaResolver.java deleted file mode 100644 index 60141e4..0000000 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/CaptchaResolver.java +++ /dev/null @@ -1,19 +0,0 @@ -/** - * - */ -package com.rogiel.httpchannel.captcha; - -/** - * @author Rogiel - */ -public interface CaptchaResolver { - /** - * Tries to resolve the captcha - * - * @param captcha - * the captcha - * @return true if the captcha was resolve, false - * to abort - */ - boolean resolve(Captcha captcha); -} diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/CaptchaService.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/CaptchaService.java index 6ec0439..d9ff0ed 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/CaptchaService.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/CaptchaService.java @@ -3,9 +3,52 @@ */ package com.rogiel.httpchannel.captcha; +import com.rogiel.httpchannel.captcha.exception.AuthenticationCaptchaServiceException; +import com.rogiel.httpchannel.captcha.exception.InvalidCaptchaServiceException; +import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException; + /** * @author Rogiel - * */ public interface CaptchaService { + /** + * Authenticates the service instance into the CAPTCHA solving server, if + * any. Implementations that do not use authentication, should do nothing + * and return -1 + * + * @param username + * @param password + * @return amount of remaining CAPTCHA solving, -1 if no limit + * is applied + */ + int authenticate(String username, String password) + throws AuthenticationCaptchaServiceException; + + /** + * Tries to resolve the captcha and returns the correct answer. + * + * @param captcha + * @throws UnsolvableCaptchaServiceException + * if the CAPTCHA could not be solved by the service + */ + void solve(C captcha) throws UnsolvableCaptchaServiceException; + + /** + * Notifies the service that the given captcha answer was correct + * + * @param captcha + * the captcha + * @throws InvalidCaptchaServiceException + * normally thrown if the CAPTCHA was not solved by this service + */ + void valid(C captcha) throws InvalidCaptchaServiceException; + + /** + * Notifies the service that the given captcha answer was incorrect + * + * @param captcha + * @throws InvalidCaptchaServiceException + * normally thrown if the CAPTCHA was not solved by this service + */ + void invalid(C captcha) throws InvalidCaptchaServiceException; } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/ImageCaptcha.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/ImageCaptcha.java index 6094cdc..375e947 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/ImageCaptcha.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/ImageCaptcha.java @@ -9,14 +9,66 @@ import java.net.URL; * @author Rogiel * */ -public interface ImageCaptcha extends Captcha { +public class ImageCaptcha implements Captcha { /** - * @return the captcha identifier + * The CAPTCHA ID */ - String getID(); + private final String ID; + /** + * The CAPTCHA Image {@link URL} + */ + private final URL imageURL; + /** + * The CAPTCHA answer + */ + private String answer; + /** + * The CAPTCHA attachment + */ + private Object attachment; - /** - * @return the captcha image {@link URL} - */ - URL getImageURL(); + public ImageCaptcha(String id, URL imageURL) { + this.ID = id; + this.imageURL = imageURL; + } + + @Override + public String getID() { + return ID; + } + + public URL getImageURL() { + return imageURL; + } + + @Override + public String getAnswer() { + return answer; + } + + @Override + public void setAnswer(String answer) { + this.answer = answer; + } + + @Override + public boolean isResolved() { + return answer != null; + } + + @Override + public Object getAttachment() { + return attachment; + } + + @Override + public void setAttachment(Object attachment) { + this.attachment = attachment; + } + + @Override + public String toString() { + return "ImageCaptcha [ID=" + ID + ", imageURL=" + imageURL + + ", answer=" + answer + ", attachment=" + attachment + "]"; + } } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/ImageCaptchaService.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/ImageCaptchaService.java index 9c497cd..7f07051 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/ImageCaptchaService.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/ImageCaptchaService.java @@ -3,32 +3,10 @@ */ package com.rogiel.httpchannel.captcha; -import java.net.MalformedURLException; -import java.net.URL; - /** * @author Rogiel * */ -public interface ImageCaptchaService extends - CaptchaService { - /** - * Creates a new captcha from the given HTML content - * - * @param image - * the image {@link URL} - * @return a new captcha - * @throws MalformedURLException - * if any error occur while creating the Image {@link URL} - */ - C create(String html) throws MalformedURLException; +public interface ImageCaptchaService extends CaptchaService { - /** - * Tries to automatically resolve the captcha - * - * @param captcha - * the captcha to be resolved - * @return true if the captcha was successfully resolved - */ - boolean resolve(C captcha); } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/AuthenticationCaptchaServiceException.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/AuthenticationCaptchaServiceException.java new file mode 100644 index 0000000..6db3f76 --- /dev/null +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/AuthenticationCaptchaServiceException.java @@ -0,0 +1,49 @@ +/** + * + */ +package com.rogiel.httpchannel.captcha.exception; + + +/** + * @author Rogiel + * + */ +public class AuthenticationCaptchaServiceException extends CaptchaServiceException { + /** + * The Java Serialization API ID + */ + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance + */ + public AuthenticationCaptchaServiceException() { + } + + /** + * @param message + * the message + * @param cause + * the cause + */ + public AuthenticationCaptchaServiceException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + * the message + */ + public AuthenticationCaptchaServiceException(String message) { + super(message); + } + + /** + * @param cause + * the cause + */ + public AuthenticationCaptchaServiceException(Throwable cause) { + super(cause); + } + +} diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/CaptchaServiceException.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/CaptchaServiceException.java new file mode 100644 index 0000000..7b9a7ae --- /dev/null +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/CaptchaServiceException.java @@ -0,0 +1,50 @@ +/** + * + */ +package com.rogiel.httpchannel.captcha.exception; + +import com.rogiel.httpchannel.service.exception.ChannelServiceException; + +/** + * @author Rogiel + * + */ +public class CaptchaServiceException extends ChannelServiceException { + /** + * The Java Serialization API ID + */ + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance + */ + public CaptchaServiceException() { + } + + /** + * @param message + * the message + * @param cause + * the cause + */ + public CaptchaServiceException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + * the message + */ + public CaptchaServiceException(String message) { + super(message); + } + + /** + * @param cause + * the cause + */ + public CaptchaServiceException(Throwable cause) { + super(cause); + } + +} diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/InvalidCaptchaServiceException.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/InvalidCaptchaServiceException.java new file mode 100644 index 0000000..969e3f0 --- /dev/null +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/InvalidCaptchaServiceException.java @@ -0,0 +1,49 @@ +/** + * + */ +package com.rogiel.httpchannel.captcha.exception; + + +/** + * @author Rogiel + * + */ +public class InvalidCaptchaServiceException extends CaptchaServiceException { + /** + * The Java Serialization API ID + */ + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance + */ + public InvalidCaptchaServiceException() { + } + + /** + * @param message + * the message + * @param cause + * the cause + */ + public InvalidCaptchaServiceException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + * the message + */ + public InvalidCaptchaServiceException(String message) { + super(message); + } + + /** + * @param cause + * the cause + */ + public InvalidCaptchaServiceException(Throwable cause) { + super(cause); + } + +} diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/UnsolvableCaptchaServiceException.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/UnsolvableCaptchaServiceException.java new file mode 100644 index 0000000..7cba7d9 --- /dev/null +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/captcha/exception/UnsolvableCaptchaServiceException.java @@ -0,0 +1,49 @@ +/** + * + */ +package com.rogiel.httpchannel.captcha.exception; + + +/** + * @author Rogiel + * + */ +public class UnsolvableCaptchaServiceException extends CaptchaServiceException { + /** + * The Java Serialization API ID + */ + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance + */ + public UnsolvableCaptchaServiceException() { + } + + /** + * @param message + * the message + * @param cause + * the cause + */ + public UnsolvableCaptchaServiceException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param message + * the message + */ + public UnsolvableCaptchaServiceException(String message) { + super(message); + } + + /** + * @param cause + * the cause + */ + public UnsolvableCaptchaServiceException(Throwable cause) { + super(cause); + } + +} diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/AbstractService.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/AbstractService.java index 90dbdaf..348401c 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/AbstractService.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/AbstractService.java @@ -16,9 +16,13 @@ */ package com.rogiel.httpchannel.service; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.rogiel.httpchannel.captcha.Captcha; -import com.rogiel.httpchannel.captcha.CaptchaResolver; -import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException; +import com.rogiel.httpchannel.captcha.CaptchaService; +import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException; +import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException; /** * This is an abstract {@link Service} implementation. @@ -27,7 +31,11 @@ import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException; * @version 1.0 */ public abstract class AbstractService implements Service { - protected CaptchaResolver captchaResolver; + /** + * The service {@link Logger} instance + */ + protected final Logger logger = LoggerFactory.getLogger(this.getClass()); + protected CaptchaService captchaService; @Override public Service clone() { @@ -39,17 +47,17 @@ public abstract class AbstractService implements Service { } @Override - public void setCaptchaResolver(CaptchaResolver captchaResolver) { - this.captchaResolver = captchaResolver; + @SuppressWarnings("unchecked") + public void setCaptchaService( + CaptchaService captchaService) { + this.captchaService = (CaptchaService) captchaService; } protected void resolveCaptcha(Captcha captcha) - throws UnresolvedCaptchaException { - if (captchaResolver == null) - throw new UnresolvedCaptchaException(); - if (!captchaResolver.resolve(captcha)) - throw new UnresolvedCaptchaException(); - if (captcha.getAnswer() == null) - throw new UnresolvedCaptchaException(); + throws NoCaptchaServiceException, UnsolvableCaptchaServiceException { + if (captchaService == null) + throw new NoCaptchaServiceException( + "No CaptchaService is configured"); + captchaService.solve((Captcha) captcha); } } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Authenticator.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Authenticator.java index 4bf92c2..38ce16b 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Authenticator.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Authenticator.java @@ -18,10 +18,11 @@ package com.rogiel.httpchannel.service; import java.io.IOException; -import com.rogiel.httpchannel.captcha.CaptchaResolver; +import com.rogiel.httpchannel.captcha.CaptchaService; +import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException; import com.rogiel.httpchannel.service.Authenticator.AuthenticatorConfiguration; import com.rogiel.httpchannel.service.exception.AuthenticationInvalidCredentialException; -import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException; +import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException; /** * This interfaces provides authentication for an service. @@ -40,13 +41,16 @@ public interface Authenticator { * if any IO error occur * @throws AuthenticationInvalidCredentialException * if the credentials are not valid or cannot be used - * @throws UnresolvedCaptchaException + * @throws UnsolvableCaptchaServiceException * if the service required captcha resolving but no - * {@link CaptchaResolver} was available or the resolver did not + * {@link CaptchaService} was available or the service did not * solve the challenge + * @throws NoCaptchaServiceException + * if the service required an {@link CaptchaService} + * implementation to be present, but none was available */ void login() throws IOException, AuthenticationInvalidCredentialException, - UnresolvedCaptchaException; + UnsolvableCaptchaServiceException, NoCaptchaServiceException; /** * Logout into the {@link Service}. The session is restored to an not diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/DownloadChannel.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/DownloadChannel.java index f53112b..f3791a4 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/DownloadChannel.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/DownloadChannel.java @@ -32,13 +32,4 @@ import java.nio.channels.ReadableByteChannel; * @author Rogiel */ public interface DownloadChannel extends HttpChannel, ReadableByteChannel { - /** - * @return the file size - */ - long getFilesize(); - - /** - * @return the file name - */ - String getFilename(); } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Downloader.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Downloader.java index b701c41..457eaf6 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Downloader.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Downloader.java @@ -18,13 +18,14 @@ package com.rogiel.httpchannel.service; import java.io.IOException; -import com.rogiel.httpchannel.captcha.CaptchaResolver; +import com.rogiel.httpchannel.captcha.CaptchaService; +import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException; import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration; import com.rogiel.httpchannel.service.exception.DownloadLimitExceededException; import com.rogiel.httpchannel.service.exception.DownloadLinkNotFoundException; import com.rogiel.httpchannel.service.exception.DownloadNotAuthorizedException; import com.rogiel.httpchannel.service.exception.DownloadNotResumableException; -import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException; +import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException; /** * This interfaces provides downloading for an service. @@ -42,7 +43,8 @@ public interface Downloader { * very unlikely to be done. The most common usage usage scenario for this * is when an {@link DownloadNotResumableException} is thrown and you wish * to restart the download from start giving position equal to - * zero. + * zero, in such scenario, reutilizing the same {@link Downloader} instance + * is safe. *

* Please remember to close the channel by calling * {@link DownloadChannel#close()}, otherwise some of the resources (such as @@ -70,15 +72,19 @@ public interface Downloader { * @throws DownloadNotResumableException * if the download cannot be started at position. Will * only be thrown if position > 0. - * @throws UnresolvedCaptchaException + * @throws UnsolvableCaptchaServiceException * if the service required captcha resolving but no - * {@link CaptchaResolver} was available or the resolver did not + * {@link CaptchaService} was available or the service did not * solve the challenge + * @throws NoCaptchaServiceException + * if the service required an {@link CaptchaService} + * implementation to be present, but none was available */ DownloadChannel openChannel(DownloadListener listener, long position) throws IOException, DownloadLinkNotFoundException, DownloadLimitExceededException, DownloadNotAuthorizedException, - DownloadNotResumableException, UnresolvedCaptchaException; + DownloadNotResumableException, UnsolvableCaptchaServiceException, + NoCaptchaServiceException; /** * Opens a new {@link DownloadChannel} with not listener. For more details, @@ -102,14 +108,26 @@ public interface Downloader { * @throws DownloadNotResumableException * if the download cannot be started at position. Will * only be thrown if position > 0. + * @throws UnsolvableCaptchaServiceException + * if the service required captcha resolving but no + * {@link CaptchaService} was available or the service did not + * solve the challenge + * @throws NoCaptchaServiceException + * if the service required an {@link CaptchaService} + * implementation to be present, but none was available + * */ DownloadChannel openChannel(long position) throws IOException, DownloadLinkNotFoundException, DownloadLimitExceededException, - DownloadNotAuthorizedException, DownloadNotResumableException; + DownloadNotAuthorizedException, DownloadNotResumableException, + UnsolvableCaptchaServiceException, NoCaptchaServiceException; /** * Opens a new {@link DownloadChannel} positioned at start. For more * details, see {@link #openChannel(DownloadListener, long)} + *

+ * Note that {@link DownloadNotResumableException} is never thrown because + * this channel always starts at 0 offset. * * @param listener * the listener to keep a track on the download progress @@ -125,14 +143,25 @@ public interface Downloader { * @throws DownloadNotAuthorizedException * if the user (or guest) account does not have necessary rights * to download the file + * @throws UnsolvableCaptchaServiceException + * if the service required captcha resolving but no + * {@link CaptchaService} was available or the service did not + * solve the challenge + * @throws NoCaptchaServiceException + * if the service required an {@link CaptchaService} + * implementation to be present, but none was available */ DownloadChannel openChannel(DownloadListener listener) throws IOException, DownloadLinkNotFoundException, DownloadLimitExceededException, - DownloadNotAuthorizedException; + DownloadNotAuthorizedException, UnsolvableCaptchaServiceException, + NoCaptchaServiceException; /** * Opens a new {@link DownloadChannel} with not listener and positioned at * start. For more details, see {@link #openChannel(DownloadListener, long)} + *

+ * Note that {@link DownloadNotResumableException} is never thrown because + * this channel always starts at 0 offset. * * @return the {@link DownloadChannel} instance * @throws IOException @@ -146,10 +175,18 @@ public interface Downloader { * @throws DownloadNotAuthorizedException * if the user (or guest) account does not have necessary rights * to download the file + * @throws UnsolvableCaptchaServiceException + * if the service required captcha resolving but no + * {@link CaptchaService} was available or the service did not + * solve the challenge + * @throws NoCaptchaServiceException + * if the service required an {@link CaptchaService} + * implementation to be present, but none was available */ DownloadChannel openChannel() throws IOException, DownloadLinkNotFoundException, DownloadLimitExceededException, - DownloadNotAuthorizedException; + DownloadNotAuthorizedException, UnsolvableCaptchaServiceException, + NoCaptchaServiceException; /** * Returns this {@link Downloader} configuration. diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/HttpChannel.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/HttpChannel.java new file mode 100644 index 0000000..15e9c8e --- /dev/null +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/HttpChannel.java @@ -0,0 +1,23 @@ +/** + * + */ +package com.rogiel.httpchannel.service; + +import java.io.Closeable; +import java.nio.channels.Channel; + +/** + * @author Rogiel + * + */ +public interface HttpChannel extends Channel, Closeable { + /** + * @return the file size + */ + long getFilesize(); + + /** + * @return the file name + */ + String getFilename(); +} diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Service.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Service.java index ba652ed..986cea6 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Service.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Service.java @@ -16,7 +16,8 @@ */ package com.rogiel.httpchannel.service; -import com.rogiel.httpchannel.captcha.CaptchaResolver; +import com.rogiel.httpchannel.captcha.Captcha; +import com.rogiel.httpchannel.captcha.CaptchaService; /** * Base interface for all the services. Whenever the operation suported by the @@ -53,13 +54,13 @@ public interface Service extends Cloneable { int getMinorVersion(); /** - * Sets this service captcha resolver. Resolvers are safe to be switched + * Sets this service captcha service. CaptchaService are safe to be switched * even after an transfer has begun. * - * @param resolver - * the captcha resolver + * @param captchaService + * the captcha service */ - void setCaptchaResolver(CaptchaResolver resolver); + void setCaptchaService(CaptchaService captchaService); /** * @return a cloned version of this service diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/UploadChannel.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/UploadChannel.java index 193cc85..e3ec2d5 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/UploadChannel.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/UploadChannel.java @@ -36,16 +36,6 @@ import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException; * @author Rogiel */ public interface UploadChannel extends HttpChannel, WritableByteChannel { - /** - * @return the file size - */ - long getFilesize(); - - /** - * @return the file name - */ - String getFilename(); - /** * The link is located after you call {@link UploadChannel#close()}, but it * can only be retrieved by calling this method. If {@link #close()} throwed diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Uploader.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Uploader.java index 074c62e..56f5b01 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Uploader.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Uploader.java @@ -18,9 +18,10 @@ package com.rogiel.httpchannel.service; import java.io.IOException; -import com.rogiel.httpchannel.captcha.CaptchaResolver; +import com.rogiel.httpchannel.captcha.CaptchaService; +import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException; import com.rogiel.httpchannel.service.Uploader.UploaderConfiguration; -import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException; +import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException; /** * This interfaces provides uploading for an service. @@ -48,12 +49,16 @@ public interface Uploader { * @return the {@link UploadChannel} instance * @throws IOException * if any IO error occur - * @throws UnresolvedCaptchaException + * @throws UnsolvableCaptchaServiceException * if the service required captcha resolving but no - * {@link CaptchaResolver} was available or the resolver did not + * {@link CaptchaService} was available or the service did not * solve the challenge + * @throws NoCaptchaServiceException + * if the service required an {@link CaptchaService} + * implementation to be present, but none was available */ - UploadChannel openChannel() throws IOException, UnresolvedCaptchaException; + UploadChannel openChannel() throws IOException, + UnsolvableCaptchaServiceException, NoCaptchaServiceException; /** * Returns this {@link Uploader} configuration. diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/InvalidCaptchaException.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/InvalidCaptchaException.java index c3b227e..8d02ca0 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/InvalidCaptchaException.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/InvalidCaptchaException.java @@ -16,10 +16,10 @@ */ package com.rogiel.httpchannel.service.exception; -import com.rogiel.httpchannel.captcha.CaptchaResolver; +import com.rogiel.httpchannel.captcha.CaptchaService; /** - * Exception thrown if the {@link CaptchaResolver} has returned an invalid + * Exception thrown if the {@link CaptchaService} has returned an invalid * captcha * * @author Rogiel diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/UnresolvedCaptchaException.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/NoCaptchaServiceException.java similarity index 74% rename from httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/UnresolvedCaptchaException.java rename to httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/NoCaptchaServiceException.java index da86cf0..e18d912 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/UnresolvedCaptchaException.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/exception/NoCaptchaServiceException.java @@ -16,21 +16,21 @@ */ package com.rogiel.httpchannel.service.exception; -import com.rogiel.httpchannel.captcha.CaptchaResolver; +import com.rogiel.httpchannel.captcha.CaptchaService; /** - * Exception thrown if the {@link CaptchaResolver} has returned an invalid + * Exception thrown if the {@link CaptchaService} has returned an invalid * captcha * * @author Rogiel */ -public class UnresolvedCaptchaException extends ChannelServiceException { +public class NoCaptchaServiceException extends ChannelServiceException { private static final long serialVersionUID = 1L; /** * Creates a new empty instance of this exception */ - public UnresolvedCaptchaException() { + public NoCaptchaServiceException() { super(); } @@ -40,7 +40,7 @@ public class UnresolvedCaptchaException extends ChannelServiceException { * @param cause * the root cause */ - public UnresolvedCaptchaException(String message, Throwable cause) { + public NoCaptchaServiceException(String message, Throwable cause) { super(message, cause); } @@ -48,7 +48,7 @@ public class UnresolvedCaptchaException extends ChannelServiceException { * @param message * the message */ - public UnresolvedCaptchaException(String message) { + public NoCaptchaServiceException(String message) { super(message); } @@ -56,7 +56,7 @@ public class UnresolvedCaptchaException extends ChannelServiceException { * @param cause * the root cause */ - public UnresolvedCaptchaException(Throwable cause) { + public NoCaptchaServiceException(Throwable cause) { super(cause); } } diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/pom.xml b/httpchannel-captcha/httpchannel-captcha-captchatrader/pom.xml new file mode 100644 index 0000000..62ad5db --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/pom.xml @@ -0,0 +1,49 @@ + + 4.0.0 + + httpchannel-captcha + com.rogiel.httpchannel + 1.0.0 + .. + + com.rogiel.httpchannel.captcha + httpchannel-captcha-captchatrader + HttpChannel/Captcha/CaptchaTrader + This module provides an CaptchService that resolves image captchas. + + + + org.apache.httpcomponents + httpclient + 4.1.2 + jar + compile + + + commons-logging + commons-logging + + + + + org.apache.httpcomponents + httpmime + 4.1.2 + jar + compile + + + org.apache.commons + commons-io + 1.3.2 + jar + compile + + + com.googlecode.json-simple + json-simple + 1.1 + + + \ No newline at end of file diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/CaptchaTrader.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/CaptchaTrader.java new file mode 100644 index 0000000..0d78ce9 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/CaptchaTrader.java @@ -0,0 +1,207 @@ +/** + * + */ +package com.captchatrader; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; +import java.util.List; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.entity.mime.MultipartEntity; +import org.apache.http.entity.mime.content.StringBody; +import org.apache.http.impl.client.DefaultHttpClient; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.omg.CORBA.Any; + +import com.captchatrader.exception.ApplicationKeyDisabledException; +import com.captchatrader.exception.CaptchaTraderException; +import com.captchatrader.exception.ConnectionLimitException; +import com.captchatrader.exception.DailyLimitException; +import com.captchatrader.exception.ImageTooLargeException; +import com.captchatrader.exception.IncorrectRespondsException; +import com.captchatrader.exception.InsuficientCreditsException; +import com.captchatrader.exception.InternalErrorException; +import com.captchatrader.exception.InvalidApplicationKeyException; +import com.captchatrader.exception.InvalidParametersException; +import com.captchatrader.exception.InvalidTicketException; +import com.captchatrader.exception.InvalidURLException; +import com.captchatrader.exception.InvalidUserException; +import com.captchatrader.exception.NotAnImageException; +import com.captchatrader.exception.SubmissionErrorException; +import com.captchatrader.exception.UserNotValidatedException; + +/** + * @author Rogiel + * + */ +public class CaptchaTrader { + /** + * The {@link HttpClient} instance + */ + private final HttpClient client = new DefaultHttpClient(); + private final JSONParser json = new JSONParser(); + + private final URI apiURL; + private final String applicationKey; + private final String username; + private final String password; + + /** + * Creates a new API instance with the given application key + * + * @param applicationKey + * the key + */ + public CaptchaTrader(URI apiURL, String applicationKey, String username, + String password) { + this.apiURL = apiURL; + this.applicationKey = applicationKey; + this.username = username; + this.password = password; + } + + /** + * Creates a new API instance with the given application key + * + * @param applicationKey + * the key + * @throws MalformedURLException + */ + public CaptchaTrader(String applicationKey, String username, String password) { + this(URI.create("http://api.captchatrader.com/"), applicationKey, + username, password); + } + + /** + * Submit a CAPTCHA already hosted on an existing website. + * + * @param url + * The URL of the CAPTCHA image. + * @return The decoded CAPTCHA. + * @throws Any + * exceptions sent by the server. + */ + public ResolvedCaptcha submit(URL url) throws CaptchaTraderException, + IOException { + final URI requestUri = apiURL.resolve("submit"); + final HttpPost request = new HttpPost(requestUri); + final MultipartEntity entity = new MultipartEntity(); + + entity.addPart("api_key", new StringBody(applicationKey)); + entity.addPart("username", new StringBody(username)); + entity.addPart("password", new StringBody(password)); + entity.addPart("value", new StringBody(url.toString())); + + request.setEntity(entity); + final List response = validate(execute(request)); + + return new ResolvedCaptcha(this, ((Long) response.get(0)).intValue(), + (String) response.get(1)); + } + + /** + * Responds if an CAPTCHA wes correctly answered or not + * + * @param captcha + * the CAPTCHA object + * @param state + * true if the CAPTCHA was correctly resolved + * @throws CaptchaTraderException + * any of the possible errors + */ + public void response(ResolvedCaptcha captcha, boolean state) + throws CaptchaTraderException, IOException { + final URI requestUri = apiURL.resolve("respond"); + final HttpPost request = new HttpPost(requestUri); + final MultipartEntity entity = new MultipartEntity(); + + entity.addPart("is_correct", new StringBody(state ? "1" : "0")); + entity.addPart("username", new StringBody(username)); + entity.addPart("password", new StringBody(password)); + entity.addPart("ticket", + new StringBody(Integer.toString(captcha.getID()))); + + request.setEntity(entity); + validate(execute(request)); + } + + /** + * Checks the amount of resolutions available on a users account + * + * @return The decoded CAPTCHA. + * @throws Any + * exceptions sent by the server. + */ + public int getCredits() throws CaptchaTraderException, IOException { + return ((Number) validate( + execute(new HttpGet(apiURL.resolve("get_credits/username:" + + username + "/password:" + password + "/")))).get(1)) + .intValue(); + } + + private List validate(List response) + throws CaptchaTraderException { + if ((long) response.get(0) == -1) { + throw translateException((String) response.get(1)); + } + return response; + } + + @SuppressWarnings("unchecked") + private List execute(HttpUriRequest request) throws IOException { + final HttpResponse response = client.execute(request); + try { + return (List) json.parse(new InputStreamReader(response + .getEntity().getContent())); + } catch (IllegalStateException | ParseException e) { + throw new IOException(e); + } + } + + private CaptchaTraderException translateException(String error) { + switch (error) { + case "API KEY DISABLED": + return new ApplicationKeyDisabledException(); + case " CONNECTION LIMIT": + return new ConnectionLimitException(); + case "DAILY LIMIT": + return new DailyLimitException(); + case "IMAGE TOO LARGE": + return new ImageTooLargeException(); + case "INSUFFICIENT CREDITS": + return new InsuficientCreditsException(); + case "INTERNAL ERROR": + return new InternalErrorException(); + case "INVALID API KEY": + return new InvalidApplicationKeyException(); + case "INVALID PARAMETERS": + return new InvalidParametersException(); + case "INVALID URL": + return new InvalidURLException(); + case "INVALID USER": + return new InvalidUserException(); + case "USER NOT VALIDATED": + return new UserNotValidatedException(); + case "NOT AN IMAGE": + return new NotAnImageException(); + case "SUBMISSION ERROR": + return new SubmissionErrorException(); + case "INCORRECT REPORTS": + return new IncorrectRespondsException(); + case "INVALID TICKET": + return new InvalidTicketException(); + default: + return new CaptchaTraderException(error); + } + + } +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/ResolvedCaptcha.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/ResolvedCaptcha.java new file mode 100644 index 0000000..02a9472 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/ResolvedCaptcha.java @@ -0,0 +1,40 @@ +/** + * + */ +package com.captchatrader; + +import java.io.IOException; + +import com.captchatrader.exception.CaptchaTraderException; + +/** + * @author Rogiel + * + */ +public class ResolvedCaptcha { + private final CaptchaTrader api; + private final int id; + private final String answer; + + public ResolvedCaptcha(CaptchaTrader api, int id, String answer) { + this.api = api; + this.id = id; + this.answer = answer; + } + + public int getID() { + return id; + } + + public String getAnswer() { + return answer; + } + + public void valid() throws CaptchaTraderException, IOException { + api.response(this, true); + } + + public void invalid() throws CaptchaTraderException, IOException { + api.response(this, true); + } +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ApplicationKeyDisabledException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ApplicationKeyDisabledException.java new file mode 100644 index 0000000..246e941 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ApplicationKeyDisabledException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class ApplicationKeyDisabledException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public ApplicationKeyDisabledException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public ApplicationKeyDisabledException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public ApplicationKeyDisabledException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public ApplicationKeyDisabledException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public ApplicationKeyDisabledException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/CaptchaTraderException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/CaptchaTraderException.java new file mode 100644 index 0000000..6e5cd02 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/CaptchaTraderException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class CaptchaTraderException extends Exception { + private static final long serialVersionUID = 1L; + + /** + * + */ + public CaptchaTraderException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public CaptchaTraderException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public CaptchaTraderException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public CaptchaTraderException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public CaptchaTraderException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ConnectionLimitException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ConnectionLimitException.java new file mode 100644 index 0000000..e65c363 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ConnectionLimitException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class ConnectionLimitException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public ConnectionLimitException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public ConnectionLimitException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public ConnectionLimitException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public ConnectionLimitException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public ConnectionLimitException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/DailyLimitException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/DailyLimitException.java new file mode 100644 index 0000000..9553405 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/DailyLimitException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class DailyLimitException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public DailyLimitException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public DailyLimitException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public DailyLimitException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public DailyLimitException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public DailyLimitException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ImageTooLargeException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ImageTooLargeException.java new file mode 100644 index 0000000..7a75cb3 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/ImageTooLargeException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class ImageTooLargeException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public ImageTooLargeException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public ImageTooLargeException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public ImageTooLargeException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public ImageTooLargeException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public ImageTooLargeException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/IncorrectRespondsException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/IncorrectRespondsException.java new file mode 100644 index 0000000..3137ea3 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/IncorrectRespondsException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class IncorrectRespondsException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public IncorrectRespondsException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public IncorrectRespondsException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public IncorrectRespondsException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public IncorrectRespondsException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public IncorrectRespondsException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InsuficientCreditsException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InsuficientCreditsException.java new file mode 100644 index 0000000..1c46d2b --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InsuficientCreditsException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class InsuficientCreditsException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public InsuficientCreditsException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public InsuficientCreditsException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public InsuficientCreditsException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public InsuficientCreditsException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public InsuficientCreditsException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InternalErrorException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InternalErrorException.java new file mode 100644 index 0000000..4ca1341 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InternalErrorException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class InternalErrorException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public InternalErrorException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public InternalErrorException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public InternalErrorException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public InternalErrorException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public InternalErrorException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidApplicationKeyException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidApplicationKeyException.java new file mode 100644 index 0000000..60f25c6 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidApplicationKeyException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class InvalidApplicationKeyException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public InvalidApplicationKeyException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public InvalidApplicationKeyException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public InvalidApplicationKeyException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public InvalidApplicationKeyException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public InvalidApplicationKeyException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidParametersException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidParametersException.java new file mode 100644 index 0000000..8d089ec --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidParametersException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class InvalidParametersException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public InvalidParametersException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public InvalidParametersException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public InvalidParametersException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public InvalidParametersException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public InvalidParametersException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidTicketException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidTicketException.java new file mode 100644 index 0000000..cc4a46b --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidTicketException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class InvalidTicketException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public InvalidTicketException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public InvalidTicketException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public InvalidTicketException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public InvalidTicketException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public InvalidTicketException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidURLException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidURLException.java new file mode 100644 index 0000000..7ab4906 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidURLException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class InvalidURLException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public InvalidURLException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public InvalidURLException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public InvalidURLException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public InvalidURLException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public InvalidURLException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidUserException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidUserException.java new file mode 100644 index 0000000..76258c3 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/InvalidUserException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class InvalidUserException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public InvalidUserException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public InvalidUserException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public InvalidUserException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public InvalidUserException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public InvalidUserException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/NotAnImageException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/NotAnImageException.java new file mode 100644 index 0000000..ac7574a --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/NotAnImageException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class NotAnImageException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public NotAnImageException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public NotAnImageException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public NotAnImageException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public NotAnImageException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public NotAnImageException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/SubmissionErrorException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/SubmissionErrorException.java new file mode 100644 index 0000000..8860786 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/SubmissionErrorException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class SubmissionErrorException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public SubmissionErrorException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public SubmissionErrorException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public SubmissionErrorException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public SubmissionErrorException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public SubmissionErrorException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/UserNotValidatedException.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/UserNotValidatedException.java new file mode 100644 index 0000000..9649e4d --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/captchatrader/exception/UserNotValidatedException.java @@ -0,0 +1,57 @@ +/** + * + */ +package com.captchatrader.exception; + +/** + * @author Rogiel + * + */ +public class UserNotValidatedException extends CaptchaTraderException { + private static final long serialVersionUID = 1L; + + /** + * + */ + public UserNotValidatedException() { + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public UserNotValidatedException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public UserNotValidatedException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public UserNotValidatedException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + * @param enableSuppression + * @param writableStackTrace + */ + public UserNotValidatedException(String message, Throwable cause, + boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + // TODO Auto-generated constructor stub + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/rogiel/httpchannel/captcha/impl/CaptchaTraderService.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/rogiel/httpchannel/captcha/impl/CaptchaTraderService.java new file mode 100644 index 0000000..4a5da63 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/main/java/com/rogiel/httpchannel/captcha/impl/CaptchaTraderService.java @@ -0,0 +1,117 @@ +/** + * + */ +package com.rogiel.httpchannel.captcha.impl; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.captchatrader.CaptchaTrader; +import com.captchatrader.ResolvedCaptcha; +import com.captchatrader.exception.CaptchaTraderException; +import com.rogiel.httpchannel.captcha.ImageCaptcha; +import com.rogiel.httpchannel.captcha.ImageCaptchaService; +import com.rogiel.httpchannel.captcha.exception.AuthenticationCaptchaServiceException; +import com.rogiel.httpchannel.captcha.exception.InvalidCaptchaServiceException; +import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException; + +/** + * Implements CAPTCHA solving using CaptchaTrader.com service. If + * username-password authentication is not desired, send the API key as username + * and null password. + * + * @author Rogiel + */ +public class CaptchaTraderService implements ImageCaptchaService { + private static final Logger logger = LoggerFactory + .getLogger(CaptchaTraderService.class); + private static final String APP_KEY = "2acc44805ec208cc4d6b00c75a414996"; + + /** + * The current application key to be used + */ + private String currentApplicationKey = APP_KEY; + + /** + * The CaptchaTrader.com API object + */ + private CaptchaTrader api; + + @Override + public int authenticate(String username, String password) + throws AuthenticationCaptchaServiceException { + api = new CaptchaTrader(currentApplicationKey, username, password); + logger.debug("Authenticating into CaptchaTrader"); + try { + // this will validate the account + return (int) Math.ceil(((double) api.getCredits()) / 10); + } catch (IOException | CaptchaTraderException e) { + throw new AuthenticationCaptchaServiceException(e); + } + } + + @Override + public void solve(ImageCaptcha captcha) + throws UnsolvableCaptchaServiceException { + try { + logger.debug("Resolving CAPTCHA {}", captcha.getImageURL()); + final ResolvedCaptcha resolved = api.submit(captcha.getImageURL()); + captcha.setAnswer(resolved.getAnswer()); + captcha.setAttachment(resolved); + logger.debug("CAPTCHA solved, answer is \"{}\"", + resolved.getAnswer()); + } catch (IOException | CaptchaTraderException e) { + throw new UnsolvableCaptchaServiceException(e); + } + } + + @Override + public void valid(ImageCaptcha captcha) + throws InvalidCaptchaServiceException { + final Object attachment = captcha.getAttachment(); + if (attachment instanceof ResolvedCaptcha) { + try { + logger.debug("Notifying server that CAPTCHA {} is valid", + captcha); + ((ResolvedCaptcha) attachment).valid(); + } catch (CaptchaTraderException | IOException e) { + throw new InvalidCaptchaServiceException(e); + } + } else { + throw new InvalidCaptchaServiceException(); + } + } + + @Override + public void invalid(ImageCaptcha captcha) + throws InvalidCaptchaServiceException { + final Object attachment = captcha.getAttachment(); + if (attachment instanceof ResolvedCaptcha) { + try { + logger.debug("Notifying server that CAPTCHA {} is invalid", + captcha); + ((ResolvedCaptcha) attachment).invalid(); + } catch (CaptchaTraderException | IOException e) { + throw new InvalidCaptchaServiceException(e); + } + } else { + throw new InvalidCaptchaServiceException(); + } + } + + /** + * Sets the CaptchaTrader API key. Each application should provide a key, + * otherwise the default "HttpChannel" key will be used. + * + * @param key + * the application key + */ + public void setApplicationKey(String key) { + if (key == null) + key = APP_KEY; + logger.debug("Setting new application key as {}", key); + currentApplicationKey = key; + } +} diff --git a/httpchannel-captcha/httpchannel-captcha-captchatrader/src/test/java/com/captchatrader/CaptchaTraderTest.java b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/test/java/com/captchatrader/CaptchaTraderTest.java new file mode 100644 index 0000000..de42b39 --- /dev/null +++ b/httpchannel-captcha/httpchannel-captcha-captchatrader/src/test/java/com/captchatrader/CaptchaTraderTest.java @@ -0,0 +1,42 @@ +/** + * + */ +package com.captchatrader; + +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Properties; + +import org.junit.Test; + +/** + * @author Rogiel + * + */ +public class CaptchaTraderTest { + /** + * Test method for + * {@link com.captchatrader.old.CaptchaTrader#respond(boolean)}. + * + * @throws Exception + */ + @Test + public void testRespond() throws Exception { + final Properties p = new Properties(); + p.load(Files.newInputStream( + Paths.get("../../httpchannel-captcha/src/test/resources/captchatrader.properties"), + StandardOpenOption.READ)); + + final CaptchaTrader api = new CaptchaTrader( + "2acc44805ec208cc4d6b00c75a414996", p.getProperty("username"), + p.getProperty("password")); + final ResolvedCaptcha resolved = api + .submit(new URL( + "http://www.google.com/recaptcha/api/image?c=03AHJ_VusNSxAzZgs9OEvH79rOWOFDYXE2ElE5qkCr9kFU-ZU7gqy72tqEL3j_qCLYwdXgh4jaxU1iECISuUwt0zHbelni-lq8c7RVGSjUtJiMyHwlTTsG5CxWKIEus--yy3GPvwaW9l4N7hFnT57lLq272EOxcFDGYA")); + System.out.println(resolved); + resolved.valid(); + } + +} diff --git a/httpchannel-captcha/httpchannel-captcha-recaptcha/pom.xml b/httpchannel-captcha/httpchannel-captcha-recaptcha/pom.xml deleted file mode 100644 index 9e4a4ac..0000000 --- a/httpchannel-captcha/httpchannel-captcha-recaptcha/pom.xml +++ /dev/null @@ -1,24 +0,0 @@ - - 4.0.0 - - httpchannel-capcha - com.rogiel.httpchannel - 1.0.0 - .. - - httpchannel-captcha-recaptcha - HttpChannel/CaptchaService/ReCaptcha - This module provides captcha resolving for Google ReCaptcha - - - com.rogiel.httpchannel - httpchannel-api - 1.0.0 - - - com.rogiel.httpchannel - httpchannel-util - 1.0.0 - - - \ No newline at end of file diff --git a/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/AjaxReCaptchaService.java b/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/AjaxReCaptchaService.java deleted file mode 100644 index 5716ebf..0000000 --- a/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/AjaxReCaptchaService.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * - */ -package com.rogiel.httpchannel.captcha.impl; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.util.regex.Pattern; - -import com.rogiel.httpchannel.util.PatternUtils; - -/** - * @author Rogiel - */ -public class AjaxReCaptchaService extends BaseReCaptchaService { - private static final Pattern CAPTCHA_URL_PATTERN = Pattern - .compile("Recaptcha\\.create\\(\"([0-9A-z|_|\\-]*)\", "); - private static final String BASE_URL = "http://www.google.com/recaptcha/api/challenge?ajax=1&k="; - - @Override - public ReCaptcha create(String content) throws MalformedURLException { - final String siteID = PatternUtils - .find(CAPTCHA_URL_PATTERN, content, 1); - try { - return super.create(get(BASE_URL + siteID).asString()); - } catch (IOException e) { - return null; - } - } - - @Override - public boolean resolve(ReCaptcha captcha) { - // not supported! - return false; - } -} diff --git a/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/BaseReCaptchaService.java b/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/BaseReCaptchaService.java deleted file mode 100644 index a90081a..0000000 --- a/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/BaseReCaptchaService.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * - */ -package com.rogiel.httpchannel.captcha.impl; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.regex.Pattern; - -import com.rogiel.httpchannel.captcha.AbstractImageCaptchaService; -import com.rogiel.httpchannel.util.PatternUtils; - -/** - * @author Rogiel - * - */ -public class BaseReCaptchaService extends - AbstractImageCaptchaService { - private static final Pattern CAPTCHA_IMAGE_PATTERN = Pattern - .compile("challenge : '(.*)'"); - private static final String BASE_URL = "http://www.google.com/recaptcha/api/image?c="; - - @Override - public ReCaptcha create(String content) throws MalformedURLException { - final String id = PatternUtils.find(CAPTCHA_IMAGE_PATTERN, content, 1); - return new ReCaptcha(new URL(BASE_URL + id), id); - } - - @Override - public boolean resolve(ReCaptcha captcha) { - // not supported! - return false; - } -} diff --git a/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/EmbeddedReCaptchaService.java b/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/EmbeddedReCaptchaService.java deleted file mode 100644 index ae320e3..0000000 --- a/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/EmbeddedReCaptchaService.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * - */ -package com.rogiel.httpchannel.captcha.impl; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.util.regex.Pattern; - -import com.rogiel.httpchannel.util.htmlparser.HTMLPage; - -/** - * @author Rogiel - * - */ -public class EmbeddedReCaptchaService extends BaseReCaptchaService { - private static final Pattern CAPTCHA_URL_PATTERN = Pattern - .compile("http://www\\.google\\.com/recaptcha/api/challenge\\?k=([0-9A-z|\\-]*)(&(.*))?"); - - @Override - public ReCaptcha create(String content) throws MalformedURLException { - try { - return create(HTMLPage.parse(content)); - } catch (IOException e) { - return null; - } - } - - public ReCaptcha create(HTMLPage page) throws IOException { - final String url = page.findScriptSrc(CAPTCHA_URL_PATTERN); - if (url == null) - return null; - return super.create(get(url).asString()); - } - - @Override - public boolean resolve(ReCaptcha captcha) { - // not supported! - return false; - } -} diff --git a/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/ReCaptcha.java b/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/ReCaptcha.java deleted file mode 100644 index 6d3f277..0000000 --- a/httpchannel-captcha/httpchannel-captcha-recaptcha/src/main/java/com/rogiel/httpchannel/captcha/impl/ReCaptcha.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.rogiel.httpchannel.captcha.impl; - -import java.net.URL; - -import com.rogiel.httpchannel.captcha.AbstractImageCaptcha; - -/** - * @author Rogiel - * - */ -public class ReCaptcha extends AbstractImageCaptcha { - public ReCaptcha(URL url, String ID) { - super(url, ID); - } -} diff --git a/httpchannel-captcha/httpchannel-captcha-recaptcha/src/test/java/com/rogiel/httpchannel/captcha/impl/AjaxReCaptchaServiceTest.java b/httpchannel-captcha/httpchannel-captcha-recaptcha/src/test/java/com/rogiel/httpchannel/captcha/impl/AjaxReCaptchaServiceTest.java deleted file mode 100644 index 81c0708..0000000 --- a/httpchannel-captcha/httpchannel-captcha-recaptcha/src/test/java/com/rogiel/httpchannel/captcha/impl/AjaxReCaptchaServiceTest.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * - */ -package com.rogiel.httpchannel.captcha.impl; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; - -import org.apache.commons.io.IOUtils; -import org.junit.Test; - -/** - * @author Rogiel - * - */ -public class AjaxReCaptchaServiceTest { - @Test - public void test() throws MalformedURLException, IOException { - final String content = IOUtils.toString(new URL( - "http://www.uploadking.com/WM3PHD9JAY").openStream()); - final AjaxReCaptchaService ajax = new AjaxReCaptchaService(); - ajax.create(content); - } -} diff --git a/httpchannel-captcha/pom.xml b/httpchannel-captcha/pom.xml index 043f161..f3241ed 100644 --- a/httpchannel-captcha/pom.xml +++ b/httpchannel-captcha/pom.xml @@ -14,6 +14,13 @@ This module provides implementations for captcha resolving - httpchannel-captcha-recaptcha + httpchannel-captcha-captchatrader + + + com.rogiel.httpchannel + httpchannel-api + 1.0.0 + + \ No newline at end of file diff --git a/httpchannel-captcha/src/test/resources/.gitignore b/httpchannel-captcha/src/test/resources/.gitignore new file mode 100644 index 0000000..dd92308 --- /dev/null +++ b/httpchannel-captcha/src/test/resources/.gitignore @@ -0,0 +1 @@ +/captchatrader.properties diff --git a/httpchannel-service/httpchannel-service-depositfiles/pom.xml b/httpchannel-service/httpchannel-service-depositfiles/pom.xml index ba72efa..43525c6 100644 --- a/httpchannel-service/httpchannel-service-depositfiles/pom.xml +++ b/httpchannel-service/httpchannel-service-depositfiles/pom.xml @@ -10,11 +10,4 @@ com.rogiel.httpchannel.services HttpChannel/Service/DepositFiles Provides upload access to depositfiles.com - - - com.rogiel.httpchannel - httpchannel-captcha-recaptcha - 1.0.0 - - \ No newline at end of file diff --git a/httpchannel-service/httpchannel-service-depositfiles/src/main/java/com/rogiel/httpchannel/service/impl/DepositFilesService.java b/httpchannel-service/httpchannel-service-depositfiles/src/main/java/com/rogiel/httpchannel/service/impl/DepositFilesService.java index 95a207f..1ea57e3 100644 --- a/httpchannel-service/httpchannel-service-depositfiles/src/main/java/com/rogiel/httpchannel/service/impl/DepositFilesService.java +++ b/httpchannel-service/httpchannel-service-depositfiles/src/main/java/com/rogiel/httpchannel/service/impl/DepositFilesService.java @@ -5,8 +5,9 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.regex.Pattern; -import com.rogiel.httpchannel.captcha.impl.EmbeddedReCaptchaService; -import com.rogiel.httpchannel.captcha.impl.ReCaptcha; +import com.rogiel.httpchannel.captcha.ImageCaptcha; +import com.rogiel.httpchannel.captcha.ReCaptchaExtractor; +import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException; import com.rogiel.httpchannel.service.AbstractAuthenticator; import com.rogiel.httpchannel.service.AbstractHttpService; import com.rogiel.httpchannel.service.AbstractUploader; @@ -50,8 +51,6 @@ public class DepositFilesService extends AbstractHttpService implements private static final Pattern VALID_LOGIN_REDIRECT = Pattern .compile("window.location.href"); - private final EmbeddedReCaptchaService captchaService = new EmbeddedReCaptchaService(); - @Override public ServiceID getID() { return SERVICE_ID; @@ -137,12 +136,15 @@ public class DepositFilesService extends AbstractHttpService implements @Override public UploadChannel openChannel() throws IOException { + logger.debug("Starting upload to depositfiles.com"); final HTMLPage page = get("http://www.depositfiles.com/").asPage(); final String url = page.findFormAction(UPLOAD_URL_PATTERN); final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER"); final String maxFileSize = page.getInputValue("MAX_FILE_SIZE"); + logger.debug("Upload URL: {}, ID: {}", url, uploadID); + final LinkedUploadChannel channel = createLinkedChannel(this); uploadFuture = multipartPost(url).parameter("files", channel) .parameter("go", true) @@ -178,13 +180,16 @@ public class DepositFilesService extends AbstractHttpService implements @Override public void login() throws IOException { + logger.debug("Authenticating into depositfiles.com"); HTMLPage page = post("http://depositfiles.com/login.php?return=%2F") .parameter("go", true) .parameter("login", credential.getUsername()) .parameter("password", credential.getPassword()).asPage(); - final ReCaptcha captcha = captchaService.create(page); + final ImageCaptcha captcha = ReCaptchaExtractor.extractCaptcha( + page, http); if (captcha != null) { + logger.debug("Service is requiring CAPTCHA {}", captcha); resolveCaptcha(captcha); page = post("http://depositfiles.com/login.php?return=%2F") .parameter("go", true) @@ -195,9 +200,17 @@ public class DepositFilesService extends AbstractHttpService implements captcha.getAnswer()).asPage(); } - if (!page.contains(VALID_LOGIN_REDIRECT)) - throw new AuthenticationInvalidCredentialException(); - return; + final ImageCaptcha testCaptcha = ReCaptchaExtractor.extractCaptcha( + page, http); + if (testCaptcha != null) { + captchaService.invalid(captcha); + throw new UnsolvableCaptchaServiceException(); + } else { + captchaService.valid(captcha); + if (!page.contains(VALID_LOGIN_REDIRECT)) + throw new AuthenticationInvalidCredentialException(); + return; + } } @Override diff --git a/httpchannel-service/httpchannel-service-filesonic/pom.xml b/httpchannel-service/httpchannel-service-filesonic/pom.xml new file mode 100644 index 0000000..2846625 --- /dev/null +++ b/httpchannel-service/httpchannel-service-filesonic/pom.xml @@ -0,0 +1,13 @@ + + 4.0.0 + + httpchannel-service + com.rogiel.httpchannel + 1.0.0 + .. + + httpchannel-service-filesonic + com.rogiel.httpchannel.services + HttpChannel/Service/FileSonic + Provides download and upload access to filesonic.com + \ No newline at end of file diff --git a/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/FileSonicAPI.java b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/FileSonicAPI.java new file mode 100644 index 0000000..4776d18 --- /dev/null +++ b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/FileSonicAPI.java @@ -0,0 +1,56 @@ +/** + * + */ +package com.rogiel.httpchannel.filesonic; + +import java.io.IOException; +import java.net.URL; + +import javax.xml.bind.JAXB; + +import com.rogiel.httpchannel.filesonic.xml.FSAPI; +import com.rogiel.httpchannel.filesonic.xml.FSGetUploadURL; +import com.rogiel.httpchannel.filesonic.xml.FSUpload; + +/** + * @author Rogiel + */ +public class FileSonicAPI { + private static final String BASE_URL = "http://api.filesonic.com/"; + + private String email; + private String password; + + public Object getInfo(int id) { + return id; + } + + public URL getUploadURL() throws IOException { + return new URL(((FSGetUploadURL) execute(FSUpload.class, + "upload?method=getUploadUrl").getResponse()).getResponse() + .getUploadURL()); + } + + public long getMaxFilesize() throws IOException { + return ((FSGetUploadURL) execute(FSUpload.class, + "upload?method=getUploadUrl").getResponse()).getResponse() + .getMaxFilesize(); + } + + public void login(String email, String password) { + this.email = email; + this.password = password; + } + + public void logout() { + this.email = null; + this.password = null; + } + + private T execute(Class type, String requestURL) + throws IOException { + final URL url = new URL(BASE_URL + requestURL + "&u=" + email + "&p=" + + password + "&format=xml"); + return JAXB.unmarshal(url.openStream(), type); + } +} diff --git a/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSAPI.java b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSAPI.java new file mode 100644 index 0000000..1e3281c --- /dev/null +++ b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSAPI.java @@ -0,0 +1,12 @@ +/** + * + */ +package com.rogiel.httpchannel.filesonic.xml; + +/** + * @author Rogiel + * + */ +public class FSAPI { + +} diff --git a/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSGetUploadURL.java b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSGetUploadURL.java new file mode 100644 index 0000000..e9a29ea --- /dev/null +++ b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSGetUploadURL.java @@ -0,0 +1,40 @@ +/** + * + */ +package com.rogiel.httpchannel.filesonic.xml; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Rogiel + * + */ +@XmlRootElement(name = "getUploadUrl") +@XmlAccessorType(XmlAccessType.NONE) +public class FSGetUploadURL extends FSResponse { + @XmlElement(name = "response") + private FSGetUploadURLResponse response; + + @XmlAccessorType(XmlAccessType.NONE) + public static class FSGetUploadURLResponse { + @XmlElement(name = "url") + private String uploadURL; + @XmlElement(name = "max-filesize") + private long maxFilesize; + + public String getUploadURL() { + return uploadURL; + } + + public long getMaxFilesize() { + return maxFilesize; + } + } + + public FSGetUploadURLResponse getResponse() { + return response; + } +} diff --git a/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSResponse.java b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSResponse.java new file mode 100644 index 0000000..e0373d4 --- /dev/null +++ b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSResponse.java @@ -0,0 +1,21 @@ +/** + * + */ +package com.rogiel.httpchannel.filesonic.xml; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; + +/** + * @author Rogiel + */ +@XmlAccessorType(XmlAccessType.NONE) +public abstract class FSResponse { + @XmlElement(name = "status") + private String status; + + public String getStatus() { + return status; + } +} diff --git a/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSUpload.java b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSUpload.java new file mode 100644 index 0000000..4be12ce --- /dev/null +++ b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/filesonic/xml/FSUpload.java @@ -0,0 +1,25 @@ +/** + * + */ +package com.rogiel.httpchannel.filesonic.xml; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Rogiel + * + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "FSApi_Upload") +public class FSUpload extends FSAPI { + @XmlElements(value = { @XmlElement(name = "getUploadUrl", type = FSGetUploadURL.class) }) + private FSResponse response; + + public FSResponse getResponse() { + return response; + } +} diff --git a/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/service/impl/FileSonicService.java b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/service/impl/FileSonicService.java new file mode 100644 index 0000000..e15693f --- /dev/null +++ b/httpchannel-service/httpchannel-service-filesonic/src/main/java/com/rogiel/httpchannel/service/impl/FileSonicService.java @@ -0,0 +1,206 @@ +/* + * This file is part of seedbox . + * + * seedbox is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * seedbox is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with seedbox. If not, see . + */ +package com.rogiel.httpchannel.service.impl; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.regex.Pattern; + +import com.rogiel.httpchannel.filesonic.FileSonicAPI; +import com.rogiel.httpchannel.service.AbstractAuthenticator; +import com.rogiel.httpchannel.service.AbstractHttpService; +import com.rogiel.httpchannel.service.AbstractUploader; +import com.rogiel.httpchannel.service.AuthenticationService; +import com.rogiel.httpchannel.service.Authenticator; +import com.rogiel.httpchannel.service.AuthenticatorCapability; +import com.rogiel.httpchannel.service.CapabilityMatrix; +import com.rogiel.httpchannel.service.Credential; +import com.rogiel.httpchannel.service.Service; +import com.rogiel.httpchannel.service.ServiceID; +import com.rogiel.httpchannel.service.UploadChannel; +import com.rogiel.httpchannel.service.UploadService; +import com.rogiel.httpchannel.service.Uploader; +import com.rogiel.httpchannel.service.UploaderCapability; +import com.rogiel.httpchannel.service.channel.LinkedUploadChannel; +import com.rogiel.httpchannel.service.channel.LinkedUploadChannel.LinkedUploadChannelCloseCallback; +import com.rogiel.httpchannel.service.config.NullAuthenticatorConfiguration; +import com.rogiel.httpchannel.service.config.NullUploaderConfiguration; +import com.rogiel.httpchannel.util.PatternUtils; + +/** + * This service handles login, upload and download to MegaUpload.com. + * + * @author Rogiel + * @since 1.0 + */ +public class FileSonicService extends AbstractHttpService implements Service, + UploadService, + AuthenticationService { + /** + * This service ID + */ + public static final ServiceID SERVICE_ID = ServiceID.create("megaupload"); + + /** + * The download URL pattern + */ + private static final Pattern DOWNLOAD_URL_PATTERN = Pattern + .compile("http://www.filesonic.com/file/[0-9A-z]*"); + /** + * The FileSonic API + */ + private final FileSonicAPI api = new FileSonicAPI(); + + @Override + public ServiceID getID() { + return SERVICE_ID; + } + + @Override + public int getMajorVersion() { + return 1; + } + + @Override + public int getMinorVersion() { + return 0; + } + + @Override + public Uploader getUploader(String filename, + long filesize, NullUploaderConfiguration configuration) { + return new UploaderImpl(filename, filesize, configuration); + } + + @Override + public Uploader getUploader(String filename, + long filesize) { + return getUploader(filename, filesize, newUploaderConfiguration()); + } + + @Override + public NullUploaderConfiguration newUploaderConfiguration() { + return NullUploaderConfiguration.SHARED_INSTANCE; + } + + @Override + public long getMaximumFilesize() { + try { + return api.getMaxFilesize(); + } catch (IOException e) { + return -1; + } + } + + @Override + public String[] getSupportedExtensions() { + return null; + } + + @Override + public CapabilityMatrix getUploadCapabilities() { + return new CapabilityMatrix( + UploaderCapability.NON_PREMIUM_ACCOUNT_UPLOAD, + UploaderCapability.PREMIUM_ACCOUNT_UPLOAD); + } + + @Override + public Authenticator getAuthenticator( + Credential credential, NullAuthenticatorConfiguration configuration) { + return new AuthenticatorImpl(credential, configuration); + } + + @Override + public Authenticator getAuthenticator( + Credential credential) { + return getAuthenticator(credential, newAuthenticatorConfiguration()); + } + + @Override + public NullAuthenticatorConfiguration newAuthenticatorConfiguration() { + return NullAuthenticatorConfiguration.SHARED_INSTANCE; + } + + @Override + public CapabilityMatrix getAuthenticationCapability() { + return new CapabilityMatrix(); + } + + protected class UploaderImpl extends + AbstractUploader implements + Uploader, + LinkedUploadChannelCloseCallback { + private Future uploadFuture; + + public UploaderImpl(String filename, long filesize, + NullUploaderConfiguration configuration) { + super(filename, filesize, configuration); + } + + @Override + public UploadChannel openChannel() throws IOException { + logger.debug("Starting upload to filesonic.com"); + final LinkedUploadChannel channel = createLinkedChannel(this); + uploadFuture = multipartPost(api.getUploadURL().toString()) + .parameter("files[]", channel).asStringAsync(); + return waitChannelLink(channel, uploadFuture); + } + + @Override + public String finish() throws IOException { + try { + return PatternUtils.find(DOWNLOAD_URL_PATTERN, + uploadFuture.get()); + } catch (InterruptedException e) { + return null; + } catch (ExecutionException e) { + throw (IOException) e.getCause(); + } + } + } + + protected class AuthenticatorImpl extends + AbstractAuthenticator implements + Authenticator { + public AuthenticatorImpl(Credential credential, + NullAuthenticatorConfiguration configuration) { + super(credential, configuration); + } + + @Override + public void login() throws IOException { + logger.debug("Logging to filesonic.com"); + api.login(credential.getUsername(), credential.getPassword()); + // if (username == null) + // throw new AuthenticationInvalidCredentialException(); + } + + @Override + public void logout() throws IOException { + post("http://www.megaupload.com/?c=account").parameter("logout", + true).request(); + // TODO check logout status + } + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + " " + getMajorVersion() + "." + + getMinorVersion(); + } +} diff --git a/httpchannel-service/httpchannel-service-filesonic/src/main/resources/META-INF/services/com.rogiel.httpchannel.service.Service b/httpchannel-service/httpchannel-service-filesonic/src/main/resources/META-INF/services/com.rogiel.httpchannel.service.Service new file mode 100644 index 0000000..15dd2f2 --- /dev/null +++ b/httpchannel-service/httpchannel-service-filesonic/src/main/resources/META-INF/services/com.rogiel.httpchannel.service.Service @@ -0,0 +1 @@ +com.rogiel.httpchannel.service.impl.FileSonicService \ No newline at end of file diff --git a/httpchannel-service/httpchannel-service-hotfile/src/main/java/com/rogiel/httpchannel/service/impl/HotFileService.java b/httpchannel-service/httpchannel-service-hotfile/src/main/java/com/rogiel/httpchannel/service/impl/HotFileService.java index 2b72687..4f285aa 100644 --- a/httpchannel-service/httpchannel-service-hotfile/src/main/java/com/rogiel/httpchannel/service/impl/HotFileService.java +++ b/httpchannel-service/httpchannel-service-hotfile/src/main/java/com/rogiel/httpchannel/service/impl/HotFileService.java @@ -196,9 +196,12 @@ public class HotFileService extends AbstractHttpService implements Service, @Override public UploadChannel openChannel() throws IOException { + logger.debug("Starting upload to hotfile.com"); final HTMLPage page = get("http://www.hotfile.com/").asPage(); final String action = page.findFormAction(UPLOAD_URL_PATTERN); + logger.debug("Upload URL is {}", action); + final LinkedUploadChannel channel = createLinkedChannel(this); uploadFuture = multipartPost(action) @@ -227,6 +230,7 @@ public class HotFileService extends AbstractHttpService implements Service, @Override public DownloadChannel openChannel(DownloadListener listener, long position) throws IOException { + logger.debug("Downloading {} from hotfile.com", url); final HTMLPage page = get(url).asPage(); // // try to find timer @@ -243,6 +247,7 @@ public class HotFileService extends AbstractHttpService implements Service, final String downloadUrl = page .findLink(DOWNLOAD_DIRECT_LINK_PATTERN); + logger.debug("Download link is {}", downloadUrl); // final String tmHash = PatternUtils.find(DOWNLOAD_TMHASH_PATTERN, // content);F if (downloadUrl != null && downloadUrl.length() > 0) { @@ -254,49 +259,6 @@ public class HotFileService extends AbstractHttpService implements Service, return new InputStreamDownloadChannel(downloadResponse .getEntity().getContent(), contentLength, filename); - // } else if (tmHash != null) { - // String dlUrl = PatternUtils.find(FREE_DOWNLOAD_URL_PATTERN, - // content); - // - // String action = PatternUtils.find(DOWNLOAD_ACTION_PATTERN, - // content, 1); - // int tm = PatternUtils.findInt(DOWNLOAD_TM_PATTERN, content, - // 1); - // int wait = PatternUtils.findInt(DOWNLOAD_WAIT_PATTERN, - // content, - // 1); - // String waitHash = - // PatternUtils.find(DOWNLOAD_WAITHASH_PATTERN, - // content, 1); - // String upId = PatternUtils.find(DOWNLOAD_UPIDHASH_PATTERN, - // content, 1); - // - // System.out.println("Wait time: "+wait); - // - // if (wait > 0) - // timer(listener, wait * 1000); - // - // final HttpPost downloadPost = new - // HttpPost("http://www.hotfile.com"+dlUrl); - // final List pairs = new - // ArrayList(); - // pairs.add(new BasicNameValuePair("action", action)); - // pairs.add(new BasicNameValuePair("tm", - // Integer.toString(tm))); - // pairs.add(new BasicNameValuePair("tmhash", tmHash)); - // pairs.add(new BasicNameValuePair("wait", - // Integer.toString(wait))); - // pairs.add(new BasicNameValuePair("waithash", waitHash)); - // pairs.add(new BasicNameValuePair("upidhash", upId)); - // - // downloadPost.setEntity(new UrlEncodedFormEntity(pairs)); - // - // final HttpResponse downloadResponse = client - // .execute(downloadPost); - // System.out.println(IOUtils.toString(downloadResponse.getEntity().getContent())); - // - // return new InputStreamDownloadChannel(downloadResponse - // .getEntity().getContent(), 0, "haha"); } else { throw new IOException("Download link not found"); } @@ -313,6 +275,7 @@ public class HotFileService extends AbstractHttpService implements Service, @Override public void login() throws ClientProtocolException, IOException { + logger.debug("Authenticating hotfile.com"); HTMLPage page = post("http://www.hotfile.com/login.php") .parameter("returnto", "/index.php") .parameter("user", credential.getUsername()) diff --git a/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java b/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java index 210d68b..3097d2d 100644 --- a/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java +++ b/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java @@ -205,10 +205,12 @@ public class MegaUploadService extends AbstractHttpService implements Service, @Override public UploadChannel openChannel() throws IOException { + logger.debug("Starting upload to megaupload.com"); final HTMLPage page = get("http://www.megaupload.com/multiupload/") .asPage(); final String url = page.findFormAction(UPLOAD_URL_PATTERN); - + logger.debug("Upload URL is {}", url); + final LinkedUploadChannel channel = createLinkedChannel(this); uploadFuture = multipartPost(url) .parameter("multimessage_0", configuration.description()) @@ -240,11 +242,13 @@ public class MegaUploadService extends AbstractHttpService implements Service, @Override public DownloadChannel openChannel(DownloadListener listener, long position) throws IOException { + logger.debug("Starting {} download from megaupload.com", url); HttpResponse response = get(url).request(); // disable direct downloads, we don't support them! if (response.getEntity().getContentType().getValue() .equals("application/octet-stream")) { + logger.debug("Direct download is enabled, deactivating"); // close connection response.getEntity().getContent().close(); @@ -263,6 +267,7 @@ public class MegaUploadService extends AbstractHttpService implements Service, // try to find timer int timer = page.findScriptAsInt(DOWNLOAD_TIMER, 1); if (timer > 0 && configuration.getRespectWaitTime()) { + logger.debug(""); timer(listener, timer * 1000); } final String downloadUrl = page @@ -299,6 +304,7 @@ public class MegaUploadService extends AbstractHttpService implements Service, @Override public void login() throws IOException { + logger.debug("Starting login to megaupload.com"); final HTMLPage page = post("http://www.megaupload.com/?c=login") .parameter("login", true) .parameter("username", credential.getUsername()) diff --git a/httpchannel-service/httpchannel-service-multiupload/src/main/java/com/rogiel/httpchannel/service/impl/MultiUploadService.java b/httpchannel-service/httpchannel-service-multiupload/src/main/java/com/rogiel/httpchannel/service/impl/MultiUploadService.java index 0f97913..c07bfd3 100644 --- a/httpchannel-service/httpchannel-service-multiupload/src/main/java/com/rogiel/httpchannel/service/impl/MultiUploadService.java +++ b/httpchannel-service/httpchannel-service-multiupload/src/main/java/com/rogiel/httpchannel/service/impl/MultiUploadService.java @@ -183,8 +183,10 @@ public class MultiUploadService extends AbstractHttpService implements Service, @Override public UploadChannel openChannel() throws IOException { + logger.debug("Starting upload to multiupload.com"); final String url = get("http://www.multiupload.com/").asPage() .findFormAction(UPLOAD_URL_PATTERN); + logger.debug("Upload URL is {}", url); final LinkedUploadChannel channel = createLinkedChannel(this); PostMultipartRequest request = multipartPost(url).parameter( @@ -192,6 +194,7 @@ public class MultiUploadService extends AbstractHttpService implements Service, "file_0", channel); for (final MultiUploadMirrorService mirror : configuration .uploadServices()) { + logger.debug("Adding {} as mirror", mirror.name()); request.parameter("service_" + mirror.id, 1); } @@ -204,6 +207,7 @@ public class MultiUploadService extends AbstractHttpService implements Service, try { final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN, uploadFuture.get(), 1); + logger.debug("Upload to multiupload.com finished"); if (linkId == null) return null; return new StringBuilder("http://www.multiupload.com/").append( @@ -231,6 +235,7 @@ public class MultiUploadService extends AbstractHttpService implements Service, DownloadNotAuthorizedException, DownloadNotResumableException { final HTMLPage page = get(url).asPage(); final String link = page.findLink(DIRECT_DOWNLOAD_LINK_PATTERN); + logger.debug("Direct download link is {}", link); if (link == null) throw new DownloadLinkNotFoundException(); return download(get(link).position(position)); diff --git a/httpchannel-service/httpchannel-service-uploadhere/pom.xml b/httpchannel-service/httpchannel-service-uploadhere/pom.xml index 77dd028..613c705 100644 --- a/httpchannel-service/httpchannel-service-uploadhere/pom.xml +++ b/httpchannel-service/httpchannel-service-uploadhere/pom.xml @@ -10,11 +10,4 @@ com.rogiel.httpchannel.services HttpChannel/Service/UploadHere Provides upload access to uploadhere.com - - - com.rogiel.httpchannel - httpchannel-captcha-recaptcha - 1.0.0 - - \ No newline at end of file diff --git a/httpchannel-service/httpchannel-service-uploadhere/src/main/java/com/rogiel/httpchannel/service/impl/UploadHereService.java b/httpchannel-service/httpchannel-service-uploadhere/src/main/java/com/rogiel/httpchannel/service/impl/UploadHereService.java index 3cf62e5..e60574e 100644 --- a/httpchannel-service/httpchannel-service-uploadhere/src/main/java/com/rogiel/httpchannel/service/impl/UploadHereService.java +++ b/httpchannel-service/httpchannel-service-uploadhere/src/main/java/com/rogiel/httpchannel/service/impl/UploadHereService.java @@ -6,8 +6,8 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.regex.Pattern; -import com.rogiel.httpchannel.captcha.impl.AjaxReCaptchaService; -import com.rogiel.httpchannel.captcha.impl.ReCaptcha; +import com.rogiel.httpchannel.captcha.ImageCaptcha; +import com.rogiel.httpchannel.captcha.ReCaptchaExtractor; import com.rogiel.httpchannel.service.AbstractAuthenticator; import com.rogiel.httpchannel.service.AbstractHttpDownloader; import com.rogiel.httpchannel.service.AbstractHttpService; @@ -67,8 +67,6 @@ public class UploadHereService extends AbstractHttpService implements Service, private static final String INVALID_LOGIN_STRING = "Incorrect username and/or password. Please try again!"; - private final AjaxReCaptchaService captchaService = new AjaxReCaptchaService(); - @Override public ServiceID getID() { return SERVICE_ID; @@ -190,6 +188,9 @@ public class UploadHereService extends AbstractHttpService implements Service, final String url = page.findFormAction(UPLOAD_URL_PATTERN); final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER"); + logger.debug("Upload URL: {}, UserCookie: {}, UploadID: {}", + new Object[] { url, userCookie, uploadID }); + final LinkedUploadChannel channel = createLinkedChannel(this); uploadFuture = multipartPost(url).parameter("file_0", channel) .parameter("u", userCookie) @@ -202,6 +203,7 @@ public class UploadHereService extends AbstractHttpService implements Service, try { final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN, uploadFuture.get(), 1); + logger.debug("Upload to uploadhere.com finished"); if (linkId == null) return null; return new StringBuilder("http://www.uploadhere.com/").append( @@ -230,15 +232,24 @@ public class UploadHereService extends AbstractHttpService implements Service, HTMLPage page = get(url).asPage(); final int waitTime = page.findScriptAsInt(TIMER_PATTERN, 1) * 1000; + logger.debug("Wait time is {}", waitTime); - final ReCaptcha captcha = captchaService.create(page.toString()); + final ImageCaptcha captcha = ReCaptchaExtractor.extractAjaxCaptcha( + page, http); if (captcha != null) { + logger.debug("Service is requiring CAPTCHA {}", captcha); final long start = System.currentTimeMillis(); resolveCaptcha(captcha); final long delta = System.currentTimeMillis() - start; - if (delta < waitTime) + if (delta < waitTime) { + logger.debug( + "After captcha resolving, still {} ms remaining", + delta); timer(listener, waitTime - delta); + } else { + logger.debug("CAPTCHA solving took longer than timer, skipping it"); + } String content = post(url) .parameter("recaptcha_challenge_field", captcha.getID()) @@ -246,10 +257,15 @@ public class UploadHereService extends AbstractHttpService implements Service, captcha.getAnswer()).asString(); String downloadLink = PatternUtils.find( DIERCT_DOWNLOAD_URL_PATTERN, content, 1); - if (downloadLink == null) + if (downloadLink == null) { + captchaService.invalid(captcha); throw new InvalidCaptchaException(); + } else { + captchaService.valid(captcha); + } downloadLink = downloadLink.replaceAll(Pattern.quote("\\/"), "/"); + logger.debug("Direct download URL is {}", downloadLink); return download(get(downloadLink).position(position)); } throw new DownloadLinkNotFoundException(); diff --git a/httpchannel-service/httpchannel-service-uploadking/pom.xml b/httpchannel-service/httpchannel-service-uploadking/pom.xml index d58c097..9fd42d4 100644 --- a/httpchannel-service/httpchannel-service-uploadking/pom.xml +++ b/httpchannel-service/httpchannel-service-uploadking/pom.xml @@ -1,20 +1,22 @@ - - 4.0.0 - - httpchannel-service - com.rogiel.httpchannel - 1.0.0 - .. - - httpchannel-service-uploadking - com.rogiel.httpchannel.services - HttpChannel/Service/UploadKing - Provides upload access to uploadking.com - - - com.rogiel.httpchannel - httpchannel-captcha-recaptcha - 1.0.0 - - + + 4.0.0 + + httpchannel-service + com.rogiel.httpchannel + 1.0.0 + .. + + httpchannel-service-uploadking + com.rogiel.httpchannel.services + HttpChannel/Service/UploadKing + Provides upload access to uploadking.com + + + com.rogiel.httpchannel.captcha + httpchannel-captcha-captchatrader + 1.0.0 + test + + \ No newline at end of file diff --git a/httpchannel-service/httpchannel-service-uploadking/src/main/java/com/rogiel/httpchannel/service/impl/UploadKingService.java b/httpchannel-service/httpchannel-service-uploadking/src/main/java/com/rogiel/httpchannel/service/impl/UploadKingService.java index b885cf6..20f9847 100644 --- a/httpchannel-service/httpchannel-service-uploadking/src/main/java/com/rogiel/httpchannel/service/impl/UploadKingService.java +++ b/httpchannel-service/httpchannel-service-uploadking/src/main/java/com/rogiel/httpchannel/service/impl/UploadKingService.java @@ -6,8 +6,8 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.regex.Pattern; -import com.rogiel.httpchannel.captcha.impl.AjaxReCaptchaService; -import com.rogiel.httpchannel.captcha.impl.ReCaptcha; +import com.rogiel.httpchannel.captcha.ImageCaptcha; +import com.rogiel.httpchannel.captcha.ReCaptchaExtractor; import com.rogiel.httpchannel.service.AbstractAuthenticator; import com.rogiel.httpchannel.service.AbstractHttpDownloader; import com.rogiel.httpchannel.service.AbstractHttpService; @@ -67,8 +67,6 @@ public class UploadKingService extends AbstractHttpService implements Service, private static final String INVALID_LOGIN_STRING = "Incorrect username and/or password. Please try again!"; - private final AjaxReCaptchaService captchaService = new AjaxReCaptchaService(); - @Override public ServiceID getID() { return SERVICE_ID; @@ -190,6 +188,9 @@ public class UploadKingService extends AbstractHttpService implements Service, final String url = page.findFormAction(UPLOAD_URL_PATTERN); final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER"); + logger.debug("Upload URL: {}, UserCookie: {}, UploadID: {}", + new Object[] { url, userCookie, uploadID }); + final LinkedUploadChannel channel = createLinkedChannel(this); uploadFuture = multipartPost(url).parameter("file", channel) .parameter("u", userCookie) @@ -202,6 +203,7 @@ public class UploadKingService extends AbstractHttpService implements Service, try { final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN, uploadFuture.get(), 1); + logger.debug("Upload to uploadking.com finished"); if (linkId == null) return null; return new StringBuilder("http://www.uploadking.com/").append( @@ -224,19 +226,29 @@ public class UploadKingService extends AbstractHttpService implements Service, @Override public DownloadChannel openChannel(DownloadListener listener, long position) throws IOException { + logger.debug("Downloading {} with uploadking.com"); HTMLPage page = get(url).asPage(); final int waitTime = page.findScriptAsInt(TIMER_PATTERN, 1) * 1000; + logger.debug("Wait time is {}", waitTime); - final ReCaptcha captcha = captchaService.create(page.toString()); + final ImageCaptcha captcha = ReCaptchaExtractor.extractAjaxCaptcha( + page, http); if (captcha != null) { + logger.debug("Service is requiring CAPTCHA {}", captcha); final long start = System.currentTimeMillis(); resolveCaptcha(captcha); final long delta = System.currentTimeMillis() - start; - if (delta < waitTime) + if (delta < waitTime) { + logger.debug( + "After captcha resolving, still {} ms remaining", + delta); timer(listener, waitTime - delta); + } else { + logger.debug("CAPTCHA solving took longer than timer, skipping it"); + } String content = post(url) .parameter("recaptcha_challenge_field", captcha.getID()) @@ -244,10 +256,15 @@ public class UploadKingService extends AbstractHttpService implements Service, captcha.getAnswer()).asString(); String downloadLink = PatternUtils.find( DIERCT_DOWNLOAD_URL_PATTERN, content, 1); - if (downloadLink == null) + if (downloadLink == null) { + captchaService.invalid(captcha); throw new InvalidCaptchaException(); + } else { + captchaService.valid(captcha); + } downloadLink = downloadLink.replaceAll(Pattern.quote("\\/"), "/"); + logger.debug("Direct download URL is {}", downloadLink); return download(get(downloadLink).position(position)); } throw new DownloadLinkNotFoundException(); diff --git a/httpchannel-service/httpchannel-service-uploadking/src/test/java/com/rogiel/httpchannel/service/impl/UploadKingServiceTest.java b/httpchannel-service/httpchannel-service-uploadking/src/test/java/com/rogiel/httpchannel/service/impl/UploadKingServiceTest.java index 9d783e7..0b855a6 100644 --- a/httpchannel-service/httpchannel-service-uploadking/src/test/java/com/rogiel/httpchannel/service/impl/UploadKingServiceTest.java +++ b/httpchannel-service/httpchannel-service-uploadking/src/test/java/com/rogiel/httpchannel/service/impl/UploadKingServiceTest.java @@ -4,14 +4,20 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; import java.net.URL; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import java.util.Properties; import junit.framework.Assert; import org.junit.Before; import org.junit.Test; +import com.rogiel.httpchannel.captcha.CaptchaService; +import com.rogiel.httpchannel.captcha.impl.CaptchaTraderService; +import com.rogiel.httpchannel.service.DownloadChannel; import com.rogiel.httpchannel.service.UploaderCapability; import com.rogiel.httpchannel.util.ChannelUtils; @@ -37,26 +43,19 @@ public class UploadKingServiceTest { System.out.println(url); } - // @Test - // public void testDownloader() throws IOException { - // service.setCaptchaResolver(new CaptchaResolver() { - // @Override - // public boolean resolve(Captcha rawCaptcha) { - // final ImageCaptcha captcha = (ImageCaptcha) rawCaptcha; - // System.out.println(captcha.getImageURL()); - // try { - // captcha.setAnswer(new BufferedReader(new InputStreamReader( - // System.in)).readLine()); - // System.out.println("Answer is: " + captcha.getAnswer()); - // return true; - // } catch (IOException e) { - // return false; - // } - // } - // }); - // - // final DownloadChannel channel = service.getDownloader( - // new URL("http://www.uploadking.com/WM3PHD9JAY")).openChannel(512); - // System.out.println(new String(ChannelUtils.toByteArray(channel))); - // } + @Test + public void testDownloader() throws IOException { + final Properties p = new Properties(); + p.load(Files.newInputStream( + Paths.get("../../httpchannel-captcha/src/test/resources/captchatrader.properties"), + StandardOpenOption.READ)); + + final CaptchaService s = new CaptchaTraderService(); + s.authenticate(p.getProperty("username"), p.getProperty("password")); + service.setCaptchaService(s); + + final DownloadChannel channel = service.getDownloader( + new URL("http://www.uploadking.com/WM3PHD9JAY")).openChannel(0); + System.out.println(new String(ChannelUtils.toByteArray(channel))); + } } diff --git a/httpchannel-service/httpchannel-service-zshare/pom.xml b/httpchannel-service/httpchannel-service-zshare/pom.xml new file mode 100644 index 0000000..683ccc4 --- /dev/null +++ b/httpchannel-service/httpchannel-service-zshare/pom.xml @@ -0,0 +1,13 @@ + + 4.0.0 + + httpchannel-service + com.rogiel.httpchannel + 1.0.0 + .. + + httpchannel-service-zshare + com.rogiel.httpchannel.services + HttpChannel/Service/ZShare + Provides download and upload access to zshare.com + \ No newline at end of file diff --git a/httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareService.java b/httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareService.java new file mode 100644 index 0000000..e2fc424 --- /dev/null +++ b/httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareService.java @@ -0,0 +1,262 @@ +package com.rogiel.httpchannel.service.impl; + +import com.rogiel.httpchannel.service.AbstractHttpService; +import com.rogiel.httpchannel.service.Service; +import com.rogiel.httpchannel.service.ServiceID; + +/** + * This service handles uploads to UploadKing.com. + * + * @author Rogiel + * @since 1.0 + */ +public class ZShareService extends AbstractHttpService implements Service/* + * , + * UploadService + * < + * ZShareUploaderConfiguration + * >, + * DownloadService + * < + * NullDownloaderConfiguration + * >, + * AuthenticationService + * < + * NullAuthenticatorConfiguration + * > + */{ + /** + * This service ID + */ + public static final ServiceID SERVICE_ID = ServiceID.create("zshare"); + + // private static final Pattern UPLOAD_URL_PATTERN = Pattern + // .compile("http://dl([0-9]*)\\.zshare\\.net(\\:[0-9]*)?/", + // Pattern.CASE_INSENSITIVE); + // private static final Pattern DOWNLOAD_ID_PATTERN = Pattern + // .compile("\"downloadid\":\"([0-9a-zA-Z]*)\""); +// private static final Pattern DOWNLOAD_URL_PATTERN = Pattern +// .compile("http://(www\\.)?uploadking.\\com/[0-9A-z]*"); +// private static final Pattern TIMER_PATTERN = Pattern.compile( +// "count = ([0-9]*);", Pattern.COMMENTS); +// private static final Pattern DIERCT_DOWNLOAD_URL_PATTERN = Pattern +// .compile("(http:\\\\/\\\\/www[0-9]*\\.uploadking\\.com(:[0-9]*)?\\\\/files\\\\/([0-9A-z]*)\\\\/(.*))\""); +// +// private static final String INVALID_LOGIN_STRING = "Incorrect username and/or password. Please try again!"; + + @Override + public ServiceID getID() { + return SERVICE_ID; + } + + @Override + public int getMajorVersion() { + return 1; + } + + @Override + public int getMinorVersion() { + return 0; + } + + // @Override + // public Uploader getUploader(String filename, + // long filesize, ZShareUploaderConfiguration configuration) { + // return new UploaderImpl(filename, filesize, configuration); + // } + // + // @Override + // public Uploader getUploader(String filename, + // long filesize) { + // return getUploader(filename, filesize, newUploaderConfiguration()); + // } + // + // @Override + // public ZShareUploaderConfiguration newUploaderConfiguration() { + // return new ZShareUploaderConfiguration(); + // } + // + // @Override + // public long getMaximumFilesize() { + // return 1 * 1024 * 1024 * 1024; + // } + // + // @Override + // public String[] getSupportedExtensions() { + // return null; + // } + // + // @Override + // public CapabilityMatrix getUploadCapabilities() { + // return new CapabilityMatrix( + // UploaderCapability.UNAUTHENTICATED_UPLOAD, + // UploaderCapability.NON_PREMIUM_ACCOUNT_UPLOAD, + // UploaderCapability.PREMIUM_ACCOUNT_UPLOAD); + // } + + // @Override + // public Downloader getDownloader(URL url, + // NullDownloaderConfiguration configuration) { + // return new DownloaderImpl(url, configuration); + // } + // + // @Override + // public Downloader getDownloader(URL url) { + // return getDownloader(url, newDownloaderConfiguration()); + // } + // + // @Override + // public NullDownloaderConfiguration newDownloaderConfiguration() { + // return NullDownloaderConfiguration.SHARED_INSTANCE; + // } + // + // @Override + // public boolean matchURL(URL url) { + // return DOWNLOAD_URL_PATTERN.matcher(url.toString()).matches(); + // } + // + // @Override + // public CapabilityMatrix getDownloadCapabilities() { + // return new CapabilityMatrix( + // DownloaderCapability.UNAUTHENTICATED_DOWNLOAD, + // DownloaderCapability.UNAUTHENTICATED_RESUME, + // DownloaderCapability.NON_PREMIUM_ACCOUNT_DOWNLOAD, + // DownloaderCapability.NON_PREMIUM_ACCOUNT_RESUME); + // } + // + // @Override + // public Authenticator getAuthenticator( + // Credential credential, NullAuthenticatorConfiguration configuration) { + // return new AuthenticatorImpl(credential, configuration); + // } + // + // @Override + // public Authenticator getAuthenticator( + // Credential credential) { + // return getAuthenticator(credential, newAuthenticatorConfiguration()); + // } + // + // @Override + // public NullAuthenticatorConfiguration newAuthenticatorConfiguration() { + // return NullAuthenticatorConfiguration.SHARED_INSTANCE; + // } + // + // @Override + // public CapabilityMatrix + // getAuthenticationCapability() { + // return new CapabilityMatrix(); + // } + + // protected class UploaderImpl extends + // AbstractUploader implements + // Uploader, + // LinkedUploadChannelCloseCallback { + // private Future uploadFuture; + // + // public UploaderImpl(String filename, long filesize, + // ZShareUploaderConfiguration configuration) { + // super(filename, filesize, configuration); + // } + // + // @Override + // public UploadChannel openChannel() throws IOException { + // final HTMLPage page = get("http://www.zshare.net/").asPage(); + // + // final String url = page.findFormAction(UPLOAD_URL_PATTERN); + // System.out.println(url+"cgi-bin/ubr_upload.pl"); + // + // final LinkedUploadChannel channel = createLinkedChannel(this); + // uploadFuture = + // multipartPost(url+"cgi-bin/ubr_upload.pl").parameter("file", channel) + // .parameter("descr", configuration.description()) + // .parameter("TOS", true).parameter("is_private", false) + // .asStringAsync(); + // return waitChannelLink(channel, uploadFuture); + // } + // + // @Override + // public String finish() throws IOException { + // try { + // System.out.println(uploadFuture.get()); + // final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN, + // uploadFuture.get(), 1); + // if (linkId == null) + // return null; + // return new StringBuilder("http://www.uploadking.com/").append( + // linkId).toString(); + // } catch (InterruptedException e) { + // return null; + // } catch (ExecutionException e) { + // ExceptionUtils.asIOException(e); + // return null; + // } + // } + // } + + // protected class DownloaderImpl extends + // AbstractHttpDownloader implements + // Downloader { + // public DownloaderImpl(URL url, NullDownloaderConfiguration configuration) + // { + // super(url, configuration); + // } + // + // @Override + // public DownloadChannel openChannel(DownloadListener listener, + // long position) throws IOException { + // HTMLPage page = get(url).asPage(); + // + // final int waitTime = page.findScriptAsInt(TIMER_PATTERN, 1) * 1000; + // + // // final ReCaptcha captcha = captchaService.create(page.toString()); + // // if (captcha != null) { + // // final long start = System.currentTimeMillis(); + // // + // // resolveCaptcha(captcha); + // // + // // final long delta = System.currentTimeMillis() - start; + // // if (delta < waitTime) + // // timer(listener, waitTime - delta); + // // + // // String content = post(url) + // // .parameter("recaptcha_challenge_field", captcha.getID()) + // // .parameter("recaptcha_response_field", + // // captcha.getAnswer()).asString(); + // // String downloadLink = PatternUtils.find( + // // DIERCT_DOWNLOAD_URL_PATTERN, content, 1); + // // if (downloadLink == null) + // // throw new InvalidCaptchaException(); + // // downloadLink = downloadLink.replaceAll(Pattern.quote("\\/"), + // // "/"); + // // return download(get(downloadLink).position(position)); + // // } + // throw new DownloadLinkNotFoundException(); + // } + // } + + // protected class AuthenticatorImpl extends + // AbstractAuthenticator implements + // Authenticator { + // public AuthenticatorImpl(Credential credential, + // NullAuthenticatorConfiguration configuration) { + // super(credential, configuration); + // } + // + // @Override + // public void login() throws IOException { + // final HTMLPage page = post("http://www.uploadking.com/login") + // .parameter("do", "login") + // .parameter("username", credential.getUsername()) + // .parameter("password", credential.getPassword()).asPage(); + // if (page.contains(INVALID_LOGIN_STRING)) + // throw new AuthenticationInvalidCredentialException(); + // } + // + // @Override + // public void logout() throws IOException { + // post("http://www.uploadking.com/login").parameter("do", "logout") + // .request(); + // // TODO check logout status + // } + // } +} diff --git a/httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareUploaderConfiguration.java b/httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareUploaderConfiguration.java new file mode 100644 index 0000000..939f3df --- /dev/null +++ b/httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareUploaderConfiguration.java @@ -0,0 +1,28 @@ +package com.rogiel.httpchannel.service.impl; + +import com.rogiel.httpchannel.service.Uploader.DescriptionableUploaderConfiguration; +import com.rogiel.httpchannel.service.Uploader.UploaderConfiguration; + +/** + * Describes an configuration for an {@link UploaderImpl} + * + * @author Rogiel + */ +public class ZShareUploaderConfiguration implements UploaderConfiguration, + DescriptionableUploaderConfiguration { + /** + * The upload description + */ + private String description = DescriptionableUploaderConfiguration.DEFAULT_DESCRIPTION; + + @Override + public String description() { + return description; + } + + @Override + public ZShareUploaderConfiguration description(String description) { + this.description = description; + return this; + } +} diff --git a/httpchannel-service/httpchannel-service-zshare/src/main/resources/META-INF/services/com.rogiel.httpchannel.service.Service b/httpchannel-service/httpchannel-service-zshare/src/main/resources/META-INF/services/com.rogiel.httpchannel.service.Service new file mode 100644 index 0000000..9b6dcd1 --- /dev/null +++ b/httpchannel-service/httpchannel-service-zshare/src/main/resources/META-INF/services/com.rogiel.httpchannel.service.Service @@ -0,0 +1 @@ +com.rogiel.httpchannel.service.impl.ZShareService \ No newline at end of file diff --git a/httpchannel-service/httpchannel-service-zshare/src/test/resources/upload-test-file.txt b/httpchannel-service/httpchannel-service-zshare/src/test/resources/upload-test-file.txt new file mode 100644 index 0000000..3cfccc8 --- /dev/null +++ b/httpchannel-service/httpchannel-service-zshare/src/test/resources/upload-test-file.txt @@ -0,0 +1,3 @@ +This is a simple upload test file. + +This is for testing purposes only. \ No newline at end of file diff --git a/httpchannel-util/pom.xml b/httpchannel-util/pom.xml index 4a2f3e1..42d8164 100644 --- a/httpchannel-util/pom.xml +++ b/httpchannel-util/pom.xml @@ -48,13 +48,6 @@ jar compile - - org.slf4j - slf4j-log4j12 - 1.6.2 - jar - compile - org.htmlparser htmlparser diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractHTMLImageCaptchaService.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractHTMLImageCaptchaService.java deleted file mode 100644 index da7194d..0000000 --- a/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractHTMLImageCaptchaService.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * - */ -package com.rogiel.httpchannel.captcha; - -import java.io.IOException; - -import com.rogiel.httpchannel.util.htmlparser.HTMLPage; - -/** - * @author Rogiel - * - */ -public abstract class AbstractHTMLImageCaptchaService - extends AbstractImageCaptchaService { - @Override - public final C create(String html) { - try { - return create(HTMLPage.parse(html)); - } catch (IOException e) { - return null; - } - } - - public abstract C create(HTMLPage page) throws IOException; -} diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractImageCaptcha.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractImageCaptcha.java deleted file mode 100644 index 2429ef9..0000000 --- a/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractImageCaptcha.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * - */ -package com.rogiel.httpchannel.captcha; - -import java.net.URL; - -/** - * @author Rogiel - * - */ -public abstract class AbstractImageCaptcha implements ImageCaptcha { - private final URL imageURL; - private final String ID; - - private String answer; - private boolean automaticallyResolved; - - public AbstractImageCaptcha(URL imageURL, String ID) { - this.imageURL = imageURL; - this.ID = ID; - } - - @Override - public void setAnswer(String answer) { - this.answer = answer; - } - - @Override - public String getAnswer() { - return answer; - } - - @Override - public boolean wasAutomaticallyResolved() { - return automaticallyResolved; - } - - @Override - public URL getImageURL() { - return imageURL; - } - - public String getID() { - return ID; - } -} diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractImageCaptchaService.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractImageCaptchaService.java deleted file mode 100644 index f5b9de8..0000000 --- a/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/AbstractImageCaptchaService.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * - */ -package com.rogiel.httpchannel.captcha; - -import java.net.URL; - -import com.rogiel.httpchannel.http.GetRequest; -import com.rogiel.httpchannel.http.HttpContext; -import com.rogiel.httpchannel.http.PostMultipartRequest; -import com.rogiel.httpchannel.http.PostRequest; - -/** - * @author Rogiel - * - */ -public abstract class AbstractImageCaptchaService - implements ImageCaptchaService { - protected final HttpContext http = new HttpContext(); - - @Override - public boolean resolve(C captcha) { - return false; - } - - public GetRequest get(String url) { - return http.get(url); - } - - public GetRequest get(URL url) { - return http.get(url); - } - - public PostRequest post(String url) { - return http.post(url); - } - - public PostMultipartRequest multipartPost(String url) { - return http.multipartPost(url); - } -} diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/ReCaptchaExtractor.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/ReCaptchaExtractor.java new file mode 100644 index 0000000..89b623e --- /dev/null +++ b/httpchannel-util/src/main/java/com/rogiel/httpchannel/captcha/ReCaptchaExtractor.java @@ -0,0 +1,58 @@ +/** + * + */ +package com.rogiel.httpchannel.captcha; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.regex.Pattern; + +import com.rogiel.httpchannel.http.HttpContext; +import com.rogiel.httpchannel.util.PatternUtils; +import com.rogiel.httpchannel.util.htmlparser.HTMLPage; + +/** + * @author Rogiel + * + */ +public class ReCaptchaExtractor { + private static final Pattern CAPTCHA_ID_PATTERN = Pattern + .compile("Recaptcha\\.create\\(\"([0-9A-z|_|\\-]*)\", "); + private static final Pattern CAPTCHA_URL_PATTERN = Pattern + .compile("http://www\\.google\\.com/recaptcha/api/challenge\\?k=([0-9A-z|\\-]*)(&(.*))?"); + private static final Pattern CAPTCHA_IMAGE_PATTERN = Pattern + .compile("challenge : '(.*)'"); + + private static final String CHALLENGE_BASE_URL = "http://www.google.com/recaptcha/api/challenge?ajax=1&k="; + private static final String IMAGE_BASE_URL = "http://www.google.com/recaptcha/api/image?c="; + + public static ImageCaptcha extractCaptcha(HTMLPage page, HttpContext ctx) { + final String url = page.findScriptSrc(CAPTCHA_URL_PATTERN); + if (url == null) + return null; + try { + return doExtract(ctx.get(url).asString()); + } catch (IOException e) { + return null; + } + } + + public static ImageCaptcha extractAjaxCaptcha(HTMLPage page, HttpContext ctx) { + final String siteID = page.findScript(CAPTCHA_ID_PATTERN, 1); + try { + return doExtract(ctx.get(CHALLENGE_BASE_URL + siteID).asString()); + } catch (IOException e) { + return null; + } + } + + private static ImageCaptcha doExtract(String content) { + final String id = PatternUtils.find(CAPTCHA_IMAGE_PATTERN, content, 1); + try { + return new ImageCaptcha(id, new URL(IMAGE_BASE_URL + id)); + } catch (MalformedURLException e) { + return null; + } + } +} diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractHttpDownloader.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractHttpDownloader.java index f1c1e68..0c9a3eb 100644 --- a/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractHttpDownloader.java +++ b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractHttpDownloader.java @@ -23,6 +23,8 @@ import org.apache.commons.io.FilenameUtils; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.rogiel.httpchannel.http.Request; import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration; @@ -35,6 +37,8 @@ import com.rogiel.httpchannel.util.ThreadUtils; */ public abstract class AbstractHttpDownloader extends AbstractDownloader implements Downloader { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + protected AbstractHttpDownloader(URL url, C configuration) { super(url, configuration); } @@ -54,6 +58,7 @@ public abstract class AbstractHttpDownloader if (!listener.timer(timer)) return; } + logger.debug("Download timer waiting {}", timer); ThreadUtils.sleep(timer); } diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractHttpService.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractHttpService.java index dfbed49..a568cfd 100644 --- a/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractHttpService.java +++ b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractHttpService.java @@ -38,6 +38,7 @@ public abstract class AbstractHttpService extends AbstractService implements protected LinkedUploadChannel waitChannelLink(LinkedUploadChannel channel, Future future) { + logger.debug("Waiting channel {} to link", channel); while (!channel.isLinked() && !future.isDone()) { ThreadUtils.sleep(100); } diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/channel/LinkedUploadChannel.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/channel/LinkedUploadChannel.java index 8d44811..099d97b 100644 --- a/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/channel/LinkedUploadChannel.java +++ b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/channel/LinkedUploadChannel.java @@ -22,6 +22,9 @@ import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; import java.nio.channels.WritableByteChannel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.rogiel.httpchannel.service.UploadChannel; import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException; @@ -30,6 +33,8 @@ import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException; * */ public class LinkedUploadChannel implements UploadChannel { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private WritableByteChannel channel; private final LinkedUploadChannelCloseCallback closeCallback; @@ -69,6 +74,7 @@ public class LinkedUploadChannel implements UploadChannel { public void close() throws IOException { open = false; final String downloadLink = closeCallback.finish(); + logger.debug("Download link returned by service is {}", downloadLink); if (downloadLink == null) throw new UploadLinkNotFoundException(); this.downloadLink = new URL(downloadLink); diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/util/ExceptionUtils.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/util/ExceptionUtils.java new file mode 100644 index 0000000..165e3d9 --- /dev/null +++ b/httpchannel-util/src/main/java/com/rogiel/httpchannel/util/ExceptionUtils.java @@ -0,0 +1,27 @@ +/** + * + */ +package com.rogiel.httpchannel.util; + +import java.io.IOException; + +/** + * @author Rogiel + * + */ +public class ExceptionUtils { + public static void asIOException(Exception e) throws IOException { + final Throwable e2 = e.getCause(); + if (e2 == null) { + throw new IOException(e); + } else if (e instanceof IOException) { + throw (IOException) e; + } else if (e2 instanceof IOException) { + throw (IOException) e2; + } else if (e2 instanceof RuntimeException) { + throw (RuntimeException) e2; + } else { + throw new IOException(e); + } + } +} diff --git a/pom.xml b/pom.xml index 0c02893..356f7b2 100644 --- a/pom.xml +++ b/pom.xml @@ -64,6 +64,19 @@ jar test + + org.slf4j + slf4j-api + 1.6.4 + compile + + + org.slf4j + slf4j-jdk14 + 1.6.4 + runtime + true + http://httpchannel.rogiel.com/ \ No newline at end of file