diff --git a/README b/README new file mode 100644 index 0000000..0eb2991 --- /dev/null +++ b/README @@ -0,0 +1,10 @@ +# What is this? +This is a Java Library written to simplify download and upload from multiple +free share sites. + +Instead of writing an specific API for each situation, I designed a single API +capable of almost everything! Upload and downloads are done through Java.NIO +Channels and with those you can stream the file, both up and down. + +Also, if you wish, you can easily (with less than 10 lines!) implement an +file copier. It downloads the file from one server and transfer it to another! \ No newline at end of file diff --git a/log4.properties b/log4.properties new file mode 100644 index 0000000..4090469 --- /dev/null +++ b/log4.properties @@ -0,0 +1,10 @@ +log4j.rootLogger=INFO, stdout + + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%c] %m%n + + +log4j.logger.httpclient.wire.header=DEBUG +log4j.logger.org.apache.commons.httpclient=DEBUG \ No newline at end of file diff --git a/pom.xml b/pom.xml index ae78761..27a839d 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,9 @@ 4.1.2 jar compile + + commons-loggingcommons-logging + org.apache.httpcomponents @@ -35,5 +38,19 @@ jar compile + + org.slf4j + jcl-over-slf4j + 1.6.2 + jar + compile + + + org.slf4j + slf4j-log4j12 + 1.6.2 + jar + compile + \ No newline at end of file diff --git a/src/main/java/com/rogiel/httpchannel/service/AbstractDownloader.java b/src/main/java/com/rogiel/httpchannel/service/AbstractDownloader.java index 40affa3..a6ea153 100644 --- a/src/main/java/com/rogiel/httpchannel/service/AbstractDownloader.java +++ b/src/main/java/com/rogiel/httpchannel/service/AbstractDownloader.java @@ -24,7 +24,6 @@ import com.rogiel.httpchannel.util.ThreadUtils; /** * @author rogiel - * */ public abstract class AbstractDownloader implements Downloader { protected void timer(DownloadListener listener, long timer) { diff --git a/src/main/java/com/rogiel/httpchannel/service/AbstractHttpService.java b/src/main/java/com/rogiel/httpchannel/service/AbstractHttpService.java index 0d80612..4ef3a7b 100644 --- a/src/main/java/com/rogiel/httpchannel/service/AbstractHttpService.java +++ b/src/main/java/com/rogiel/httpchannel/service/AbstractHttpService.java @@ -16,11 +16,11 @@ */ package com.rogiel.httpchannel.service; - import org.apache.http.client.HttpClient; import org.apache.http.impl.client.DefaultHttpClient; import com.rogiel.httpchannel.service.config.ServiceConfiguration; +import com.rogiel.httpchannel.util.AlwaysRedirectStrategy; /** * Abstract base service for HTTP enabled services. @@ -33,9 +33,14 @@ public abstract class AbstractHttpService /** * The {@link HttpClient} instance for this service */ - protected HttpClient client = new DefaultHttpClient(); + protected DefaultHttpClient client = new DefaultHttpClient(); protected AbstractHttpService(T configuration) { super(configuration); + client.setRedirectStrategy(new AlwaysRedirectStrategy()); + // client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, + // true); + // client.getParams().setIntParameter(ClientPNames.MAX_REDIRECTS, 10); + // client.setRedirectStrategy(new DefaultRedirectStrategy()); } } diff --git a/src/main/java/com/rogiel/httpchannel/service/Authenticator.java b/src/main/java/com/rogiel/httpchannel/service/Authenticator.java index 8cf42b6..41d1d8a 100644 --- a/src/main/java/com/rogiel/httpchannel/service/Authenticator.java +++ b/src/main/java/com/rogiel/httpchannel/service/Authenticator.java @@ -34,7 +34,7 @@ public interface Authenticator { * @param listener * the listener do keep a track on the authentication progress */ - void login(AuthenticatorListener listener) throws IOException; + boolean login(AuthenticatorListener listener) throws IOException; /** * Logout into the {@link Service}. The session is restored to an not @@ -43,5 +43,5 @@ public interface Authenticator { * @param listener * the listener do keep a track on the logout progress */ - void logout(AuthenticatorListener listener) throws IOException; + boolean logout(AuthenticatorListener listener) throws IOException; } diff --git a/src/main/java/com/rogiel/httpchannel/service/AuthenticatorListener.java b/src/main/java/com/rogiel/httpchannel/service/AuthenticatorListener.java index 87e98bb..c0e8434 100644 --- a/src/main/java/com/rogiel/httpchannel/service/AuthenticatorListener.java +++ b/src/main/java/com/rogiel/httpchannel/service/AuthenticatorListener.java @@ -16,8 +16,6 @@ */ package com.rogiel.httpchannel.service; -import java.io.IOException; - /** * This listener keeps an track on the Authentication process. * @@ -25,23 +23,4 @@ import java.io.IOException; * @since 1.0 */ public interface AuthenticatorListener { - /** - * The username and password informed was not valid. - * - * @param credential - * the authenticating credential - */ - void invalidCredentials(Credential credential); - - /** - * The username and password informed was valid. User is authenticated. - * - * @param credential - * the authenticating credential - */ - void loginSuccessful(Credential credential); - - void logout(Credential credential); - - void exception(IOException e) throws IOException; } diff --git a/src/main/java/com/rogiel/httpchannel/service/impl/HotFileService.java b/src/main/java/com/rogiel/httpchannel/service/impl/HotFileService.java new file mode 100644 index 0000000..cdcf32d --- /dev/null +++ b/src/main/java/com/rogiel/httpchannel/service/impl/HotFileService.java @@ -0,0 +1,293 @@ +/* + * This file is part of seedbox . + * + * seedbox is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * seedbox is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with seedbox. If not, see . + */ +package com.rogiel.httpchannel.service.impl; + +import java.io.IOException; +import java.net.URL; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.regex.Pattern; + +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.mime.MultipartEntity; +import org.apache.http.entity.mime.content.StringBody; + +import com.rogiel.httpchannel.service.AbstractDownloader; +import com.rogiel.httpchannel.service.AbstractHttpService; +import com.rogiel.httpchannel.service.AuthenticationService; +import com.rogiel.httpchannel.service.Authenticator; +import com.rogiel.httpchannel.service.AuthenticatorCapability; +import com.rogiel.httpchannel.service.AuthenticatorListener; +import com.rogiel.httpchannel.service.CapabilityMatrix; +import com.rogiel.httpchannel.service.Credential; +import com.rogiel.httpchannel.service.DownloadChannel; +import com.rogiel.httpchannel.service.DownloadListener; +import com.rogiel.httpchannel.service.DownloadService; +import com.rogiel.httpchannel.service.Downloader; +import com.rogiel.httpchannel.service.DownloaderCapability; +import com.rogiel.httpchannel.service.Service; +import com.rogiel.httpchannel.service.UploadChannel; +import com.rogiel.httpchannel.service.UploadListener; +import com.rogiel.httpchannel.service.UploadListenerContentBody; +import com.rogiel.httpchannel.service.UploadService; +import com.rogiel.httpchannel.service.Uploader; +import com.rogiel.httpchannel.service.UploaderCapability; +import com.rogiel.httpchannel.service.channel.InputStreamDownloadChannel; +import com.rogiel.httpchannel.service.channel.LinkedUploadChannel; +import com.rogiel.httpchannel.service.channel.LinkedUploadChannel.LinkedUploadChannelCloseCallback; +import com.rogiel.httpchannel.service.config.ServiceConfiguration; +import com.rogiel.httpchannel.service.impl.HotFileService.HotFileServiceConfiguration; +import com.rogiel.httpchannel.util.HttpClientUtils; +import com.rogiel.httpchannel.util.PatternUtils; +import com.rogiel.httpchannel.util.ThreadUtils; + +/** + * This service handles login, upload and download to HotFile.com. + * + * @author Rogiel + * @since 1.0 + */ +public class HotFileService extends + AbstractHttpService implements Service, + UploadService, DownloadService, AuthenticationService { + private static final Pattern UPLOAD_URL_PATTERN = Pattern + .compile("http://u[0-9]*\\.hotfile\\.com/upload\\.cgi\\?[0-9]*"); + + private static final Pattern DOWNLOAD_DIRECT_LINK_PATTERN = Pattern + .compile("http://hotfile\\.com/get/([0-9]*)/([A-Za-z0-9]*)/([A-Za-z0-9]*)/([^\"]*)"); + private static final Pattern DOWNLOAD_TIMER = Pattern + .compile("timerend=d\\.getTime\\(\\)\\+([0-9]*);"); + // private static final Pattern DOWNLOAD_FILESIZE = Pattern + // .compile("[0-9]*(\\.[0-9]*)? (K|M|G)B"); + + private static final Pattern DOWNLOAD_URL_PATTERN = Pattern + .compile("http://hotfile\\.com/dl/([0-9]*)/([A-Za-z0-9]*)/([^\"]*)"); + + public HotFileService(final HotFileServiceConfiguration configuration) { + super(configuration); + } + + @Override + public String getId() { + return "hotfile"; + } + + @Override + public int getMajorVersion() { + return 1; + } + + @Override + public int getMinorVersion() { + return 0; + } + + @Override + public Uploader getUploader(String description) { + return new HotFileUploader(); + } + + @Override + public long getMaximumFilesize() { + return 1 * 1024 * 1024 * 1024; + } + + @Override + public CapabilityMatrix getUploadCapabilities() { + return new CapabilityMatrix( + UploaderCapability.UNAUTHENTICATED_UPLOAD, + UploaderCapability.NON_PREMIUM_ACCOUNT_UPLOAD, + UploaderCapability.PREMIUM_ACCOUNT_UPLOAD); + } + + @Override + public Downloader getDownloader(URL url) { + return new HotFileDownloader(url); + } + + @Override + public boolean matchURL(URL url) { + return false; + } + + @Override + public CapabilityMatrix getDownloadCapabilities() { + return new CapabilityMatrix( + DownloaderCapability.UNAUTHENTICATED_DOWNLOAD, + DownloaderCapability.NON_PREMIUM_ACCOUNT_DOWNLOAD, + DownloaderCapability.PREMIUM_ACCOUNT_DOWNLOAD); + } + + @Override + public Authenticator getAuthenticator(Credential credential) { + return new HotFileAuthenticator(credential); + } + + @Override + public CapabilityMatrix getAuthenticationCapability() { + return new CapabilityMatrix(); + } + + protected class HotFileUploader implements Uploader, + LinkedUploadChannelCloseCallback { + private Future uploadFuture; + + @Override + public UploadChannel upload(UploadListener listener) throws IOException { + final String body = HttpClientUtils.get(client, + "http://www.hotfile.com/"); + final String url = PatternUtils.find(UPLOAD_URL_PATTERN, body); + + final HttpPost upload = new HttpPost(url); + final MultipartEntity entity = new MultipartEntity(); + upload.setEntity(entity); + + final LinkedUploadChannel channel = new LinkedUploadChannel(this, + listener.getFilesize(), listener.getFilename()); + + entity.addPart("uploads[]", new UploadListenerContentBody(channel)); + + uploadFuture = HttpClientUtils.executeAsync(client, upload); + while (!channel.isLinked() && !uploadFuture.isDone()) { + ThreadUtils.sleep(100); + } + return channel; + } + + @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 HotFileDownloader extends AbstractDownloader { + private final URL url; + + public HotFileDownloader(URL url) { + this.url = url; + } + + @Override + public DownloadChannel download(DownloadListener listener) + throws IOException { + final HttpGet request = new HttpGet(url.toString()); + final HttpResponse response = client.execute(request); + final String content = IOUtils.toString(response.getEntity() + .getContent()); + + // try to find timer + final String stringTimer = PatternUtils.find(DOWNLOAD_TIMER, + content, 2, 1); + int timer = 0; + if (stringTimer != null && stringTimer.length() > 0) { + timer = Integer.parseInt(stringTimer); + } + if (timer > 0) { + cooldown(listener, timer); + return download(listener); + } + + final String downloadUrl = PatternUtils.find( + DOWNLOAD_DIRECT_LINK_PATTERN, content, 0); + if (downloadUrl != null && downloadUrl.length() > 0) { + final HttpGet downloadRequest = new HttpGet(downloadUrl); + final HttpResponse downloadResponse = client + .execute(downloadRequest); + final String filename = FilenameUtils.getName(downloadUrl); + + final Header contentLengthHeader = downloadResponse + .getFirstHeader("Content-Length"); + long contentLength = -1; + if (contentLengthHeader != null) { + contentLength = Long + .valueOf(contentLengthHeader.getValue()); + } + + return new InputStreamDownloadChannel(downloadResponse + .getEntity().getContent(), contentLength, filename); + } else { + throw new IOException("Download link not found"); + } + } + } + + protected class HotFileAuthenticator implements Authenticator { + private final Credential credential; + + public HotFileAuthenticator(Credential credential) { + this.credential = credential; + } + + @Override + public boolean login(AuthenticatorListener listener) + throws ClientProtocolException, IOException { + final HttpPost login = new HttpPost( + "http://www.hotfile.com/login.php"); + final MultipartEntity entity = new MultipartEntity(); + login.setEntity(entity); + + entity.addPart("returnto", new StringBody("/index.php")); + entity.addPart("user", new StringBody(credential.getUsername())); + entity.addPart("pass", new StringBody(credential.getPassword())); + + String response = HttpClientUtils.execute(client, login); + if (response.toLowerCase().contains( + credential.getUsername().toLowerCase())) + return true; + return false; + } + + @Override + public boolean logout(AuthenticatorListener listener) + throws IOException { + final HttpPost logout = new HttpPost( + "http://www.megaupload.com/?c=account"); + final MultipartEntity entity = new MultipartEntity(); + logout.setEntity(entity); + + entity.addPart("logout", new StringBody("1")); + HttpClientUtils.execute(client, logout); + + // TODO check logout status + + return true; + } + } + + public static interface HotFileServiceConfiguration extends + ServiceConfiguration { + } + + @Override + public String toString() { + return this.getClass().getSimpleName() + " " + getMajorVersion() + "." + + getMinorVersion(); + } +} diff --git a/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java b/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java index cfc537e..e64472e 100644 --- a/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java +++ b/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java @@ -22,7 +22,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.regex.Pattern; - import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.http.Header; @@ -266,51 +265,36 @@ public class MegaUploadService extends } @Override - public void login(AuthenticatorListener listener) { - try { - final HttpPost login = new HttpPost( - "http://www.megaupload.com/?c=login"); - final MultipartEntity entity = new MultipartEntity(); - login.setEntity(entity); + public boolean login(AuthenticatorListener listener) throws IOException { + final HttpPost login = new HttpPost( + "http://www.megaupload.com/?c=login"); + final MultipartEntity entity = new MultipartEntity(); + login.setEntity(entity); - entity.addPart("login", new StringBody("1")); - entity.addPart("username", - new StringBody(credential.getUsername())); - entity.addPart("password", - new StringBody(credential.getPassword())); + entity.addPart("login", new StringBody("1")); + entity.addPart("username", new StringBody(credential.getUsername())); + entity.addPart("password", new StringBody(credential.getPassword())); - final String response = HttpClientUtils.execute(client, login); - if (response.contains("Username and password do " - + "not match. Please try again!")) { - listener.invalidCredentials(credential); - return; - } - listener.loginSuccessful(credential); - } catch (IOException e) { - // throw new NestedLoginServiceException(e); - // TODO throw an exception here - } + final String response = HttpClientUtils.execute(client, login); + if (response.contains("Username and password do " + + "not match. Please try again!")) + return false; + return true; } @Override - public void logout(AuthenticatorListener listener) { - try { - final HttpPost logout = new HttpPost( - "http://www.megaupload.com/?c=account"); - final MultipartEntity entity = new MultipartEntity(); - logout.setEntity(entity); + public boolean logout(AuthenticatorListener listener) throws IOException { + final HttpPost logout = new HttpPost( + "http://www.megaupload.com/?c=account"); + final MultipartEntity entity = new MultipartEntity(); + logout.setEntity(entity); - entity.addPart("logout", new StringBody("1")); - HttpClientUtils.execute(client, logout); + entity.addPart("logout", new StringBody("1")); + HttpClientUtils.execute(client, logout); - // TODO check logout status + // TODO check logout status - listener.logout(credential); - return; - } catch (IOException e) { - // throw new NestedLoginServiceException(e); - // TODO throw an exception here - } + return true; } } diff --git a/src/main/java/com/rogiel/httpchannel/util/AlwaysRedirectStrategy.java b/src/main/java/com/rogiel/httpchannel/util/AlwaysRedirectStrategy.java new file mode 100644 index 0000000..347c4b2 --- /dev/null +++ b/src/main/java/com/rogiel/httpchannel/util/AlwaysRedirectStrategy.java @@ -0,0 +1,43 @@ +/* + * This file is part of seedbox . + * + * seedbox is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * seedbox is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with seedbox. If not, see . + */ +package com.rogiel.httpchannel.util; + +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.ProtocolException; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.impl.client.DefaultRedirectStrategy; +import org.apache.http.protocol.HttpContext; + +/** + * @author Rogiel + * + */ +public class AlwaysRedirectStrategy extends DefaultRedirectStrategy { + @Override + public boolean isRedirected(HttpRequest request, HttpResponse response, + HttpContext context) throws ProtocolException { + return response.getFirstHeader("location") != null; + } + + @Override + public HttpUriRequest getRedirect(HttpRequest request, + HttpResponse response, HttpContext context) + throws ProtocolException { + return super.getRedirect(request, response, context); + } +} diff --git a/src/main/java/com/rogiel/httpchannel/util/HttpClientUtils.java b/src/main/java/com/rogiel/httpchannel/util/HttpClientUtils.java index 5ab8a0c..b0417f8 100644 --- a/src/main/java/com/rogiel/httpchannel/util/HttpClientUtils.java +++ b/src/main/java/com/rogiel/httpchannel/util/HttpClientUtils.java @@ -52,6 +52,17 @@ public class HttpClientUtils { }); } + public static Future executeAsyncHttpResponse( + final HttpClient client, final HttpUriRequest request) + throws IOException { + return threadPool.submit(new Callable() { + @Override + public HttpResponse call() throws Exception { + return client.execute(request); + } + }); + } + public static String toString(HttpResponse response) throws IOException { final InputStream in = response.getEntity().getContent(); try { diff --git a/src/main/java/com/rogiel/httpchannel/util/PatternUtils.java b/src/main/java/com/rogiel/httpchannel/util/PatternUtils.java index df342e9..fab5403 100644 --- a/src/main/java/com/rogiel/httpchannel/util/PatternUtils.java +++ b/src/main/java/com/rogiel/httpchannel/util/PatternUtils.java @@ -31,7 +31,15 @@ public class PatternUtils { } return null; } - + + public static String find(Pattern pattern, String text, int index, int n) { + final Matcher matcher = pattern.matcher(text); + int found = 0; + while (matcher.find() && (++found) < index) { + } + return (found == 0 ? null : matcher.group(n)); + } + public static String match(Pattern pattern, String text) { return match(pattern, text, 0); } diff --git a/src/test/java/com/rogiel/httpchannel/service/impl/HotFileServiceTest.java b/src/test/java/com/rogiel/httpchannel/service/impl/HotFileServiceTest.java new file mode 100644 index 0000000..b93de81 --- /dev/null +++ b/src/test/java/com/rogiel/httpchannel/service/impl/HotFileServiceTest.java @@ -0,0 +1,245 @@ +/* + * This file is part of seedbox . + * + * seedbox is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * seedbox is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with seedbox. If not, see . + */ +package com.rogiel.httpchannel.service.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.util.Properties; + +import junit.framework.Assert; + +import org.apache.commons.io.IOUtils; +import org.junit.Before; +import org.junit.Test; + +import com.rogiel.httpchannel.service.AuthenticationService; +import com.rogiel.httpchannel.service.Credential; +import com.rogiel.httpchannel.service.DownloadChannel; +import com.rogiel.httpchannel.service.DownloadListener; +import com.rogiel.httpchannel.service.DownloadService; +import com.rogiel.httpchannel.service.Service; +import com.rogiel.httpchannel.service.UploadChannel; +import com.rogiel.httpchannel.service.UploadListener; +import com.rogiel.httpchannel.service.UploadService; +import com.rogiel.httpchannel.service.UploaderCapability; +import com.rogiel.httpchannel.service.captcha.Captcha; +import com.rogiel.httpchannel.service.config.ServiceConfigurationHelper; +import com.rogiel.httpchannel.service.impl.HotFileService.HotFileServiceConfiguration; +import com.rogiel.httpchannel.service.impl.MegaUploadService.MegaUploadServiceConfiguration; + +public class HotFileServiceTest { + private Service service; + + /** + * See src/test/resources/config/hotfile.properties + *

