mirror of
https://github.com/Rogiel/httpchannel
synced 2025-12-06 07:32:50 +00:00
Implements CaptchaTrader service
This commit is contained in:
@@ -9,25 +9,45 @@ package com.rogiel.httpchannel.captcha;
|
|||||||
*/
|
*/
|
||||||
public interface Captcha {
|
public interface Captcha {
|
||||||
/**
|
/**
|
||||||
* Sets the captcha answer
|
* @return the captcha ID
|
||||||
*
|
*/
|
||||||
|
String getID();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the resolved captcha answer
|
||||||
|
*/
|
||||||
|
String getAnswer();
|
||||||
|
|
||||||
|
/**
|
||||||
* @param answer
|
* @param answer
|
||||||
* the captcha answer
|
* the captcha answer
|
||||||
*/
|
*/
|
||||||
void setAnswer(String answer);
|
void setAnswer(String answer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the captcha answer. <code>null</code> if the service was not able
|
* @return <code>true</code> if the captcha was resolved and
|
||||||
* to resolve it automatically. In such case, {@link #setAnswer(String)}
|
* {@link #getAnswer()} will not return <code>null</code>.
|
||||||
* must be used to set the correct answer.
|
|
||||||
*
|
|
||||||
* @return the captcha answer
|
|
||||||
*/
|
*/
|
||||||
String getAnswer();
|
boolean isResolved();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return <code>true</code> if, and only if, the service was able to
|
* Get this CAPTCHA's attachment.
|
||||||
* automatically resolve the captcha result
|
* <p>
|
||||||
|
* <b>Important note</b>: 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.
|
||||||
|
* <p>
|
||||||
|
* <b>Important note</b>: Attachments are for {@link CaptchaService}
|
||||||
|
* implementations usage! You should not touch any of the attachments!
|
||||||
|
*
|
||||||
|
* @param attachment
|
||||||
|
* the attachment
|
||||||
|
*/
|
||||||
|
void setAttachment(Object attachment);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package com.rogiel.httpchannel.captcha;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
|
||||||
*/
|
|
||||||
public interface CaptchaResolver {
|
|
||||||
/**
|
|
||||||
* Tries to resolve the captcha
|
|
||||||
*
|
|
||||||
* @param captcha
|
|
||||||
* the captcha
|
|
||||||
* @return <code>true</code> if the captcha was resolve, <code>false</code>
|
|
||||||
* to abort
|
|
||||||
*/
|
|
||||||
boolean resolve(Captcha captcha);
|
|
||||||
}
|
|
||||||
@@ -3,9 +3,52 @@
|
|||||||
*/
|
*/
|
||||||
package com.rogiel.httpchannel.captcha;
|
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 <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface CaptchaService<C extends Captcha> {
|
public interface CaptchaService<C extends Captcha> {
|
||||||
|
/**
|
||||||
|
* Authenticates the service instance into the CAPTCHA solving server, if
|
||||||
|
* any. Implementations that do not use authentication, should do nothing
|
||||||
|
* and return <code>-1</code>
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* @param password
|
||||||
|
* @return amount of remaining CAPTCHA solving, <code>-1</code> 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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,66 @@ import java.net.URL;
|
|||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
|
||||||
/**
|
public ImageCaptcha(String id, URL imageURL) {
|
||||||
* @return the captcha image {@link URL}
|
this.ID = id;
|
||||||
*/
|
this.imageURL = imageURL;
|
||||||
URL getImageURL();
|
}
|
||||||
|
|
||||||
|
@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 + "]";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,32 +3,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.rogiel.httpchannel.captcha;
|
package com.rogiel.httpchannel.captcha;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface ImageCaptchaService<C extends ImageCaptcha> extends
|
public interface ImageCaptchaService extends CaptchaService<ImageCaptcha> {
|
||||||
CaptchaService<C> {
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to automatically resolve the captcha
|
|
||||||
*
|
|
||||||
* @param captcha
|
|
||||||
* the captcha to be resolved
|
|
||||||
* @return <code>true</code> if the captcha was successfully resolved
|
|
||||||
*/
|
|
||||||
boolean resolve(C captcha);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.rogiel.httpchannel.captcha.exception;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.rogiel.httpchannel.captcha.exception;
|
||||||
|
|
||||||
|
import com.rogiel.httpchannel.service.exception.ChannelServiceException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.rogiel.httpchannel.captcha.exception;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.rogiel.httpchannel.captcha.exception;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -16,9 +16,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.rogiel.httpchannel.service;
|
package com.rogiel.httpchannel.service;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.rogiel.httpchannel.captcha.Captcha;
|
import com.rogiel.httpchannel.captcha.Captcha;
|
||||||
import com.rogiel.httpchannel.captcha.CaptchaResolver;
|
import com.rogiel.httpchannel.captcha.CaptchaService;
|
||||||
import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException;
|
import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException;
|
||||||
|
import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an abstract {@link Service} implementation.
|
* This is an abstract {@link Service} implementation.
|
||||||
@@ -27,7 +31,11 @@ import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException;
|
|||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractService implements Service {
|
public abstract class AbstractService implements Service {
|
||||||
protected CaptchaResolver captchaResolver;
|
/**
|
||||||
|
* The service {@link Logger} instance
|
||||||
|
*/
|
||||||
|
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
protected CaptchaService<Captcha> captchaService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Service clone() {
|
public Service clone() {
|
||||||
@@ -39,17 +47,17 @@ public abstract class AbstractService implements Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setCaptchaResolver(CaptchaResolver captchaResolver) {
|
@SuppressWarnings("unchecked")
|
||||||
this.captchaResolver = captchaResolver;
|
public void setCaptchaService(
|
||||||
|
CaptchaService<? extends Captcha> captchaService) {
|
||||||
|
this.captchaService = (CaptchaService<Captcha>) captchaService;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void resolveCaptcha(Captcha captcha)
|
protected void resolveCaptcha(Captcha captcha)
|
||||||
throws UnresolvedCaptchaException {
|
throws NoCaptchaServiceException, UnsolvableCaptchaServiceException {
|
||||||
if (captchaResolver == null)
|
if (captchaService == null)
|
||||||
throw new UnresolvedCaptchaException();
|
throw new NoCaptchaServiceException(
|
||||||
if (!captchaResolver.resolve(captcha))
|
"No CaptchaService is configured");
|
||||||
throw new UnresolvedCaptchaException();
|
captchaService.solve((Captcha) captcha);
|
||||||
if (captcha.getAnswer() == null)
|
|
||||||
throw new UnresolvedCaptchaException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ package com.rogiel.httpchannel.service;
|
|||||||
|
|
||||||
import java.io.IOException;
|
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.Authenticator.AuthenticatorConfiguration;
|
||||||
import com.rogiel.httpchannel.service.exception.AuthenticationInvalidCredentialException;
|
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.
|
* This interfaces provides authentication for an service.
|
||||||
@@ -40,13 +41,16 @@ public interface Authenticator<C extends AuthenticatorConfiguration> {
|
|||||||
* if any IO error occur
|
* if any IO error occur
|
||||||
* @throws AuthenticationInvalidCredentialException
|
* @throws AuthenticationInvalidCredentialException
|
||||||
* if the credentials are not valid or cannot be used
|
* if the credentials are not valid or cannot be used
|
||||||
* @throws UnresolvedCaptchaException
|
* @throws UnsolvableCaptchaServiceException
|
||||||
* if the service required captcha resolving but no
|
* 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
|
* 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,
|
void login() throws IOException, AuthenticationInvalidCredentialException,
|
||||||
UnresolvedCaptchaException;
|
UnsolvableCaptchaServiceException, NoCaptchaServiceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logout into the {@link Service}. The session is restored to an not
|
* Logout into the {@link Service}. The session is restored to an not
|
||||||
|
|||||||
@@ -32,13 +32,4 @@ import java.nio.channels.ReadableByteChannel;
|
|||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface DownloadChannel extends HttpChannel, ReadableByteChannel {
|
public interface DownloadChannel extends HttpChannel, ReadableByteChannel {
|
||||||
/**
|
|
||||||
* @return the file size
|
|
||||||
*/
|
|
||||||
long getFilesize();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the file name
|
|
||||||
*/
|
|
||||||
String getFilename();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,14 @@ package com.rogiel.httpchannel.service;
|
|||||||
|
|
||||||
import java.io.IOException;
|
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.Downloader.DownloaderConfiguration;
|
||||||
import com.rogiel.httpchannel.service.exception.DownloadLimitExceededException;
|
import com.rogiel.httpchannel.service.exception.DownloadLimitExceededException;
|
||||||
import com.rogiel.httpchannel.service.exception.DownloadLinkNotFoundException;
|
import com.rogiel.httpchannel.service.exception.DownloadLinkNotFoundException;
|
||||||
import com.rogiel.httpchannel.service.exception.DownloadNotAuthorizedException;
|
import com.rogiel.httpchannel.service.exception.DownloadNotAuthorizedException;
|
||||||
import com.rogiel.httpchannel.service.exception.DownloadNotResumableException;
|
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.
|
* This interfaces provides downloading for an service.
|
||||||
@@ -42,7 +43,8 @@ public interface Downloader<C extends DownloaderConfiguration> {
|
|||||||
* very unlikely to be done. The most common usage usage scenario for this
|
* very unlikely to be done. The most common usage usage scenario for this
|
||||||
* is when an {@link DownloadNotResumableException} is thrown and you wish
|
* is when an {@link DownloadNotResumableException} is thrown and you wish
|
||||||
* to restart the download from start giving <tt>position</tt> equal to
|
* to restart the download from start giving <tt>position</tt> equal to
|
||||||
* zero.
|
* zero, in such scenario, reutilizing the same {@link Downloader} instance
|
||||||
|
* is safe.
|
||||||
* <p>
|
* <p>
|
||||||
* Please remember to close the channel by calling
|
* Please remember to close the channel by calling
|
||||||
* {@link DownloadChannel#close()}, otherwise some of the resources (such as
|
* {@link DownloadChannel#close()}, otherwise some of the resources (such as
|
||||||
@@ -70,15 +72,19 @@ public interface Downloader<C extends DownloaderConfiguration> {
|
|||||||
* @throws DownloadNotResumableException
|
* @throws DownloadNotResumableException
|
||||||
* if the download cannot be started at <tt>position</tt>. Will
|
* if the download cannot be started at <tt>position</tt>. Will
|
||||||
* only be thrown if <tt>position > 0</tt>.
|
* only be thrown if <tt>position > 0</tt>.
|
||||||
* @throws UnresolvedCaptchaException
|
* @throws UnsolvableCaptchaServiceException
|
||||||
* if the service required captcha resolving but no
|
* 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
|
* 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)
|
DownloadChannel openChannel(DownloadListener listener, long position)
|
||||||
throws IOException, DownloadLinkNotFoundException,
|
throws IOException, DownloadLinkNotFoundException,
|
||||||
DownloadLimitExceededException, DownloadNotAuthorizedException,
|
DownloadLimitExceededException, DownloadNotAuthorizedException,
|
||||||
DownloadNotResumableException, UnresolvedCaptchaException;
|
DownloadNotResumableException, UnsolvableCaptchaServiceException,
|
||||||
|
NoCaptchaServiceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a new {@link DownloadChannel} with not listener. For more details,
|
* Opens a new {@link DownloadChannel} with not listener. For more details,
|
||||||
@@ -102,14 +108,26 @@ public interface Downloader<C extends DownloaderConfiguration> {
|
|||||||
* @throws DownloadNotResumableException
|
* @throws DownloadNotResumableException
|
||||||
* if the download cannot be started at <tt>position</tt>. Will
|
* if the download cannot be started at <tt>position</tt>. Will
|
||||||
* only be thrown if <tt>position > 0</tt>.
|
* only be thrown if <tt>position > 0</tt>.
|
||||||
|
* @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,
|
DownloadChannel openChannel(long position) throws IOException,
|
||||||
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
||||||
DownloadNotAuthorizedException, DownloadNotResumableException;
|
DownloadNotAuthorizedException, DownloadNotResumableException,
|
||||||
|
UnsolvableCaptchaServiceException, NoCaptchaServiceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a new {@link DownloadChannel} positioned at start. For more
|
* Opens a new {@link DownloadChannel} positioned at start. For more
|
||||||
* details, see {@link #openChannel(DownloadListener, long)}
|
* details, see {@link #openChannel(DownloadListener, long)}
|
||||||
|
* <p>
|
||||||
|
* Note that {@link DownloadNotResumableException} is never thrown because
|
||||||
|
* this channel always starts at <code>0</code> offset.
|
||||||
*
|
*
|
||||||
* @param listener
|
* @param listener
|
||||||
* the listener to keep a track on the download progress
|
* the listener to keep a track on the download progress
|
||||||
@@ -125,14 +143,25 @@ public interface Downloader<C extends DownloaderConfiguration> {
|
|||||||
* @throws DownloadNotAuthorizedException
|
* @throws DownloadNotAuthorizedException
|
||||||
* if the user (or guest) account does not have necessary rights
|
* if the user (or guest) account does not have necessary rights
|
||||||
* to download the file
|
* 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,
|
DownloadChannel openChannel(DownloadListener listener) throws IOException,
|
||||||
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
||||||
DownloadNotAuthorizedException;
|
DownloadNotAuthorizedException, UnsolvableCaptchaServiceException,
|
||||||
|
NoCaptchaServiceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens a new {@link DownloadChannel} with not listener and positioned at
|
* Opens a new {@link DownloadChannel} with not listener and positioned at
|
||||||
* start. For more details, see {@link #openChannel(DownloadListener, long)}
|
* start. For more details, see {@link #openChannel(DownloadListener, long)}
|
||||||
|
* <p>
|
||||||
|
* Note that {@link DownloadNotResumableException} is never thrown because
|
||||||
|
* this channel always starts at <code>0</code> offset.
|
||||||
*
|
*
|
||||||
* @return the {@link DownloadChannel} instance
|
* @return the {@link DownloadChannel} instance
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
@@ -146,10 +175,18 @@ public interface Downloader<C extends DownloaderConfiguration> {
|
|||||||
* @throws DownloadNotAuthorizedException
|
* @throws DownloadNotAuthorizedException
|
||||||
* if the user (or guest) account does not have necessary rights
|
* if the user (or guest) account does not have necessary rights
|
||||||
* to download the file
|
* 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,
|
DownloadChannel openChannel() throws IOException,
|
||||||
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
||||||
DownloadNotAuthorizedException;
|
DownloadNotAuthorizedException, UnsolvableCaptchaServiceException,
|
||||||
|
NoCaptchaServiceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns this {@link Downloader} configuration.
|
* Returns this {@link Downloader} configuration.
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.rogiel.httpchannel.service;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.nio.channels.Channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface HttpChannel extends Channel, Closeable {
|
||||||
|
/**
|
||||||
|
* @return the file size
|
||||||
|
*/
|
||||||
|
long getFilesize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the file name
|
||||||
|
*/
|
||||||
|
String getFilename();
|
||||||
|
}
|
||||||
@@ -16,7 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.rogiel.httpchannel.service;
|
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
|
* Base interface for all the services. Whenever the operation suported by the
|
||||||
@@ -53,13 +54,13 @@ public interface Service extends Cloneable {
|
|||||||
int getMinorVersion();
|
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.
|
* even after an transfer has begun.
|
||||||
*
|
*
|
||||||
* @param resolver
|
* @param captchaService
|
||||||
* the captcha resolver
|
* the captcha service
|
||||||
*/
|
*/
|
||||||
void setCaptchaResolver(CaptchaResolver resolver);
|
void setCaptchaService(CaptchaService<? extends Captcha> captchaService);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a cloned version of this service
|
* @return a cloned version of this service
|
||||||
|
|||||||
@@ -36,16 +36,6 @@ import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException;
|
|||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public interface UploadChannel extends HttpChannel, WritableByteChannel {
|
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
|
* The link is located after you call {@link UploadChannel#close()}, but it
|
||||||
* can only be retrieved by calling this method. If {@link #close()} throwed
|
* can only be retrieved by calling this method. If {@link #close()} throwed
|
||||||
|
|||||||
@@ -18,9 +18,10 @@ package com.rogiel.httpchannel.service;
|
|||||||
|
|
||||||
import java.io.IOException;
|
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.Uploader.UploaderConfiguration;
|
||||||
import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException;
|
import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interfaces provides uploading for an service.
|
* This interfaces provides uploading for an service.
|
||||||
@@ -48,12 +49,16 @@ public interface Uploader<C extends UploaderConfiguration> {
|
|||||||
* @return the {@link UploadChannel} instance
|
* @return the {@link UploadChannel} instance
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if any IO error occur
|
* if any IO error occur
|
||||||
* @throws UnresolvedCaptchaException
|
* @throws UnsolvableCaptchaServiceException
|
||||||
* if the service required captcha resolving but no
|
* 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
|
* 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.
|
* Returns this {@link Uploader} configuration.
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.rogiel.httpchannel.service.exception;
|
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
|
* captcha
|
||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
|||||||
@@ -16,21 +16,21 @@
|
|||||||
*/
|
*/
|
||||||
package com.rogiel.httpchannel.service.exception;
|
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
|
* captcha
|
||||||
*
|
*
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
*/
|
*/
|
||||||
public class UnresolvedCaptchaException extends ChannelServiceException {
|
public class NoCaptchaServiceException extends ChannelServiceException {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new empty instance of this exception
|
* Creates a new empty instance of this exception
|
||||||
*/
|
*/
|
||||||
public UnresolvedCaptchaException() {
|
public NoCaptchaServiceException() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ public class UnresolvedCaptchaException extends ChannelServiceException {
|
|||||||
* @param cause
|
* @param cause
|
||||||
* the root cause
|
* the root cause
|
||||||
*/
|
*/
|
||||||
public UnresolvedCaptchaException(String message, Throwable cause) {
|
public NoCaptchaServiceException(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ public class UnresolvedCaptchaException extends ChannelServiceException {
|
|||||||
* @param message
|
* @param message
|
||||||
* the message
|
* the message
|
||||||
*/
|
*/
|
||||||
public UnresolvedCaptchaException(String message) {
|
public NoCaptchaServiceException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ public class UnresolvedCaptchaException extends ChannelServiceException {
|
|||||||
* @param cause
|
* @param cause
|
||||||
* the root cause
|
* the root cause
|
||||||
*/
|
*/
|
||||||
public UnresolvedCaptchaException(Throwable cause) {
|
public NoCaptchaServiceException(Throwable cause) {
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<artifactId>httpchannel-captcha</artifactId>
|
||||||
|
<groupId>com.rogiel.httpchannel</groupId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<relativePath>..</relativePath>
|
||||||
|
</parent>
|
||||||
|
<groupId>com.rogiel.httpchannel.captcha</groupId>
|
||||||
|
<artifactId>httpchannel-captcha-captchatrader</artifactId>
|
||||||
|
<name>HttpChannel/Captcha/CaptchaTrader</name>
|
||||||
|
<description>This module provides an CaptchService that resolves image captchas.</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>4.1.2</version>
|
||||||
|
<type>jar</type>
|
||||||
|
<scope>compile</scope>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>commons-logging</groupId>
|
||||||
|
<artifactId>commons-logging</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpmime</artifactId>
|
||||||
|
<version>4.1.2</version>
|
||||||
|
<type>jar</type>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>1.3.2</version>
|
||||||
|
<type>jar</type>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.googlecode.json-simple</groupId>
|
||||||
|
<artifactId>json-simple</artifactId>
|
||||||
|
<version>1.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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<Object> 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
|
||||||
|
* <code>true</code> 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<Object> validate(List<Object> response)
|
||||||
|
throws CaptchaTraderException {
|
||||||
|
if ((long) response.get(0) == -1) {
|
||||||
|
throw translateException((String) response.get(1));
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<Object> execute(HttpUriRequest request) throws IOException {
|
||||||
|
final HttpResponse response = client.execute(request);
|
||||||
|
try {
|
||||||
|
return (List<Object>) 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.captchatrader.exception.CaptchaTraderException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.captchatrader.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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 <code>null</code> password.
|
||||||
|
*
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<artifactId>httpchannel-capcha</artifactId>
|
|
||||||
<groupId>com.rogiel.httpchannel</groupId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
<relativePath>..</relativePath>
|
|
||||||
</parent>
|
|
||||||
<artifactId>httpchannel-captcha-recaptcha</artifactId>
|
|
||||||
<name>HttpChannel/CaptchaService/ReCaptcha</name>
|
|
||||||
<description>This module provides captcha resolving for Google ReCaptcha</description>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.rogiel.httpchannel</groupId>
|
|
||||||
<artifactId>httpchannel-api</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.rogiel.httpchannel</groupId>
|
|
||||||
<artifactId>httpchannel-util</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class BaseReCaptchaService extends
|
|
||||||
AbstractImageCaptchaService<ReCaptcha> {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package com.rogiel.httpchannel.captcha.impl;
|
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
import com.rogiel.httpchannel.captcha.AbstractImageCaptcha;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ReCaptcha extends AbstractImageCaptcha {
|
|
||||||
public ReCaptcha(URL url, String ID) {
|
|
||||||
super(url, ID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -14,6 +14,13 @@
|
|||||||
<description>This module provides implementations for captcha resolving</description>
|
<description>This module provides implementations for captcha resolving</description>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>httpchannel-captcha-recaptcha</module>
|
<module>httpchannel-captcha-captchatrader</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.rogiel.httpchannel</groupId>
|
||||||
|
<artifactId>httpchannel-api</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
1
httpchannel-captcha/src/test/resources/.gitignore
vendored
Normal file
1
httpchannel-captcha/src/test/resources/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/captchatrader.properties
|
||||||
@@ -10,11 +10,4 @@
|
|||||||
<groupId>com.rogiel.httpchannel.services</groupId>
|
<groupId>com.rogiel.httpchannel.services</groupId>
|
||||||
<name>HttpChannel/Service/DepositFiles</name>
|
<name>HttpChannel/Service/DepositFiles</name>
|
||||||
<description>Provides upload access to depositfiles.com</description>
|
<description>Provides upload access to depositfiles.com</description>
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.rogiel.httpchannel</groupId>
|
|
||||||
<artifactId>httpchannel-captcha-recaptcha</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
</project>
|
||||||
@@ -5,8 +5,9 @@ import java.util.concurrent.ExecutionException;
|
|||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import com.rogiel.httpchannel.captcha.impl.EmbeddedReCaptchaService;
|
import com.rogiel.httpchannel.captcha.ImageCaptcha;
|
||||||
import com.rogiel.httpchannel.captcha.impl.ReCaptcha;
|
import com.rogiel.httpchannel.captcha.ReCaptchaExtractor;
|
||||||
|
import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException;
|
||||||
import com.rogiel.httpchannel.service.AbstractAuthenticator;
|
import com.rogiel.httpchannel.service.AbstractAuthenticator;
|
||||||
import com.rogiel.httpchannel.service.AbstractHttpService;
|
import com.rogiel.httpchannel.service.AbstractHttpService;
|
||||||
import com.rogiel.httpchannel.service.AbstractUploader;
|
import com.rogiel.httpchannel.service.AbstractUploader;
|
||||||
@@ -50,8 +51,6 @@ public class DepositFilesService extends AbstractHttpService implements
|
|||||||
private static final Pattern VALID_LOGIN_REDIRECT = Pattern
|
private static final Pattern VALID_LOGIN_REDIRECT = Pattern
|
||||||
.compile("window.location.href");
|
.compile("window.location.href");
|
||||||
|
|
||||||
private final EmbeddedReCaptchaService captchaService = new EmbeddedReCaptchaService();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServiceID getID() {
|
public ServiceID getID() {
|
||||||
return SERVICE_ID;
|
return SERVICE_ID;
|
||||||
@@ -137,12 +136,15 @@ public class DepositFilesService extends AbstractHttpService implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UploadChannel openChannel() throws IOException {
|
public UploadChannel openChannel() throws IOException {
|
||||||
|
logger.debug("Starting upload to depositfiles.com");
|
||||||
final HTMLPage page = get("http://www.depositfiles.com/").asPage();
|
final HTMLPage page = get("http://www.depositfiles.com/").asPage();
|
||||||
|
|
||||||
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||||
final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER");
|
final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER");
|
||||||
final String maxFileSize = page.getInputValue("MAX_FILE_SIZE");
|
final String maxFileSize = page.getInputValue("MAX_FILE_SIZE");
|
||||||
|
|
||||||
|
logger.debug("Upload URL: {}, ID: {}", url, uploadID);
|
||||||
|
|
||||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||||
uploadFuture = multipartPost(url).parameter("files", channel)
|
uploadFuture = multipartPost(url).parameter("files", channel)
|
||||||
.parameter("go", true)
|
.parameter("go", true)
|
||||||
@@ -178,13 +180,16 @@ public class DepositFilesService extends AbstractHttpService implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void login() throws IOException {
|
public void login() throws IOException {
|
||||||
|
logger.debug("Authenticating into depositfiles.com");
|
||||||
HTMLPage page = post("http://depositfiles.com/login.php?return=%2F")
|
HTMLPage page = post("http://depositfiles.com/login.php?return=%2F")
|
||||||
.parameter("go", true)
|
.parameter("go", true)
|
||||||
.parameter("login", credential.getUsername())
|
.parameter("login", credential.getUsername())
|
||||||
.parameter("password", credential.getPassword()).asPage();
|
.parameter("password", credential.getPassword()).asPage();
|
||||||
|
|
||||||
final ReCaptcha captcha = captchaService.create(page);
|
final ImageCaptcha captcha = ReCaptchaExtractor.extractCaptcha(
|
||||||
|
page, http);
|
||||||
if (captcha != null) {
|
if (captcha != null) {
|
||||||
|
logger.debug("Service is requiring CAPTCHA {}", captcha);
|
||||||
resolveCaptcha(captcha);
|
resolveCaptcha(captcha);
|
||||||
page = post("http://depositfiles.com/login.php?return=%2F")
|
page = post("http://depositfiles.com/login.php?return=%2F")
|
||||||
.parameter("go", true)
|
.parameter("go", true)
|
||||||
@@ -195,9 +200,17 @@ public class DepositFilesService extends AbstractHttpService implements
|
|||||||
captcha.getAnswer()).asPage();
|
captcha.getAnswer()).asPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!page.contains(VALID_LOGIN_REDIRECT))
|
final ImageCaptcha testCaptcha = ReCaptchaExtractor.extractCaptcha(
|
||||||
throw new AuthenticationInvalidCredentialException();
|
page, http);
|
||||||
return;
|
if (testCaptcha != null) {
|
||||||
|
captchaService.invalid(captcha);
|
||||||
|
throw new UnsolvableCaptchaServiceException();
|
||||||
|
} else {
|
||||||
|
captchaService.valid(captcha);
|
||||||
|
if (!page.contains(VALID_LOGIN_REDIRECT))
|
||||||
|
throw new AuthenticationInvalidCredentialException();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
13
httpchannel-service/httpchannel-service-filesonic/pom.xml
Normal file
13
httpchannel-service/httpchannel-service-filesonic/pom.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<artifactId>httpchannel-service</artifactId>
|
||||||
|
<groupId>com.rogiel.httpchannel</groupId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<relativePath>..</relativePath>
|
||||||
|
</parent>
|
||||||
|
<artifactId>httpchannel-service-filesonic</artifactId>
|
||||||
|
<groupId>com.rogiel.httpchannel.services</groupId>
|
||||||
|
<name>HttpChannel/Service/FileSonic</name>
|
||||||
|
<description>Provides download and upload access to filesonic.com</description>
|
||||||
|
</project>
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*/
|
||||||
|
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 extends FSAPI> T execute(Class<T> 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.rogiel.httpchannel.filesonic.xml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FSAPI {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*/
|
||||||
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
|
public abstract class FSResponse {
|
||||||
|
@XmlElement(name = "status")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
public String getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,206 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of seedbox <github.com/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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
public class FileSonicService extends AbstractHttpService implements Service,
|
||||||
|
UploadService<NullUploaderConfiguration>,
|
||||||
|
AuthenticationService<NullAuthenticatorConfiguration> {
|
||||||
|
/**
|
||||||
|
* 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<NullUploaderConfiguration> getUploader(String filename,
|
||||||
|
long filesize, NullUploaderConfiguration configuration) {
|
||||||
|
return new UploaderImpl(filename, filesize, configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Uploader<NullUploaderConfiguration> 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<UploaderCapability> getUploadCapabilities() {
|
||||||
|
return new CapabilityMatrix<UploaderCapability>(
|
||||||
|
UploaderCapability.NON_PREMIUM_ACCOUNT_UPLOAD,
|
||||||
|
UploaderCapability.PREMIUM_ACCOUNT_UPLOAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authenticator<NullAuthenticatorConfiguration> getAuthenticator(
|
||||||
|
Credential credential, NullAuthenticatorConfiguration configuration) {
|
||||||
|
return new AuthenticatorImpl(credential, configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authenticator<NullAuthenticatorConfiguration> getAuthenticator(
|
||||||
|
Credential credential) {
|
||||||
|
return getAuthenticator(credential, newAuthenticatorConfiguration());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NullAuthenticatorConfiguration newAuthenticatorConfiguration() {
|
||||||
|
return NullAuthenticatorConfiguration.SHARED_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CapabilityMatrix<AuthenticatorCapability> getAuthenticationCapability() {
|
||||||
|
return new CapabilityMatrix<AuthenticatorCapability>();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected class UploaderImpl extends
|
||||||
|
AbstractUploader<NullUploaderConfiguration> implements
|
||||||
|
Uploader<NullUploaderConfiguration>,
|
||||||
|
LinkedUploadChannelCloseCallback {
|
||||||
|
private Future<String> 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<NullAuthenticatorConfiguration> implements
|
||||||
|
Authenticator<NullAuthenticatorConfiguration> {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
com.rogiel.httpchannel.service.impl.FileSonicService
|
||||||
@@ -196,9 +196,12 @@ public class HotFileService extends AbstractHttpService implements Service,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UploadChannel openChannel() throws IOException {
|
public UploadChannel openChannel() throws IOException {
|
||||||
|
logger.debug("Starting upload to hotfile.com");
|
||||||
final HTMLPage page = get("http://www.hotfile.com/").asPage();
|
final HTMLPage page = get("http://www.hotfile.com/").asPage();
|
||||||
final String action = page.findFormAction(UPLOAD_URL_PATTERN);
|
final String action = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||||
|
|
||||||
|
logger.debug("Upload URL is {}", action);
|
||||||
|
|
||||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||||
|
|
||||||
uploadFuture = multipartPost(action)
|
uploadFuture = multipartPost(action)
|
||||||
@@ -227,6 +230,7 @@ public class HotFileService extends AbstractHttpService implements Service,
|
|||||||
@Override
|
@Override
|
||||||
public DownloadChannel openChannel(DownloadListener listener,
|
public DownloadChannel openChannel(DownloadListener listener,
|
||||||
long position) throws IOException {
|
long position) throws IOException {
|
||||||
|
logger.debug("Downloading {} from hotfile.com", url);
|
||||||
final HTMLPage page = get(url).asPage();
|
final HTMLPage page = get(url).asPage();
|
||||||
|
|
||||||
// // try to find timer
|
// // try to find timer
|
||||||
@@ -243,6 +247,7 @@ public class HotFileService extends AbstractHttpService implements Service,
|
|||||||
|
|
||||||
final String downloadUrl = page
|
final String downloadUrl = page
|
||||||
.findLink(DOWNLOAD_DIRECT_LINK_PATTERN);
|
.findLink(DOWNLOAD_DIRECT_LINK_PATTERN);
|
||||||
|
logger.debug("Download link is {}", downloadUrl);
|
||||||
// final String tmHash = PatternUtils.find(DOWNLOAD_TMHASH_PATTERN,
|
// final String tmHash = PatternUtils.find(DOWNLOAD_TMHASH_PATTERN,
|
||||||
// content);F
|
// content);F
|
||||||
if (downloadUrl != null && downloadUrl.length() > 0) {
|
if (downloadUrl != null && downloadUrl.length() > 0) {
|
||||||
@@ -254,49 +259,6 @@ public class HotFileService extends AbstractHttpService implements Service,
|
|||||||
|
|
||||||
return new InputStreamDownloadChannel(downloadResponse
|
return new InputStreamDownloadChannel(downloadResponse
|
||||||
.getEntity().getContent(), contentLength, filename);
|
.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<NameValuePair> pairs = new
|
|
||||||
// ArrayList<NameValuePair>();
|
|
||||||
// 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 {
|
} else {
|
||||||
throw new IOException("Download link not found");
|
throw new IOException("Download link not found");
|
||||||
}
|
}
|
||||||
@@ -313,6 +275,7 @@ public class HotFileService extends AbstractHttpService implements Service,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void login() throws ClientProtocolException, IOException {
|
public void login() throws ClientProtocolException, IOException {
|
||||||
|
logger.debug("Authenticating hotfile.com");
|
||||||
HTMLPage page = post("http://www.hotfile.com/login.php")
|
HTMLPage page = post("http://www.hotfile.com/login.php")
|
||||||
.parameter("returnto", "/index.php")
|
.parameter("returnto", "/index.php")
|
||||||
.parameter("user", credential.getUsername())
|
.parameter("user", credential.getUsername())
|
||||||
|
|||||||
@@ -205,10 +205,12 @@ public class MegaUploadService extends AbstractHttpService implements Service,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UploadChannel openChannel() throws IOException {
|
public UploadChannel openChannel() throws IOException {
|
||||||
|
logger.debug("Starting upload to megaupload.com");
|
||||||
final HTMLPage page = get("http://www.megaupload.com/multiupload/")
|
final HTMLPage page = get("http://www.megaupload.com/multiupload/")
|
||||||
.asPage();
|
.asPage();
|
||||||
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||||
|
logger.debug("Upload URL is {}", url);
|
||||||
|
|
||||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||||
uploadFuture = multipartPost(url)
|
uploadFuture = multipartPost(url)
|
||||||
.parameter("multimessage_0", configuration.description())
|
.parameter("multimessage_0", configuration.description())
|
||||||
@@ -240,11 +242,13 @@ public class MegaUploadService extends AbstractHttpService implements Service,
|
|||||||
@Override
|
@Override
|
||||||
public DownloadChannel openChannel(DownloadListener listener,
|
public DownloadChannel openChannel(DownloadListener listener,
|
||||||
long position) throws IOException {
|
long position) throws IOException {
|
||||||
|
logger.debug("Starting {} download from megaupload.com", url);
|
||||||
HttpResponse response = get(url).request();
|
HttpResponse response = get(url).request();
|
||||||
|
|
||||||
// disable direct downloads, we don't support them!
|
// disable direct downloads, we don't support them!
|
||||||
if (response.getEntity().getContentType().getValue()
|
if (response.getEntity().getContentType().getValue()
|
||||||
.equals("application/octet-stream")) {
|
.equals("application/octet-stream")) {
|
||||||
|
logger.debug("Direct download is enabled, deactivating");
|
||||||
// close connection
|
// close connection
|
||||||
response.getEntity().getContent().close();
|
response.getEntity().getContent().close();
|
||||||
|
|
||||||
@@ -263,6 +267,7 @@ public class MegaUploadService extends AbstractHttpService implements Service,
|
|||||||
// try to find timer
|
// try to find timer
|
||||||
int timer = page.findScriptAsInt(DOWNLOAD_TIMER, 1);
|
int timer = page.findScriptAsInt(DOWNLOAD_TIMER, 1);
|
||||||
if (timer > 0 && configuration.getRespectWaitTime()) {
|
if (timer > 0 && configuration.getRespectWaitTime()) {
|
||||||
|
logger.debug("");
|
||||||
timer(listener, timer * 1000);
|
timer(listener, timer * 1000);
|
||||||
}
|
}
|
||||||
final String downloadUrl = page
|
final String downloadUrl = page
|
||||||
@@ -299,6 +304,7 @@ public class MegaUploadService extends AbstractHttpService implements Service,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void login() throws IOException {
|
public void login() throws IOException {
|
||||||
|
logger.debug("Starting login to megaupload.com");
|
||||||
final HTMLPage page = post("http://www.megaupload.com/?c=login")
|
final HTMLPage page = post("http://www.megaupload.com/?c=login")
|
||||||
.parameter("login", true)
|
.parameter("login", true)
|
||||||
.parameter("username", credential.getUsername())
|
.parameter("username", credential.getUsername())
|
||||||
|
|||||||
@@ -183,8 +183,10 @@ public class MultiUploadService extends AbstractHttpService implements Service,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UploadChannel openChannel() throws IOException {
|
public UploadChannel openChannel() throws IOException {
|
||||||
|
logger.debug("Starting upload to multiupload.com");
|
||||||
final String url = get("http://www.multiupload.com/").asPage()
|
final String url = get("http://www.multiupload.com/").asPage()
|
||||||
.findFormAction(UPLOAD_URL_PATTERN);
|
.findFormAction(UPLOAD_URL_PATTERN);
|
||||||
|
logger.debug("Upload URL is {}", url);
|
||||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||||
|
|
||||||
PostMultipartRequest request = multipartPost(url).parameter(
|
PostMultipartRequest request = multipartPost(url).parameter(
|
||||||
@@ -192,6 +194,7 @@ public class MultiUploadService extends AbstractHttpService implements Service,
|
|||||||
"file_0", channel);
|
"file_0", channel);
|
||||||
for (final MultiUploadMirrorService mirror : configuration
|
for (final MultiUploadMirrorService mirror : configuration
|
||||||
.uploadServices()) {
|
.uploadServices()) {
|
||||||
|
logger.debug("Adding {} as mirror", mirror.name());
|
||||||
request.parameter("service_" + mirror.id, 1);
|
request.parameter("service_" + mirror.id, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,6 +207,7 @@ public class MultiUploadService extends AbstractHttpService implements Service,
|
|||||||
try {
|
try {
|
||||||
final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN,
|
final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN,
|
||||||
uploadFuture.get(), 1);
|
uploadFuture.get(), 1);
|
||||||
|
logger.debug("Upload to multiupload.com finished");
|
||||||
if (linkId == null)
|
if (linkId == null)
|
||||||
return null;
|
return null;
|
||||||
return new StringBuilder("http://www.multiupload.com/").append(
|
return new StringBuilder("http://www.multiupload.com/").append(
|
||||||
@@ -231,6 +235,7 @@ public class MultiUploadService extends AbstractHttpService implements Service,
|
|||||||
DownloadNotAuthorizedException, DownloadNotResumableException {
|
DownloadNotAuthorizedException, DownloadNotResumableException {
|
||||||
final HTMLPage page = get(url).asPage();
|
final HTMLPage page = get(url).asPage();
|
||||||
final String link = page.findLink(DIRECT_DOWNLOAD_LINK_PATTERN);
|
final String link = page.findLink(DIRECT_DOWNLOAD_LINK_PATTERN);
|
||||||
|
logger.debug("Direct download link is {}", link);
|
||||||
if (link == null)
|
if (link == null)
|
||||||
throw new DownloadLinkNotFoundException();
|
throw new DownloadLinkNotFoundException();
|
||||||
return download(get(link).position(position));
|
return download(get(link).position(position));
|
||||||
|
|||||||
@@ -10,11 +10,4 @@
|
|||||||
<groupId>com.rogiel.httpchannel.services</groupId>
|
<groupId>com.rogiel.httpchannel.services</groupId>
|
||||||
<name>HttpChannel/Service/UploadHere</name>
|
<name>HttpChannel/Service/UploadHere</name>
|
||||||
<description>Provides upload access to uploadhere.com</description>
|
<description>Provides upload access to uploadhere.com</description>
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.rogiel.httpchannel</groupId>
|
|
||||||
<artifactId>httpchannel-captcha-recaptcha</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
</project>
|
||||||
@@ -6,8 +6,8 @@ import java.util.concurrent.ExecutionException;
|
|||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import com.rogiel.httpchannel.captcha.impl.AjaxReCaptchaService;
|
import com.rogiel.httpchannel.captcha.ImageCaptcha;
|
||||||
import com.rogiel.httpchannel.captcha.impl.ReCaptcha;
|
import com.rogiel.httpchannel.captcha.ReCaptchaExtractor;
|
||||||
import com.rogiel.httpchannel.service.AbstractAuthenticator;
|
import com.rogiel.httpchannel.service.AbstractAuthenticator;
|
||||||
import com.rogiel.httpchannel.service.AbstractHttpDownloader;
|
import com.rogiel.httpchannel.service.AbstractHttpDownloader;
|
||||||
import com.rogiel.httpchannel.service.AbstractHttpService;
|
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 static final String INVALID_LOGIN_STRING = "Incorrect username and/or password. Please try again!";
|
||||||
|
|
||||||
private final AjaxReCaptchaService captchaService = new AjaxReCaptchaService();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServiceID getID() {
|
public ServiceID getID() {
|
||||||
return SERVICE_ID;
|
return SERVICE_ID;
|
||||||
@@ -190,6 +188,9 @@ public class UploadHereService extends AbstractHttpService implements Service,
|
|||||||
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||||
final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER");
|
final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER");
|
||||||
|
|
||||||
|
logger.debug("Upload URL: {}, UserCookie: {}, UploadID: {}",
|
||||||
|
new Object[] { url, userCookie, uploadID });
|
||||||
|
|
||||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||||
uploadFuture = multipartPost(url).parameter("file_0", channel)
|
uploadFuture = multipartPost(url).parameter("file_0", channel)
|
||||||
.parameter("u", userCookie)
|
.parameter("u", userCookie)
|
||||||
@@ -202,6 +203,7 @@ public class UploadHereService extends AbstractHttpService implements Service,
|
|||||||
try {
|
try {
|
||||||
final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN,
|
final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN,
|
||||||
uploadFuture.get(), 1);
|
uploadFuture.get(), 1);
|
||||||
|
logger.debug("Upload to uploadhere.com finished");
|
||||||
if (linkId == null)
|
if (linkId == null)
|
||||||
return null;
|
return null;
|
||||||
return new StringBuilder("http://www.uploadhere.com/").append(
|
return new StringBuilder("http://www.uploadhere.com/").append(
|
||||||
@@ -230,15 +232,24 @@ public class UploadHereService extends AbstractHttpService implements Service,
|
|||||||
HTMLPage page = get(url).asPage();
|
HTMLPage page = get(url).asPage();
|
||||||
|
|
||||||
final int waitTime = page.findScriptAsInt(TIMER_PATTERN, 1) * 1000;
|
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) {
|
if (captcha != null) {
|
||||||
|
logger.debug("Service is requiring CAPTCHA {}", captcha);
|
||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
resolveCaptcha(captcha);
|
resolveCaptcha(captcha);
|
||||||
|
|
||||||
final long delta = System.currentTimeMillis() - start;
|
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);
|
timer(listener, waitTime - delta);
|
||||||
|
} else {
|
||||||
|
logger.debug("CAPTCHA solving took longer than timer, skipping it");
|
||||||
|
}
|
||||||
|
|
||||||
String content = post(url)
|
String content = post(url)
|
||||||
.parameter("recaptcha_challenge_field", captcha.getID())
|
.parameter("recaptcha_challenge_field", captcha.getID())
|
||||||
@@ -246,10 +257,15 @@ public class UploadHereService extends AbstractHttpService implements Service,
|
|||||||
captcha.getAnswer()).asString();
|
captcha.getAnswer()).asString();
|
||||||
String downloadLink = PatternUtils.find(
|
String downloadLink = PatternUtils.find(
|
||||||
DIERCT_DOWNLOAD_URL_PATTERN, content, 1);
|
DIERCT_DOWNLOAD_URL_PATTERN, content, 1);
|
||||||
if (downloadLink == null)
|
if (downloadLink == null) {
|
||||||
|
captchaService.invalid(captcha);
|
||||||
throw new InvalidCaptchaException();
|
throw new InvalidCaptchaException();
|
||||||
|
} else {
|
||||||
|
captchaService.valid(captcha);
|
||||||
|
}
|
||||||
downloadLink = downloadLink.replaceAll(Pattern.quote("\\/"),
|
downloadLink = downloadLink.replaceAll(Pattern.quote("\\/"),
|
||||||
"/");
|
"/");
|
||||||
|
logger.debug("Direct download URL is {}", downloadLink);
|
||||||
return download(get(downloadLink).position(position));
|
return download(get(downloadLink).position(position));
|
||||||
}
|
}
|
||||||
throw new DownloadLinkNotFoundException();
|
throw new DownloadLinkNotFoundException();
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
<modelVersion>4.0.0</modelVersion>
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>httpchannel-service</artifactId>
|
<parent>
|
||||||
<groupId>com.rogiel.httpchannel</groupId>
|
<artifactId>httpchannel-service</artifactId>
|
||||||
<version>1.0.0</version>
|
<groupId>com.rogiel.httpchannel</groupId>
|
||||||
<relativePath>..</relativePath>
|
<version>1.0.0</version>
|
||||||
</parent>
|
<relativePath>..</relativePath>
|
||||||
<artifactId>httpchannel-service-uploadking</artifactId>
|
</parent>
|
||||||
<groupId>com.rogiel.httpchannel.services</groupId>
|
<artifactId>httpchannel-service-uploadking</artifactId>
|
||||||
<name>HttpChannel/Service/UploadKing</name>
|
<groupId>com.rogiel.httpchannel.services</groupId>
|
||||||
<description>Provides upload access to uploadking.com</description>
|
<name>HttpChannel/Service/UploadKing</name>
|
||||||
<dependencies>
|
<description>Provides upload access to uploadking.com</description>
|
||||||
<dependency>
|
<dependencies>
|
||||||
<groupId>com.rogiel.httpchannel</groupId>
|
<dependency>
|
||||||
<artifactId>httpchannel-captcha-recaptcha</artifactId>
|
<groupId>com.rogiel.httpchannel.captcha</groupId>
|
||||||
<version>1.0.0</version>
|
<artifactId>httpchannel-captcha-captchatrader</artifactId>
|
||||||
</dependency>
|
<version>1.0.0</version>
|
||||||
</dependencies>
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@@ -6,8 +6,8 @@ import java.util.concurrent.ExecutionException;
|
|||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import com.rogiel.httpchannel.captcha.impl.AjaxReCaptchaService;
|
import com.rogiel.httpchannel.captcha.ImageCaptcha;
|
||||||
import com.rogiel.httpchannel.captcha.impl.ReCaptcha;
|
import com.rogiel.httpchannel.captcha.ReCaptchaExtractor;
|
||||||
import com.rogiel.httpchannel.service.AbstractAuthenticator;
|
import com.rogiel.httpchannel.service.AbstractAuthenticator;
|
||||||
import com.rogiel.httpchannel.service.AbstractHttpDownloader;
|
import com.rogiel.httpchannel.service.AbstractHttpDownloader;
|
||||||
import com.rogiel.httpchannel.service.AbstractHttpService;
|
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 static final String INVALID_LOGIN_STRING = "Incorrect username and/or password. Please try again!";
|
||||||
|
|
||||||
private final AjaxReCaptchaService captchaService = new AjaxReCaptchaService();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ServiceID getID() {
|
public ServiceID getID() {
|
||||||
return SERVICE_ID;
|
return SERVICE_ID;
|
||||||
@@ -190,6 +188,9 @@ public class UploadKingService extends AbstractHttpService implements Service,
|
|||||||
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||||
final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER");
|
final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER");
|
||||||
|
|
||||||
|
logger.debug("Upload URL: {}, UserCookie: {}, UploadID: {}",
|
||||||
|
new Object[] { url, userCookie, uploadID });
|
||||||
|
|
||||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||||
uploadFuture = multipartPost(url).parameter("file", channel)
|
uploadFuture = multipartPost(url).parameter("file", channel)
|
||||||
.parameter("u", userCookie)
|
.parameter("u", userCookie)
|
||||||
@@ -202,6 +203,7 @@ public class UploadKingService extends AbstractHttpService implements Service,
|
|||||||
try {
|
try {
|
||||||
final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN,
|
final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN,
|
||||||
uploadFuture.get(), 1);
|
uploadFuture.get(), 1);
|
||||||
|
logger.debug("Upload to uploadking.com finished");
|
||||||
if (linkId == null)
|
if (linkId == null)
|
||||||
return null;
|
return null;
|
||||||
return new StringBuilder("http://www.uploadking.com/").append(
|
return new StringBuilder("http://www.uploadking.com/").append(
|
||||||
@@ -224,19 +226,29 @@ public class UploadKingService extends AbstractHttpService implements Service,
|
|||||||
@Override
|
@Override
|
||||||
public DownloadChannel openChannel(DownloadListener listener,
|
public DownloadChannel openChannel(DownloadListener listener,
|
||||||
long position) throws IOException {
|
long position) throws IOException {
|
||||||
|
logger.debug("Downloading {} with uploadking.com");
|
||||||
HTMLPage page = get(url).asPage();
|
HTMLPage page = get(url).asPage();
|
||||||
|
|
||||||
final int waitTime = page.findScriptAsInt(TIMER_PATTERN, 1) * 1000;
|
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) {
|
if (captcha != null) {
|
||||||
|
logger.debug("Service is requiring CAPTCHA {}", captcha);
|
||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
|
|
||||||
resolveCaptcha(captcha);
|
resolveCaptcha(captcha);
|
||||||
|
|
||||||
final long delta = System.currentTimeMillis() - start;
|
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);
|
timer(listener, waitTime - delta);
|
||||||
|
} else {
|
||||||
|
logger.debug("CAPTCHA solving took longer than timer, skipping it");
|
||||||
|
}
|
||||||
|
|
||||||
String content = post(url)
|
String content = post(url)
|
||||||
.parameter("recaptcha_challenge_field", captcha.getID())
|
.parameter("recaptcha_challenge_field", captcha.getID())
|
||||||
@@ -244,10 +256,15 @@ public class UploadKingService extends AbstractHttpService implements Service,
|
|||||||
captcha.getAnswer()).asString();
|
captcha.getAnswer()).asString();
|
||||||
String downloadLink = PatternUtils.find(
|
String downloadLink = PatternUtils.find(
|
||||||
DIERCT_DOWNLOAD_URL_PATTERN, content, 1);
|
DIERCT_DOWNLOAD_URL_PATTERN, content, 1);
|
||||||
if (downloadLink == null)
|
if (downloadLink == null) {
|
||||||
|
captchaService.invalid(captcha);
|
||||||
throw new InvalidCaptchaException();
|
throw new InvalidCaptchaException();
|
||||||
|
} else {
|
||||||
|
captchaService.valid(captcha);
|
||||||
|
}
|
||||||
downloadLink = downloadLink.replaceAll(Pattern.quote("\\/"),
|
downloadLink = downloadLink.replaceAll(Pattern.quote("\\/"),
|
||||||
"/");
|
"/");
|
||||||
|
logger.debug("Direct download URL is {}", downloadLink);
|
||||||
return download(get(downloadLink).position(position));
|
return download(get(downloadLink).position(position));
|
||||||
}
|
}
|
||||||
throw new DownloadLinkNotFoundException();
|
throw new DownloadLinkNotFoundException();
|
||||||
|
|||||||
@@ -4,14 +4,20 @@ import static org.junit.Assert.assertTrue;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import junit.framework.Assert;
|
import junit.framework.Assert;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
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.service.UploaderCapability;
|
||||||
import com.rogiel.httpchannel.util.ChannelUtils;
|
import com.rogiel.httpchannel.util.ChannelUtils;
|
||||||
|
|
||||||
@@ -37,26 +43,19 @@ public class UploadKingServiceTest {
|
|||||||
System.out.println(url);
|
System.out.println(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Test
|
@Test
|
||||||
// public void testDownloader() throws IOException {
|
public void testDownloader() throws IOException {
|
||||||
// service.setCaptchaResolver(new CaptchaResolver() {
|
final Properties p = new Properties();
|
||||||
// @Override
|
p.load(Files.newInputStream(
|
||||||
// public boolean resolve(Captcha rawCaptcha) {
|
Paths.get("../../httpchannel-captcha/src/test/resources/captchatrader.properties"),
|
||||||
// final ImageCaptcha captcha = (ImageCaptcha) rawCaptcha;
|
StandardOpenOption.READ));
|
||||||
// System.out.println(captcha.getImageURL());
|
|
||||||
// try {
|
final CaptchaService<?> s = new CaptchaTraderService();
|
||||||
// captcha.setAnswer(new BufferedReader(new InputStreamReader(
|
s.authenticate(p.getProperty("username"), p.getProperty("password"));
|
||||||
// System.in)).readLine());
|
service.setCaptchaService(s);
|
||||||
// System.out.println("Answer is: " + captcha.getAnswer());
|
|
||||||
// return true;
|
final DownloadChannel channel = service.getDownloader(
|
||||||
// } catch (IOException e) {
|
new URL("http://www.uploadking.com/WM3PHD9JAY")).openChannel(0);
|
||||||
// return false;
|
System.out.println(new String(ChannelUtils.toByteArray(channel)));
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// final DownloadChannel channel = service.getDownloader(
|
|
||||||
// new URL("http://www.uploadking.com/WM3PHD9JAY")).openChannel(512);
|
|
||||||
// System.out.println(new String(ChannelUtils.toByteArray(channel)));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
13
httpchannel-service/httpchannel-service-zshare/pom.xml
Normal file
13
httpchannel-service/httpchannel-service-zshare/pom.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<artifactId>httpchannel-service</artifactId>
|
||||||
|
<groupId>com.rogiel.httpchannel</groupId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
<relativePath>..</relativePath>
|
||||||
|
</parent>
|
||||||
|
<artifactId>httpchannel-service-zshare</artifactId>
|
||||||
|
<groupId>com.rogiel.httpchannel.services</groupId>
|
||||||
|
<name>HttpChannel/Service/ZShare</name>
|
||||||
|
<description>Provides download and upload access to zshare.com</description>
|
||||||
|
</project>
|
||||||
@@ -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 <a href="http://www.rogiel.com/">Rogiel</a>
|
||||||
|
* @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<ZShareUploaderConfiguration> getUploader(String filename,
|
||||||
|
// long filesize, ZShareUploaderConfiguration configuration) {
|
||||||
|
// return new UploaderImpl(filename, filesize, configuration);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public Uploader<ZShareUploaderConfiguration> 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<UploaderCapability> getUploadCapabilities() {
|
||||||
|
// return new CapabilityMatrix<UploaderCapability>(
|
||||||
|
// UploaderCapability.UNAUTHENTICATED_UPLOAD,
|
||||||
|
// UploaderCapability.NON_PREMIUM_ACCOUNT_UPLOAD,
|
||||||
|
// UploaderCapability.PREMIUM_ACCOUNT_UPLOAD);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public Downloader<NullDownloaderConfiguration> getDownloader(URL url,
|
||||||
|
// NullDownloaderConfiguration configuration) {
|
||||||
|
// return new DownloaderImpl(url, configuration);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public Downloader<NullDownloaderConfiguration> 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<DownloaderCapability> getDownloadCapabilities() {
|
||||||
|
// return new CapabilityMatrix<DownloaderCapability>(
|
||||||
|
// DownloaderCapability.UNAUTHENTICATED_DOWNLOAD,
|
||||||
|
// DownloaderCapability.UNAUTHENTICATED_RESUME,
|
||||||
|
// DownloaderCapability.NON_PREMIUM_ACCOUNT_DOWNLOAD,
|
||||||
|
// DownloaderCapability.NON_PREMIUM_ACCOUNT_RESUME);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public Authenticator<NullAuthenticatorConfiguration> getAuthenticator(
|
||||||
|
// Credential credential, NullAuthenticatorConfiguration configuration) {
|
||||||
|
// return new AuthenticatorImpl(credential, configuration);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public Authenticator<NullAuthenticatorConfiguration> getAuthenticator(
|
||||||
|
// Credential credential) {
|
||||||
|
// return getAuthenticator(credential, newAuthenticatorConfiguration());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public NullAuthenticatorConfiguration newAuthenticatorConfiguration() {
|
||||||
|
// return NullAuthenticatorConfiguration.SHARED_INSTANCE;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public CapabilityMatrix<AuthenticatorCapability>
|
||||||
|
// getAuthenticationCapability() {
|
||||||
|
// return new CapabilityMatrix<AuthenticatorCapability>();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// protected class UploaderImpl extends
|
||||||
|
// AbstractUploader<ZShareUploaderConfiguration> implements
|
||||||
|
// Uploader<ZShareUploaderConfiguration>,
|
||||||
|
// LinkedUploadChannelCloseCallback {
|
||||||
|
// private Future<String> 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<NullDownloaderConfiguration> implements
|
||||||
|
// Downloader<NullDownloaderConfiguration> {
|
||||||
|
// 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<NullAuthenticatorConfiguration> implements
|
||||||
|
// Authenticator<NullAuthenticatorConfiguration> {
|
||||||
|
// 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
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
com.rogiel.httpchannel.service.impl.ZShareService
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
This is a simple upload test file.
|
||||||
|
|
||||||
|
This is for testing purposes only.
|
||||||
@@ -48,13 +48,6 @@
|
|||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
|
||||||
<version>1.6.2</version>
|
|
||||||
<type>jar</type>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.htmlparser</groupId>
|
<groupId>org.htmlparser</groupId>
|
||||||
<artifactId>htmlparser</artifactId>
|
<artifactId>htmlparser</artifactId>
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package com.rogiel.httpchannel.captcha;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.rogiel.httpchannel.util.htmlparser.HTMLPage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class AbstractHTMLImageCaptchaService<C extends AbstractImageCaptcha>
|
|
||||||
extends AbstractImageCaptchaService<C> {
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package com.rogiel.httpchannel.captcha;
|
|
||||||
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class AbstractImageCaptchaService<C extends AbstractImageCaptcha>
|
|
||||||
implements ImageCaptchaService<C> {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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 <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,6 +23,8 @@ import org.apache.commons.io.FilenameUtils;
|
|||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.rogiel.httpchannel.http.Request;
|
import com.rogiel.httpchannel.http.Request;
|
||||||
import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration;
|
import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration;
|
||||||
@@ -35,6 +37,8 @@ import com.rogiel.httpchannel.util.ThreadUtils;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractHttpDownloader<C extends DownloaderConfiguration>
|
public abstract class AbstractHttpDownloader<C extends DownloaderConfiguration>
|
||||||
extends AbstractDownloader<C> implements Downloader<C> {
|
extends AbstractDownloader<C> implements Downloader<C> {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
protected AbstractHttpDownloader(URL url, C configuration) {
|
protected AbstractHttpDownloader(URL url, C configuration) {
|
||||||
super(url, configuration);
|
super(url, configuration);
|
||||||
}
|
}
|
||||||
@@ -54,6 +58,7 @@ public abstract class AbstractHttpDownloader<C extends DownloaderConfiguration>
|
|||||||
if (!listener.timer(timer))
|
if (!listener.timer(timer))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
logger.debug("Download timer waiting {}", timer);
|
||||||
ThreadUtils.sleep(timer);
|
ThreadUtils.sleep(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public abstract class AbstractHttpService extends AbstractService implements
|
|||||||
|
|
||||||
protected LinkedUploadChannel waitChannelLink(LinkedUploadChannel channel,
|
protected LinkedUploadChannel waitChannelLink(LinkedUploadChannel channel,
|
||||||
Future<?> future) {
|
Future<?> future) {
|
||||||
|
logger.debug("Waiting channel {} to link", channel);
|
||||||
while (!channel.isLinked() && !future.isDone()) {
|
while (!channel.isLinked() && !future.isDone()) {
|
||||||
ThreadUtils.sleep(100);
|
ThreadUtils.sleep(100);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.channels.ClosedChannelException;
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.channels.WritableByteChannel;
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.rogiel.httpchannel.service.UploadChannel;
|
import com.rogiel.httpchannel.service.UploadChannel;
|
||||||
import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException;
|
import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException;
|
||||||
|
|
||||||
@@ -30,6 +33,8 @@ import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class LinkedUploadChannel implements UploadChannel {
|
public class LinkedUploadChannel implements UploadChannel {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
private WritableByteChannel channel;
|
private WritableByteChannel channel;
|
||||||
private final LinkedUploadChannelCloseCallback closeCallback;
|
private final LinkedUploadChannelCloseCallback closeCallback;
|
||||||
|
|
||||||
@@ -69,6 +74,7 @@ public class LinkedUploadChannel implements UploadChannel {
|
|||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
open = false;
|
open = false;
|
||||||
final String downloadLink = closeCallback.finish();
|
final String downloadLink = closeCallback.finish();
|
||||||
|
logger.debug("Download link returned by service is {}", downloadLink);
|
||||||
if (downloadLink == null)
|
if (downloadLink == null)
|
||||||
throw new UploadLinkNotFoundException();
|
throw new UploadLinkNotFoundException();
|
||||||
this.downloadLink = new URL(downloadLink);
|
this.downloadLink = new URL(downloadLink);
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.rogiel.httpchannel.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
pom.xml
13
pom.xml
@@ -64,6 +64,19 @@
|
|||||||
<type>jar</type>
|
<type>jar</type>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>1.6.4</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-jdk14</artifactId>
|
||||||
|
<version>1.6.4</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<url>http://httpchannel.rogiel.com/</url>
|
<url>http://httpchannel.rogiel.com/</url>
|
||||||
</project>
|
</project>
|
||||||
Reference in New Issue
Block a user