mirror of
https://github.com/Rogiel/httpchannel
synced 2025-12-05 23:22:51 +00:00
Implements CaptchaTrader service
This commit is contained in:
@@ -9,25 +9,45 @@ package com.rogiel.httpchannel.captcha;
|
||||
*/
|
||||
public interface Captcha {
|
||||
/**
|
||||
* Sets the captcha answer
|
||||
*
|
||||
* @return the captcha ID
|
||||
*/
|
||||
String getID();
|
||||
|
||||
/**
|
||||
* @return the resolved captcha answer
|
||||
*/
|
||||
String getAnswer();
|
||||
|
||||
/**
|
||||
* @param answer
|
||||
* the captcha answer
|
||||
*/
|
||||
void setAnswer(String answer);
|
||||
|
||||
/**
|
||||
* Returns the captcha answer. <code>null</code> if the service was not able
|
||||
* to resolve it automatically. In such case, {@link #setAnswer(String)}
|
||||
* must be used to set the correct answer.
|
||||
*
|
||||
* @return the captcha answer
|
||||
* @return <code>true</code> if the captcha was resolved and
|
||||
* {@link #getAnswer()} will not return <code>null</code>.
|
||||
*/
|
||||
String getAnswer();
|
||||
boolean isResolved();
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if, and only if, the service was able to
|
||||
* automatically resolve the captcha result
|
||||
* Get this CAPTCHA's attachment.
|
||||
* <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;
|
||||
|
||||
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>
|
||||
*
|
||||
*/
|
||||
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>
|
||||
*
|
||||
*/
|
||||
public interface ImageCaptcha extends Captcha {
|
||||
public class ImageCaptcha implements Captcha {
|
||||
/**
|
||||
* @return the captcha identifier
|
||||
* The CAPTCHA ID
|
||||
*/
|
||||
String getID();
|
||||
private final String ID;
|
||||
/**
|
||||
* The CAPTCHA Image {@link URL}
|
||||
*/
|
||||
private final URL imageURL;
|
||||
/**
|
||||
* The CAPTCHA answer
|
||||
*/
|
||||
private String answer;
|
||||
/**
|
||||
* The CAPTCHA attachment
|
||||
*/
|
||||
private Object attachment;
|
||||
|
||||
/**
|
||||
* @return the captcha image {@link URL}
|
||||
*/
|
||||
URL getImageURL();
|
||||
public ImageCaptcha(String id, URL imageURL) {
|
||||
this.ID = id;
|
||||
this.imageURL = imageURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
public URL getImageURL() {
|
||||
return imageURL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAnswer() {
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnswer(String answer) {
|
||||
this.answer = answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResolved() {
|
||||
return answer != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getAttachment() {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttachment(Object attachment) {
|
||||
this.attachment = attachment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ImageCaptcha [ID=" + ID + ", imageURL=" + imageURL
|
||||
+ ", answer=" + answer + ", attachment=" + attachment + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,32 +3,10 @@
|
||||
*/
|
||||
package com.rogiel.httpchannel.captcha;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*
|
||||
*/
|
||||
public interface ImageCaptchaService<C extends ImageCaptcha> extends
|
||||
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;
|
||||
public interface ImageCaptchaService extends CaptchaService<ImageCaptcha> {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.rogiel.httpchannel.captcha.Captcha;
|
||||
import com.rogiel.httpchannel.captcha.CaptchaResolver;
|
||||
import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException;
|
||||
import com.rogiel.httpchannel.captcha.CaptchaService;
|
||||
import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException;
|
||||
import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
* This is an abstract {@link Service} implementation.
|
||||
@@ -27,7 +31,11 @@ import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException;
|
||||
* @version 1.0
|
||||
*/
|
||||
public abstract class AbstractService implements Service {
|
||||
protected CaptchaResolver captchaResolver;
|
||||
/**
|
||||
* The service {@link Logger} instance
|
||||
*/
|
||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
protected CaptchaService<Captcha> captchaService;
|
||||
|
||||
@Override
|
||||
public Service clone() {
|
||||
@@ -39,17 +47,17 @@ public abstract class AbstractService implements Service {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCaptchaResolver(CaptchaResolver captchaResolver) {
|
||||
this.captchaResolver = captchaResolver;
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setCaptchaService(
|
||||
CaptchaService<? extends Captcha> captchaService) {
|
||||
this.captchaService = (CaptchaService<Captcha>) captchaService;
|
||||
}
|
||||
|
||||
protected void resolveCaptcha(Captcha captcha)
|
||||
throws UnresolvedCaptchaException {
|
||||
if (captchaResolver == null)
|
||||
throw new UnresolvedCaptchaException();
|
||||
if (!captchaResolver.resolve(captcha))
|
||||
throw new UnresolvedCaptchaException();
|
||||
if (captcha.getAnswer() == null)
|
||||
throw new UnresolvedCaptchaException();
|
||||
throws NoCaptchaServiceException, UnsolvableCaptchaServiceException {
|
||||
if (captchaService == null)
|
||||
throw new NoCaptchaServiceException(
|
||||
"No CaptchaService is configured");
|
||||
captchaService.solve((Captcha) captcha);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,11 @@ package com.rogiel.httpchannel.service;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.rogiel.httpchannel.captcha.CaptchaResolver;
|
||||
import com.rogiel.httpchannel.captcha.CaptchaService;
|
||||
import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException;
|
||||
import com.rogiel.httpchannel.service.Authenticator.AuthenticatorConfiguration;
|
||||
import com.rogiel.httpchannel.service.exception.AuthenticationInvalidCredentialException;
|
||||
import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException;
|
||||
import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
* This interfaces provides authentication for an service.
|
||||
@@ -40,13 +41,16 @@ public interface Authenticator<C extends AuthenticatorConfiguration> {
|
||||
* if any IO error occur
|
||||
* @throws AuthenticationInvalidCredentialException
|
||||
* if the credentials are not valid or cannot be used
|
||||
* @throws UnresolvedCaptchaException
|
||||
* @throws UnsolvableCaptchaServiceException
|
||||
* if the service required captcha resolving but no
|
||||
* {@link CaptchaResolver} was available or the resolver did not
|
||||
* {@link CaptchaService} was available or the service did not
|
||||
* solve the challenge
|
||||
* @throws NoCaptchaServiceException
|
||||
* if the service required an {@link CaptchaService}
|
||||
* implementation to be present, but none was available
|
||||
*/
|
||||
void login() throws IOException, AuthenticationInvalidCredentialException,
|
||||
UnresolvedCaptchaException;
|
||||
UnsolvableCaptchaServiceException, NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
* Logout into the {@link Service}. The session is restored to an not
|
||||
|
||||
@@ -32,13 +32,4 @@ import java.nio.channels.ReadableByteChannel;
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
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 com.rogiel.httpchannel.captcha.CaptchaResolver;
|
||||
import com.rogiel.httpchannel.captcha.CaptchaService;
|
||||
import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException;
|
||||
import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration;
|
||||
import com.rogiel.httpchannel.service.exception.DownloadLimitExceededException;
|
||||
import com.rogiel.httpchannel.service.exception.DownloadLinkNotFoundException;
|
||||
import com.rogiel.httpchannel.service.exception.DownloadNotAuthorizedException;
|
||||
import com.rogiel.httpchannel.service.exception.DownloadNotResumableException;
|
||||
import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException;
|
||||
import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
* This interfaces provides downloading for an service.
|
||||
@@ -42,7 +43,8 @@ public interface Downloader<C extends DownloaderConfiguration> {
|
||||
* very unlikely to be done. The most common usage usage scenario for this
|
||||
* is when an {@link DownloadNotResumableException} is thrown and you wish
|
||||
* to restart the download from start giving <tt>position</tt> equal to
|
||||
* zero.
|
||||
* zero, in such scenario, reutilizing the same {@link Downloader} instance
|
||||
* is safe.
|
||||
* <p>
|
||||
* Please remember to close the channel by calling
|
||||
* {@link DownloadChannel#close()}, otherwise some of the resources (such as
|
||||
@@ -70,15 +72,19 @@ public interface Downloader<C extends DownloaderConfiguration> {
|
||||
* @throws DownloadNotResumableException
|
||||
* if the download cannot be started at <tt>position</tt>. Will
|
||||
* only be thrown if <tt>position > 0</tt>.
|
||||
* @throws UnresolvedCaptchaException
|
||||
* @throws UnsolvableCaptchaServiceException
|
||||
* if the service required captcha resolving but no
|
||||
* {@link CaptchaResolver} was available or the resolver did not
|
||||
* {@link CaptchaService} was available or the service did not
|
||||
* solve the challenge
|
||||
* @throws NoCaptchaServiceException
|
||||
* if the service required an {@link CaptchaService}
|
||||
* implementation to be present, but none was available
|
||||
*/
|
||||
DownloadChannel openChannel(DownloadListener listener, long position)
|
||||
throws IOException, DownloadLinkNotFoundException,
|
||||
DownloadLimitExceededException, DownloadNotAuthorizedException,
|
||||
DownloadNotResumableException, UnresolvedCaptchaException;
|
||||
DownloadNotResumableException, UnsolvableCaptchaServiceException,
|
||||
NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
* Opens a new {@link DownloadChannel} with not listener. For more details,
|
||||
@@ -102,14 +108,26 @@ public interface Downloader<C extends DownloaderConfiguration> {
|
||||
* @throws DownloadNotResumableException
|
||||
* if the download cannot be started at <tt>position</tt>. Will
|
||||
* 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,
|
||||
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
||||
DownloadNotAuthorizedException, DownloadNotResumableException;
|
||||
DownloadNotAuthorizedException, DownloadNotResumableException,
|
||||
UnsolvableCaptchaServiceException, NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
* Opens a new {@link DownloadChannel} positioned at 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.
|
||||
*
|
||||
* @param listener
|
||||
* the listener to keep a track on the download progress
|
||||
@@ -125,14 +143,25 @@ public interface Downloader<C extends DownloaderConfiguration> {
|
||||
* @throws DownloadNotAuthorizedException
|
||||
* if the user (or guest) account does not have necessary rights
|
||||
* to download the file
|
||||
* @throws UnsolvableCaptchaServiceException
|
||||
* if the service required captcha resolving but no
|
||||
* {@link CaptchaService} was available or the service did not
|
||||
* solve the challenge
|
||||
* @throws NoCaptchaServiceException
|
||||
* if the service required an {@link CaptchaService}
|
||||
* implementation to be present, but none was available
|
||||
*/
|
||||
DownloadChannel openChannel(DownloadListener listener) throws IOException,
|
||||
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
||||
DownloadNotAuthorizedException;
|
||||
DownloadNotAuthorizedException, UnsolvableCaptchaServiceException,
|
||||
NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
* Opens a new {@link DownloadChannel} with not listener and positioned at
|
||||
* start. For more details, see {@link #openChannel(DownloadListener, long)}
|
||||
* <p>
|
||||
* Note that {@link DownloadNotResumableException} is never thrown because
|
||||
* this channel always starts at <code>0</code> offset.
|
||||
*
|
||||
* @return the {@link DownloadChannel} instance
|
||||
* @throws IOException
|
||||
@@ -146,10 +175,18 @@ public interface Downloader<C extends DownloaderConfiguration> {
|
||||
* @throws DownloadNotAuthorizedException
|
||||
* if the user (or guest) account does not have necessary rights
|
||||
* to download the file
|
||||
* @throws UnsolvableCaptchaServiceException
|
||||
* if the service required captcha resolving but no
|
||||
* {@link CaptchaService} was available or the service did not
|
||||
* solve the challenge
|
||||
* @throws NoCaptchaServiceException
|
||||
* if the service required an {@link CaptchaService}
|
||||
* implementation to be present, but none was available
|
||||
*/
|
||||
DownloadChannel openChannel() throws IOException,
|
||||
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
||||
DownloadNotAuthorizedException;
|
||||
DownloadNotAuthorizedException, UnsolvableCaptchaServiceException,
|
||||
NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
* Returns this {@link Downloader} configuration.
|
||||
|
||||
@@ -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;
|
||||
|
||||
import com.rogiel.httpchannel.captcha.CaptchaResolver;
|
||||
import com.rogiel.httpchannel.captcha.Captcha;
|
||||
import com.rogiel.httpchannel.captcha.CaptchaService;
|
||||
|
||||
/**
|
||||
* Base interface for all the services. Whenever the operation suported by the
|
||||
@@ -53,13 +54,13 @@ public interface Service extends Cloneable {
|
||||
int getMinorVersion();
|
||||
|
||||
/**
|
||||
* Sets this service captcha resolver. Resolvers are safe to be switched
|
||||
* Sets this service captcha service. CaptchaService are safe to be switched
|
||||
* even after an transfer has begun.
|
||||
*
|
||||
* @param resolver
|
||||
* the captcha resolver
|
||||
* @param captchaService
|
||||
* the captcha service
|
||||
*/
|
||||
void setCaptchaResolver(CaptchaResolver resolver);
|
||||
void setCaptchaService(CaptchaService<? extends Captcha> captchaService);
|
||||
|
||||
/**
|
||||
* @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>
|
||||
*/
|
||||
public interface UploadChannel extends HttpChannel, WritableByteChannel {
|
||||
/**
|
||||
* @return the file size
|
||||
*/
|
||||
long getFilesize();
|
||||
|
||||
/**
|
||||
* @return the file name
|
||||
*/
|
||||
String getFilename();
|
||||
|
||||
/**
|
||||
* The link is located after you call {@link UploadChannel#close()}, but it
|
||||
* can only be retrieved by calling this method. If {@link #close()} throwed
|
||||
|
||||
@@ -18,9 +18,10 @@ package com.rogiel.httpchannel.service;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.rogiel.httpchannel.captcha.CaptchaResolver;
|
||||
import com.rogiel.httpchannel.captcha.CaptchaService;
|
||||
import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException;
|
||||
import com.rogiel.httpchannel.service.Uploader.UploaderConfiguration;
|
||||
import com.rogiel.httpchannel.service.exception.UnresolvedCaptchaException;
|
||||
import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
* This interfaces provides uploading for an service.
|
||||
@@ -48,12 +49,16 @@ public interface Uploader<C extends UploaderConfiguration> {
|
||||
* @return the {@link UploadChannel} instance
|
||||
* @throws IOException
|
||||
* if any IO error occur
|
||||
* @throws UnresolvedCaptchaException
|
||||
* @throws UnsolvableCaptchaServiceException
|
||||
* if the service required captcha resolving but no
|
||||
* {@link CaptchaResolver} was available or the resolver did not
|
||||
* {@link CaptchaService} was available or the service did not
|
||||
* solve the challenge
|
||||
* @throws NoCaptchaServiceException
|
||||
* if the service required an {@link CaptchaService}
|
||||
* implementation to be present, but none was available
|
||||
*/
|
||||
UploadChannel openChannel() throws IOException, UnresolvedCaptchaException;
|
||||
UploadChannel openChannel() throws IOException,
|
||||
UnsolvableCaptchaServiceException, NoCaptchaServiceException;
|
||||
|
||||
/**
|
||||
* Returns this {@link Uploader} configuration.
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
*/
|
||||
package com.rogiel.httpchannel.service.exception;
|
||||
|
||||
import com.rogiel.httpchannel.captcha.CaptchaResolver;
|
||||
import com.rogiel.httpchannel.captcha.CaptchaService;
|
||||
|
||||
/**
|
||||
* Exception thrown if the {@link CaptchaResolver} has returned an invalid
|
||||
* Exception thrown if the {@link CaptchaService} has returned an invalid
|
||||
* captcha
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
|
||||
@@ -16,21 +16,21 @@
|
||||
*/
|
||||
package com.rogiel.httpchannel.service.exception;
|
||||
|
||||
import com.rogiel.httpchannel.captcha.CaptchaResolver;
|
||||
import com.rogiel.httpchannel.captcha.CaptchaService;
|
||||
|
||||
/**
|
||||
* Exception thrown if the {@link CaptchaResolver} has returned an invalid
|
||||
* Exception thrown if the {@link CaptchaService} has returned an invalid
|
||||
* captcha
|
||||
*
|
||||
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||
*/
|
||||
public class UnresolvedCaptchaException extends ChannelServiceException {
|
||||
public class NoCaptchaServiceException extends ChannelServiceException {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new empty instance of this exception
|
||||
*/
|
||||
public UnresolvedCaptchaException() {
|
||||
public NoCaptchaServiceException() {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class UnresolvedCaptchaException extends ChannelServiceException {
|
||||
* @param cause
|
||||
* the root cause
|
||||
*/
|
||||
public UnresolvedCaptchaException(String message, Throwable cause) {
|
||||
public NoCaptchaServiceException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ public class UnresolvedCaptchaException extends ChannelServiceException {
|
||||
* @param message
|
||||
* the message
|
||||
*/
|
||||
public UnresolvedCaptchaException(String message) {
|
||||
public NoCaptchaServiceException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class UnresolvedCaptchaException extends ChannelServiceException {
|
||||
* @param cause
|
||||
* the root cause
|
||||
*/
|
||||
public UnresolvedCaptchaException(Throwable cause) {
|
||||
public NoCaptchaServiceException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
<modules>
|
||||
<module>httpchannel-captcha-recaptcha</module>
|
||||
<module>httpchannel-captcha-captchatrader</module>
|
||||
</modules>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.rogiel.httpchannel</groupId>
|
||||
<artifactId>httpchannel-api</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</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>
|
||||
<name>HttpChannel/Service/DepositFiles</name>
|
||||
<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>
|
||||
@@ -5,8 +5,9 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.rogiel.httpchannel.captcha.impl.EmbeddedReCaptchaService;
|
||||
import com.rogiel.httpchannel.captcha.impl.ReCaptcha;
|
||||
import com.rogiel.httpchannel.captcha.ImageCaptcha;
|
||||
import com.rogiel.httpchannel.captcha.ReCaptchaExtractor;
|
||||
import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException;
|
||||
import com.rogiel.httpchannel.service.AbstractAuthenticator;
|
||||
import com.rogiel.httpchannel.service.AbstractHttpService;
|
||||
import com.rogiel.httpchannel.service.AbstractUploader;
|
||||
@@ -50,8 +51,6 @@ public class DepositFilesService extends AbstractHttpService implements
|
||||
private static final Pattern VALID_LOGIN_REDIRECT = Pattern
|
||||
.compile("window.location.href");
|
||||
|
||||
private final EmbeddedReCaptchaService captchaService = new EmbeddedReCaptchaService();
|
||||
|
||||
@Override
|
||||
public ServiceID getID() {
|
||||
return SERVICE_ID;
|
||||
@@ -137,12 +136,15 @@ public class DepositFilesService extends AbstractHttpService implements
|
||||
|
||||
@Override
|
||||
public UploadChannel openChannel() throws IOException {
|
||||
logger.debug("Starting upload to depositfiles.com");
|
||||
final HTMLPage page = get("http://www.depositfiles.com/").asPage();
|
||||
|
||||
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||
final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER");
|
||||
final String maxFileSize = page.getInputValue("MAX_FILE_SIZE");
|
||||
|
||||
logger.debug("Upload URL: {}, ID: {}", url, uploadID);
|
||||
|
||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||
uploadFuture = multipartPost(url).parameter("files", channel)
|
||||
.parameter("go", true)
|
||||
@@ -178,13 +180,16 @@ public class DepositFilesService extends AbstractHttpService implements
|
||||
|
||||
@Override
|
||||
public void login() throws IOException {
|
||||
logger.debug("Authenticating into depositfiles.com");
|
||||
HTMLPage page = post("http://depositfiles.com/login.php?return=%2F")
|
||||
.parameter("go", true)
|
||||
.parameter("login", credential.getUsername())
|
||||
.parameter("password", credential.getPassword()).asPage();
|
||||
|
||||
final ReCaptcha captcha = captchaService.create(page);
|
||||
final ImageCaptcha captcha = ReCaptchaExtractor.extractCaptcha(
|
||||
page, http);
|
||||
if (captcha != null) {
|
||||
logger.debug("Service is requiring CAPTCHA {}", captcha);
|
||||
resolveCaptcha(captcha);
|
||||
page = post("http://depositfiles.com/login.php?return=%2F")
|
||||
.parameter("go", true)
|
||||
@@ -195,9 +200,17 @@ public class DepositFilesService extends AbstractHttpService implements
|
||||
captcha.getAnswer()).asPage();
|
||||
}
|
||||
|
||||
if (!page.contains(VALID_LOGIN_REDIRECT))
|
||||
throw new AuthenticationInvalidCredentialException();
|
||||
return;
|
||||
final ImageCaptcha testCaptcha = ReCaptchaExtractor.extractCaptcha(
|
||||
page, http);
|
||||
if (testCaptcha != null) {
|
||||
captchaService.invalid(captcha);
|
||||
throw new UnsolvableCaptchaServiceException();
|
||||
} else {
|
||||
captchaService.valid(captcha);
|
||||
if (!page.contains(VALID_LOGIN_REDIRECT))
|
||||
throw new AuthenticationInvalidCredentialException();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
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
|
||||
public UploadChannel openChannel() throws IOException {
|
||||
logger.debug("Starting upload to hotfile.com");
|
||||
final HTMLPage page = get("http://www.hotfile.com/").asPage();
|
||||
final String action = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||
|
||||
logger.debug("Upload URL is {}", action);
|
||||
|
||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||
|
||||
uploadFuture = multipartPost(action)
|
||||
@@ -227,6 +230,7 @@ public class HotFileService extends AbstractHttpService implements Service,
|
||||
@Override
|
||||
public DownloadChannel openChannel(DownloadListener listener,
|
||||
long position) throws IOException {
|
||||
logger.debug("Downloading {} from hotfile.com", url);
|
||||
final HTMLPage page = get(url).asPage();
|
||||
|
||||
// // try to find timer
|
||||
@@ -243,6 +247,7 @@ public class HotFileService extends AbstractHttpService implements Service,
|
||||
|
||||
final String downloadUrl = page
|
||||
.findLink(DOWNLOAD_DIRECT_LINK_PATTERN);
|
||||
logger.debug("Download link is {}", downloadUrl);
|
||||
// final String tmHash = PatternUtils.find(DOWNLOAD_TMHASH_PATTERN,
|
||||
// content);F
|
||||
if (downloadUrl != null && downloadUrl.length() > 0) {
|
||||
@@ -254,49 +259,6 @@ public class HotFileService extends AbstractHttpService implements Service,
|
||||
|
||||
return new InputStreamDownloadChannel(downloadResponse
|
||||
.getEntity().getContent(), contentLength, filename);
|
||||
// } else if (tmHash != null) {
|
||||
// String dlUrl = PatternUtils.find(FREE_DOWNLOAD_URL_PATTERN,
|
||||
// content);
|
||||
//
|
||||
// String action = PatternUtils.find(DOWNLOAD_ACTION_PATTERN,
|
||||
// content, 1);
|
||||
// int tm = PatternUtils.findInt(DOWNLOAD_TM_PATTERN, content,
|
||||
// 1);
|
||||
// int wait = PatternUtils.findInt(DOWNLOAD_WAIT_PATTERN,
|
||||
// content,
|
||||
// 1);
|
||||
// String waitHash =
|
||||
// PatternUtils.find(DOWNLOAD_WAITHASH_PATTERN,
|
||||
// content, 1);
|
||||
// String upId = PatternUtils.find(DOWNLOAD_UPIDHASH_PATTERN,
|
||||
// content, 1);
|
||||
//
|
||||
// System.out.println("Wait time: "+wait);
|
||||
//
|
||||
// if (wait > 0)
|
||||
// timer(listener, wait * 1000);
|
||||
//
|
||||
// final HttpPost downloadPost = new
|
||||
// HttpPost("http://www.hotfile.com"+dlUrl);
|
||||
// final List<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 {
|
||||
throw new IOException("Download link not found");
|
||||
}
|
||||
@@ -313,6 +275,7 @@ public class HotFileService extends AbstractHttpService implements Service,
|
||||
|
||||
@Override
|
||||
public void login() throws ClientProtocolException, IOException {
|
||||
logger.debug("Authenticating hotfile.com");
|
||||
HTMLPage page = post("http://www.hotfile.com/login.php")
|
||||
.parameter("returnto", "/index.php")
|
||||
.parameter("user", credential.getUsername())
|
||||
|
||||
@@ -205,10 +205,12 @@ public class MegaUploadService extends AbstractHttpService implements Service,
|
||||
|
||||
@Override
|
||||
public UploadChannel openChannel() throws IOException {
|
||||
logger.debug("Starting upload to megaupload.com");
|
||||
final HTMLPage page = get("http://www.megaupload.com/multiupload/")
|
||||
.asPage();
|
||||
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||
|
||||
logger.debug("Upload URL is {}", url);
|
||||
|
||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||
uploadFuture = multipartPost(url)
|
||||
.parameter("multimessage_0", configuration.description())
|
||||
@@ -240,11 +242,13 @@ public class MegaUploadService extends AbstractHttpService implements Service,
|
||||
@Override
|
||||
public DownloadChannel openChannel(DownloadListener listener,
|
||||
long position) throws IOException {
|
||||
logger.debug("Starting {} download from megaupload.com", url);
|
||||
HttpResponse response = get(url).request();
|
||||
|
||||
// disable direct downloads, we don't support them!
|
||||
if (response.getEntity().getContentType().getValue()
|
||||
.equals("application/octet-stream")) {
|
||||
logger.debug("Direct download is enabled, deactivating");
|
||||
// close connection
|
||||
response.getEntity().getContent().close();
|
||||
|
||||
@@ -263,6 +267,7 @@ public class MegaUploadService extends AbstractHttpService implements Service,
|
||||
// try to find timer
|
||||
int timer = page.findScriptAsInt(DOWNLOAD_TIMER, 1);
|
||||
if (timer > 0 && configuration.getRespectWaitTime()) {
|
||||
logger.debug("");
|
||||
timer(listener, timer * 1000);
|
||||
}
|
||||
final String downloadUrl = page
|
||||
@@ -299,6 +304,7 @@ public class MegaUploadService extends AbstractHttpService implements Service,
|
||||
|
||||
@Override
|
||||
public void login() throws IOException {
|
||||
logger.debug("Starting login to megaupload.com");
|
||||
final HTMLPage page = post("http://www.megaupload.com/?c=login")
|
||||
.parameter("login", true)
|
||||
.parameter("username", credential.getUsername())
|
||||
|
||||
@@ -183,8 +183,10 @@ public class MultiUploadService extends AbstractHttpService implements Service,
|
||||
|
||||
@Override
|
||||
public UploadChannel openChannel() throws IOException {
|
||||
logger.debug("Starting upload to multiupload.com");
|
||||
final String url = get("http://www.multiupload.com/").asPage()
|
||||
.findFormAction(UPLOAD_URL_PATTERN);
|
||||
logger.debug("Upload URL is {}", url);
|
||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||
|
||||
PostMultipartRequest request = multipartPost(url).parameter(
|
||||
@@ -192,6 +194,7 @@ public class MultiUploadService extends AbstractHttpService implements Service,
|
||||
"file_0", channel);
|
||||
for (final MultiUploadMirrorService mirror : configuration
|
||||
.uploadServices()) {
|
||||
logger.debug("Adding {} as mirror", mirror.name());
|
||||
request.parameter("service_" + mirror.id, 1);
|
||||
}
|
||||
|
||||
@@ -204,6 +207,7 @@ public class MultiUploadService extends AbstractHttpService implements Service,
|
||||
try {
|
||||
final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN,
|
||||
uploadFuture.get(), 1);
|
||||
logger.debug("Upload to multiupload.com finished");
|
||||
if (linkId == null)
|
||||
return null;
|
||||
return new StringBuilder("http://www.multiupload.com/").append(
|
||||
@@ -231,6 +235,7 @@ public class MultiUploadService extends AbstractHttpService implements Service,
|
||||
DownloadNotAuthorizedException, DownloadNotResumableException {
|
||||
final HTMLPage page = get(url).asPage();
|
||||
final String link = page.findLink(DIRECT_DOWNLOAD_LINK_PATTERN);
|
||||
logger.debug("Direct download link is {}", link);
|
||||
if (link == null)
|
||||
throw new DownloadLinkNotFoundException();
|
||||
return download(get(link).position(position));
|
||||
|
||||
@@ -10,11 +10,4 @@
|
||||
<groupId>com.rogiel.httpchannel.services</groupId>
|
||||
<name>HttpChannel/Service/UploadHere</name>
|
||||
<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>
|
||||
@@ -6,8 +6,8 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.rogiel.httpchannel.captcha.impl.AjaxReCaptchaService;
|
||||
import com.rogiel.httpchannel.captcha.impl.ReCaptcha;
|
||||
import com.rogiel.httpchannel.captcha.ImageCaptcha;
|
||||
import com.rogiel.httpchannel.captcha.ReCaptchaExtractor;
|
||||
import com.rogiel.httpchannel.service.AbstractAuthenticator;
|
||||
import com.rogiel.httpchannel.service.AbstractHttpDownloader;
|
||||
import com.rogiel.httpchannel.service.AbstractHttpService;
|
||||
@@ -67,8 +67,6 @@ public class UploadHereService extends AbstractHttpService implements Service,
|
||||
|
||||
private static final String INVALID_LOGIN_STRING = "Incorrect username and/or password. Please try again!";
|
||||
|
||||
private final AjaxReCaptchaService captchaService = new AjaxReCaptchaService();
|
||||
|
||||
@Override
|
||||
public ServiceID getID() {
|
||||
return SERVICE_ID;
|
||||
@@ -190,6 +188,9 @@ public class UploadHereService extends AbstractHttpService implements Service,
|
||||
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||
final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER");
|
||||
|
||||
logger.debug("Upload URL: {}, UserCookie: {}, UploadID: {}",
|
||||
new Object[] { url, userCookie, uploadID });
|
||||
|
||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||
uploadFuture = multipartPost(url).parameter("file_0", channel)
|
||||
.parameter("u", userCookie)
|
||||
@@ -202,6 +203,7 @@ public class UploadHereService extends AbstractHttpService implements Service,
|
||||
try {
|
||||
final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN,
|
||||
uploadFuture.get(), 1);
|
||||
logger.debug("Upload to uploadhere.com finished");
|
||||
if (linkId == null)
|
||||
return null;
|
||||
return new StringBuilder("http://www.uploadhere.com/").append(
|
||||
@@ -230,15 +232,24 @@ public class UploadHereService extends AbstractHttpService implements Service,
|
||||
HTMLPage page = get(url).asPage();
|
||||
|
||||
final int waitTime = page.findScriptAsInt(TIMER_PATTERN, 1) * 1000;
|
||||
logger.debug("Wait time is {}", waitTime);
|
||||
|
||||
final ReCaptcha captcha = captchaService.create(page.toString());
|
||||
final ImageCaptcha captcha = ReCaptchaExtractor.extractAjaxCaptcha(
|
||||
page, http);
|
||||
if (captcha != null) {
|
||||
logger.debug("Service is requiring CAPTCHA {}", captcha);
|
||||
final long start = System.currentTimeMillis();
|
||||
resolveCaptcha(captcha);
|
||||
|
||||
final long delta = System.currentTimeMillis() - start;
|
||||
if (delta < waitTime)
|
||||
if (delta < waitTime) {
|
||||
logger.debug(
|
||||
"After captcha resolving, still {} ms remaining",
|
||||
delta);
|
||||
timer(listener, waitTime - delta);
|
||||
} else {
|
||||
logger.debug("CAPTCHA solving took longer than timer, skipping it");
|
||||
}
|
||||
|
||||
String content = post(url)
|
||||
.parameter("recaptcha_challenge_field", captcha.getID())
|
||||
@@ -246,10 +257,15 @@ public class UploadHereService extends AbstractHttpService implements Service,
|
||||
captcha.getAnswer()).asString();
|
||||
String downloadLink = PatternUtils.find(
|
||||
DIERCT_DOWNLOAD_URL_PATTERN, content, 1);
|
||||
if (downloadLink == null)
|
||||
if (downloadLink == null) {
|
||||
captchaService.invalid(captcha);
|
||||
throw new InvalidCaptchaException();
|
||||
} else {
|
||||
captchaService.valid(captcha);
|
||||
}
|
||||
downloadLink = downloadLink.replaceAll(Pattern.quote("\\/"),
|
||||
"/");
|
||||
logger.debug("Direct download URL is {}", downloadLink);
|
||||
return download(get(downloadLink).position(position));
|
||||
}
|
||||
throw new DownloadLinkNotFoundException();
|
||||
|
||||
@@ -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">
|
||||
<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-uploadking</artifactId>
|
||||
<groupId>com.rogiel.httpchannel.services</groupId>
|
||||
<name>HttpChannel/Service/UploadKing</name>
|
||||
<description>Provides upload access to uploadking.com</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.rogiel.httpchannel</groupId>
|
||||
<artifactId>httpchannel-captcha-recaptcha</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<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-uploadking</artifactId>
|
||||
<groupId>com.rogiel.httpchannel.services</groupId>
|
||||
<name>HttpChannel/Service/UploadKing</name>
|
||||
<description>Provides upload access to uploadking.com</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.rogiel.httpchannel.captcha</groupId>
|
||||
<artifactId>httpchannel-captcha-captchatrader</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -6,8 +6,8 @@ import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.rogiel.httpchannel.captcha.impl.AjaxReCaptchaService;
|
||||
import com.rogiel.httpchannel.captcha.impl.ReCaptcha;
|
||||
import com.rogiel.httpchannel.captcha.ImageCaptcha;
|
||||
import com.rogiel.httpchannel.captcha.ReCaptchaExtractor;
|
||||
import com.rogiel.httpchannel.service.AbstractAuthenticator;
|
||||
import com.rogiel.httpchannel.service.AbstractHttpDownloader;
|
||||
import com.rogiel.httpchannel.service.AbstractHttpService;
|
||||
@@ -67,8 +67,6 @@ public class UploadKingService extends AbstractHttpService implements Service,
|
||||
|
||||
private static final String INVALID_LOGIN_STRING = "Incorrect username and/or password. Please try again!";
|
||||
|
||||
private final AjaxReCaptchaService captchaService = new AjaxReCaptchaService();
|
||||
|
||||
@Override
|
||||
public ServiceID getID() {
|
||||
return SERVICE_ID;
|
||||
@@ -190,6 +188,9 @@ public class UploadKingService extends AbstractHttpService implements Service,
|
||||
final String url = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||
final String uploadID = page.getInputValue("UPLOAD_IDENTIFIER");
|
||||
|
||||
logger.debug("Upload URL: {}, UserCookie: {}, UploadID: {}",
|
||||
new Object[] { url, userCookie, uploadID });
|
||||
|
||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||
uploadFuture = multipartPost(url).parameter("file", channel)
|
||||
.parameter("u", userCookie)
|
||||
@@ -202,6 +203,7 @@ public class UploadKingService extends AbstractHttpService implements Service,
|
||||
try {
|
||||
final String linkId = PatternUtils.find(DOWNLOAD_ID_PATTERN,
|
||||
uploadFuture.get(), 1);
|
||||
logger.debug("Upload to uploadking.com finished");
|
||||
if (linkId == null)
|
||||
return null;
|
||||
return new StringBuilder("http://www.uploadking.com/").append(
|
||||
@@ -224,19 +226,29 @@ public class UploadKingService extends AbstractHttpService implements Service,
|
||||
@Override
|
||||
public DownloadChannel openChannel(DownloadListener listener,
|
||||
long position) throws IOException {
|
||||
logger.debug("Downloading {} with uploadking.com");
|
||||
HTMLPage page = get(url).asPage();
|
||||
|
||||
final int waitTime = page.findScriptAsInt(TIMER_PATTERN, 1) * 1000;
|
||||
logger.debug("Wait time is {}", waitTime);
|
||||
|
||||
final ReCaptcha captcha = captchaService.create(page.toString());
|
||||
final ImageCaptcha captcha = ReCaptchaExtractor.extractAjaxCaptcha(
|
||||
page, http);
|
||||
if (captcha != null) {
|
||||
logger.debug("Service is requiring CAPTCHA {}", captcha);
|
||||
final long start = System.currentTimeMillis();
|
||||
|
||||
resolveCaptcha(captcha);
|
||||
|
||||
final long delta = System.currentTimeMillis() - start;
|
||||
if (delta < waitTime)
|
||||
if (delta < waitTime) {
|
||||
logger.debug(
|
||||
"After captcha resolving, still {} ms remaining",
|
||||
delta);
|
||||
timer(listener, waitTime - delta);
|
||||
} else {
|
||||
logger.debug("CAPTCHA solving took longer than timer, skipping it");
|
||||
}
|
||||
|
||||
String content = post(url)
|
||||
.parameter("recaptcha_challenge_field", captcha.getID())
|
||||
@@ -244,10 +256,15 @@ public class UploadKingService extends AbstractHttpService implements Service,
|
||||
captcha.getAnswer()).asString();
|
||||
String downloadLink = PatternUtils.find(
|
||||
DIERCT_DOWNLOAD_URL_PATTERN, content, 1);
|
||||
if (downloadLink == null)
|
||||
if (downloadLink == null) {
|
||||
captchaService.invalid(captcha);
|
||||
throw new InvalidCaptchaException();
|
||||
} else {
|
||||
captchaService.valid(captcha);
|
||||
}
|
||||
downloadLink = downloadLink.replaceAll(Pattern.quote("\\/"),
|
||||
"/");
|
||||
logger.debug("Direct download URL is {}", downloadLink);
|
||||
return download(get(downloadLink).position(position));
|
||||
}
|
||||
throw new DownloadLinkNotFoundException();
|
||||
|
||||
@@ -4,14 +4,20 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.Properties;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.rogiel.httpchannel.captcha.CaptchaService;
|
||||
import com.rogiel.httpchannel.captcha.impl.CaptchaTraderService;
|
||||
import com.rogiel.httpchannel.service.DownloadChannel;
|
||||
import com.rogiel.httpchannel.service.UploaderCapability;
|
||||
import com.rogiel.httpchannel.util.ChannelUtils;
|
||||
|
||||
@@ -37,26 +43,19 @@ public class UploadKingServiceTest {
|
||||
System.out.println(url);
|
||||
}
|
||||
|
||||
// @Test
|
||||
// public void testDownloader() throws IOException {
|
||||
// service.setCaptchaResolver(new CaptchaResolver() {
|
||||
// @Override
|
||||
// public boolean resolve(Captcha rawCaptcha) {
|
||||
// final ImageCaptcha captcha = (ImageCaptcha) rawCaptcha;
|
||||
// System.out.println(captcha.getImageURL());
|
||||
// try {
|
||||
// captcha.setAnswer(new BufferedReader(new InputStreamReader(
|
||||
// System.in)).readLine());
|
||||
// System.out.println("Answer is: " + captcha.getAnswer());
|
||||
// return true;
|
||||
// } catch (IOException e) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// final DownloadChannel channel = service.getDownloader(
|
||||
// new URL("http://www.uploadking.com/WM3PHD9JAY")).openChannel(512);
|
||||
// System.out.println(new String(ChannelUtils.toByteArray(channel)));
|
||||
// }
|
||||
@Test
|
||||
public void testDownloader() throws IOException {
|
||||
final Properties p = new Properties();
|
||||
p.load(Files.newInputStream(
|
||||
Paths.get("../../httpchannel-captcha/src/test/resources/captchatrader.properties"),
|
||||
StandardOpenOption.READ));
|
||||
|
||||
final CaptchaService<?> s = new CaptchaTraderService();
|
||||
s.authenticate(p.getProperty("username"), p.getProperty("password"));
|
||||
service.setCaptchaService(s);
|
||||
|
||||
final DownloadChannel channel = service.getDownloader(
|
||||
new URL("http://www.uploadking.com/WM3PHD9JAY")).openChannel(0);
|
||||
System.out.println(new String(ChannelUtils.toByteArray(channel)));
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>1.6.2</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.htmlparser</groupId>
|
||||
<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.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.rogiel.httpchannel.http.Request;
|
||||
import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration;
|
||||
@@ -35,6 +37,8 @@ import com.rogiel.httpchannel.util.ThreadUtils;
|
||||
*/
|
||||
public abstract class AbstractHttpDownloader<C extends DownloaderConfiguration>
|
||||
extends AbstractDownloader<C> implements Downloader<C> {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
protected AbstractHttpDownloader(URL url, C configuration) {
|
||||
super(url, configuration);
|
||||
}
|
||||
@@ -54,6 +58,7 @@ public abstract class AbstractHttpDownloader<C extends DownloaderConfiguration>
|
||||
if (!listener.timer(timer))
|
||||
return;
|
||||
}
|
||||
logger.debug("Download timer waiting {}", timer);
|
||||
ThreadUtils.sleep(timer);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ public abstract class AbstractHttpService extends AbstractService implements
|
||||
|
||||
protected LinkedUploadChannel waitChannelLink(LinkedUploadChannel channel,
|
||||
Future<?> future) {
|
||||
logger.debug("Waiting channel {} to link", channel);
|
||||
while (!channel.isLinked() && !future.isDone()) {
|
||||
ThreadUtils.sleep(100);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,9 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.rogiel.httpchannel.service.UploadChannel;
|
||||
import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException;
|
||||
|
||||
@@ -30,6 +33,8 @@ import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException;
|
||||
*
|
||||
*/
|
||||
public class LinkedUploadChannel implements UploadChannel {
|
||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private WritableByteChannel channel;
|
||||
private final LinkedUploadChannelCloseCallback closeCallback;
|
||||
|
||||
@@ -69,6 +74,7 @@ public class LinkedUploadChannel implements UploadChannel {
|
||||
public void close() throws IOException {
|
||||
open = false;
|
||||
final String downloadLink = closeCallback.finish();
|
||||
logger.debug("Download link returned by service is {}", downloadLink);
|
||||
if (downloadLink == null)
|
||||
throw new UploadLinkNotFoundException();
|
||||
this.downloadLink = new URL(downloadLink);
|
||||
|
||||
@@ -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>
|
||||
<scope>test</scope>
|
||||
</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>
|
||||
<url>http://httpchannel.rogiel.com/</url>
|
||||
</project>
|
||||
Reference in New Issue
Block a user