+ * Key: username + */ + private String VALID_USERNAME; + /** + * See src/test/resources/config/hotfile.properties + *

+ * Key: password + */ + private String VALID_PASSWORD; + + private static final String INVALID_USERNAME = "invalid"; + private static final String INVALID_PASSWORD = "abc"; + + @Before + public void setUp() throws Exception { + // MegaUploadServiceConfiguration.class; + service = new HotFileService( + ServiceConfigurationHelper + .defaultConfiguration(HotFileServiceConfiguration.class)); + + final Properties properties = new Properties(); + properties.load(new FileInputStream( + "src/test/resources/config/hotfile.properties")); + VALID_USERNAME = properties.getProperty("username"); + VALID_PASSWORD = properties.getProperty("password"); + } + + @Test + public void testServiceId() { + System.out.println("Service: " + service.toString()); + assertEquals("hotfile", service.getId()); + } + + @Test + public void testValidAuthenticator() throws IOException { + Assert.assertTrue(((AuthenticationService) service).getAuthenticator( + new Credential(VALID_USERNAME, VALID_PASSWORD)).login(null)); + } + + @Test + public void testInvalidAuthenticator() throws IOException { + Assert.assertFalse(((AuthenticationService) service).getAuthenticator( + new Credential(INVALID_USERNAME, INVALID_PASSWORD)).login(null)); + } + + @Test + public void testNonLoguedInUploader() throws IOException { + assertTrue( + "This service does not have the capability UploadCapability.FREE_UPLOAD", + ((UploadService) service).getUploadCapabilities().has( + UploaderCapability.NON_PREMIUM_ACCOUNT_UPLOAD)); + final UploadChannel channel = ((UploadService) service).getUploader( + "Upload by httpchannel").upload(new UploadListener() { + @Override + public long getFilesize() { + return new File("simulado_2010_1_res_all.zip").length(); + } + + @Override + public String getFilename() { + return "simulado_2010_1_res_all.zip"; + } + }); + + final FileChannel fileChannel = new FileInputStream( + "simulado_2010_1_res_all.zip").getChannel(); + + copy(fileChannel, channel); + channel.close(); + + System.out.println(channel.getDownloadLink()); + Assert.assertNotNull(channel.getDownloadLink()); + } + + @Test + public void testLoguedInUploader() throws IOException { + assertTrue( + "This service does not have the capability UploadCapability.PREMIUM_UPLOAD", + ((UploadService) service).getUploadCapabilities().has( + UploaderCapability.PREMIUM_ACCOUNT_UPLOAD)); + + Assert.assertTrue(((AuthenticationService) service).getAuthenticator( + new Credential(VALID_USERNAME, VALID_PASSWORD)).login(null)); + + final UploadChannel channel = ((UploadService) service).getUploader( + "Upload by httpchannel").upload(new UploadListener() { + @Override + public long getFilesize() { + return new File("simulado_2010_1_res_all.zip").length(); + } + + @Override + public String getFilename() { + return "simulado_2010_1_res_all.zip"; + } + }); + + final FileChannel fileChannel = new FileInputStream( + "simulado_2010_1_res_all.zip").getChannel(); + + copy(fileChannel, channel); + channel.close(); + + System.out.println(channel.getDownloadLink()); + Assert.assertNotNull(channel.getDownloadLink()); + } + + @Test + public void testDownloader() throws IOException, MalformedURLException { + final DownloadChannel channel = ((DownloadService) service) + .getDownloader( + new URL( + "http://hotfile.com/dl/129251605/9b4faf2/simulado_2010_1_res_all.zip.html")) + .download(new DownloadListener() { + @Override + public boolean timer(long time, TimerWaitReason reason) { + System.out.println("Waiting " + time + " in " + reason); + // if (reason == TimerWaitReason.DOWNLOAD_TIMER) + // return true; + return true; + } + + @Override + public String captcha(Captcha captcha) { + return null; + } + }); + final ByteArrayOutputStream bout = new ByteArrayOutputStream(); + IOUtils.copy(Channels.newInputStream(channel), bout); + System.out.println(bout.size()); + } + + @Test + public void testLoggedInDownloader() throws IOException, + MalformedURLException { + Assert.assertTrue(((AuthenticationService) service).getAuthenticator( + new Credential(VALID_USERNAME, VALID_PASSWORD)).login(null)); + + final DownloadChannel channel = ((DownloadService) service) + .getDownloader(new URL("http://hotfile.com/dl/129251605/9b4faf2/simulado_2010_1_res_all.zip.html")) + .download(new DownloadListener() { + @Override + public boolean timer(long time, TimerWaitReason reason) { + System.out.println("Waiting " + time + " in " + reason); + if (reason == TimerWaitReason.DOWNLOAD_TIMER) + return true; + return false; + } + + @Override + public String captcha(Captcha captcha) { + // TODO Auto-generated method stub + return null; + } + }); + + final ByteArrayOutputStream bout = new ByteArrayOutputStream(); + IOUtils.copy(Channels.newInputStream(channel), bout); + System.out.println(bout.size()); + } + + public static void copy(ReadableByteChannel in, WritableByteChannel out) + throws IOException { + // First, we need a buffer to hold blocks of copied bytes. + ByteBuffer buffer = ByteBuffer.allocateDirect(32 * 1024); + + // Now loop until no more bytes to read and the buffer is empty + while (in.read(buffer) != -1 || buffer.position() > 0) { + // The read() call leaves the buffer in "fill mode". To prepare + // to write bytes from the bufferwe have to put it in "drain mode" + // by flipping it: setting limit to position and position to zero + buffer.flip(); + + // Now write some or all of the bytes out to the output channel + out.write(buffer); + + // Compact the buffer by discarding bytes that were written, + // and shifting any remaining bytes. This method also + // prepares the buffer for the next call to read() by setting the + // position to the limit and the limit to the buffer capacity. + buffer.compact(); + } + } +} diff --git a/src/test/java/com/rogiel/httpchannel/service/impl/MegaUploadServiceTest.java b/src/test/java/com/rogiel/httpchannel/service/impl/MegaUploadServiceTest.java index 2185fb4..5e62630 100644 --- a/src/test/java/com/rogiel/httpchannel/service/impl/MegaUploadServiceTest.java +++ b/src/test/java/com/rogiel/httpchannel/service/impl/MegaUploadServiceTest.java @@ -18,7 +18,6 @@ package com.rogiel.httpchannel.service.impl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.File; @@ -37,7 +36,6 @@ import org.junit.Before; import org.junit.Test; import com.rogiel.httpchannel.service.AuthenticationService; -import com.rogiel.httpchannel.service.AuthenticatorListener; import com.rogiel.httpchannel.service.Credential; import com.rogiel.httpchannel.service.DownloadChannel; import com.rogiel.httpchannel.service.DownloadListener; @@ -86,58 +84,20 @@ public class MegaUploadServiceTest { @Test public void testServiceId() { - System.out.println("Service: "+service.toString()); + System.out.println("Service: " + service.toString()); assertEquals("megaupload", service.getId()); } @Test public void testValidAuthenticator() throws IOException { - ((AuthenticationService) service).getAuthenticator( - new Credential(VALID_USERNAME, VALID_PASSWORD)).login( - new AuthenticatorListener() { - @Override - public void invalidCredentials(Credential credential) { - fail("This login attemp should've been successful."); - } - - @Override - public void loginSuccessful(Credential credential) { - } - - @Override - public void logout(Credential credential) { - } - - @Override - public void exception(IOException e) throws IOException { - throw e; - } - }); + Assert.assertTrue(((AuthenticationService) service).getAuthenticator( + new Credential(VALID_USERNAME, VALID_PASSWORD)).login(null)); } @Test public void testInvalidAuthenticator() throws IOException { - ((AuthenticationService) service).getAuthenticator( - new Credential(INVALID_USERNAME, INVALID_PASSWORD)).login( - new AuthenticatorListener() { - @Override - public void invalidCredentials(Credential credential) { - } - - @Override - public void loginSuccessful(Credential credential) { - fail("This login attemp should't have been successful."); - } - - @Override - public void logout(Credential credential) { - } - - @Override - public void exception(IOException e) throws IOException { - throw e; - } - }); + Assert.assertFalse(((AuthenticationService) service).getAuthenticator( + new Credential(INVALID_USERNAME, INVALID_PASSWORD)).login(null)); } @Test @@ -184,28 +144,8 @@ public class MegaUploadServiceTest { ((UploadService) service).getUploadCapabilities().has( UploaderCapability.PREMIUM_ACCOUNT_UPLOAD)); - ((AuthenticationService) service).getAuthenticator( - new Credential(VALID_USERNAME, VALID_PASSWORD)).login( - new AuthenticatorListener() { - @Override - public void invalidCredentials(Credential credential) { - fail("Invalid credentials"); - } - - @Override - public void loginSuccessful(Credential credential) { - } - - @Override - public void logout(Credential credential) { - } - - @Override - public void exception(IOException e) throws IOException { - // TODO Auto-generated method stub - - } - }); + Assert.assertTrue(((AuthenticationService) service).getAuthenticator( + new Credential(VALID_USERNAME, VALID_PASSWORD)).login(null)); final UploadChannel channel = ((UploadService) service).getUploader( "Upload by httpchannel").upload(new UploadListener() { diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties new file mode 100644 index 0000000..29ae93a --- /dev/null +++ b/src/test/resources/log4j.properties @@ -0,0 +1,9 @@ +log4j.rootLogger=INFO, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%c] %m%n + +log4j.logger.org.apache.http.impl.conn=DEBUG +log4j.logger.org.apache.http.impl.client=DEBUG +log4j.logger.org.apache.http.client=DEBUG \ No newline at end of file