1
0
mirror of https://github.com/Rogiel/httpchannel synced 2025-12-06 07:32:50 +00:00

Implements CaptchaTrader service

This commit is contained in:
2012-01-17 12:28:22 -02:00
parent e943b08ede
commit 08d22a12fe
81 changed files with 2750 additions and 543 deletions

View File

@@ -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>

View File

@@ -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

View 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>

View File

@@ -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);
}
}

View File

@@ -0,0 +1,12 @@
/**
*
*/
package com.rogiel.httpchannel.filesonic.xml;
/**
* @author <a href="http://www.rogiel.com">Rogiel</a>
*
*/
public class FSAPI {
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -0,0 +1 @@
com.rogiel.httpchannel.service.impl.FileSonicService

View File

@@ -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())

View File

@@ -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())

View File

@@ -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));

View File

@@ -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>

View File

@@ -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();

View File

@@ -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>

View File

@@ -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();

View File

@@ -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)));
}
}

View 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>

View File

@@ -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
// }
// }
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1 @@
com.rogiel.httpchannel.service.impl.ZShareService

View File

@@ -0,0 +1,3 @@
This is a simple upload test file.
This is for testing purposes only.