diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Authenticator.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Authenticator.java index 8314d9c..7ffd0f6 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Authenticator.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Authenticator.java @@ -82,6 +82,25 @@ public interface Authenticator { * @author Rogiel */ public interface AuthenticatorConfiguration { + /** + * Checks whether the configuration object can be casted to + * type + * + * @param type + * the casting type + * @return true if this object can be casted to + * type + */ + boolean is(Class type); + /** + * Casts this object to type. If cannot be casted, + * null is returned. + * + * @param type + * the casting type + * @return the casted configuration + */ + T as(Class type); } } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Downloader.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Downloader.java index 2a7c86e..6180f7f 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Downloader.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Downloader.java @@ -208,6 +208,25 @@ public interface Downloader { * @author Rogiel */ public interface DownloaderConfiguration { + /** + * Checks whether the configuration object can be casted to + * type + * + * @param type + * the casting type + * @return true if this object can be casted to + * type + */ + boolean is(Class type); + /** + * Casts this object to type. If cannot be casted, + * null is returned. + * + * @param type + * the casting type + * @return the casted configuration + */ + T as(Class type); } } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Uploader.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Uploader.java index c7d38bc..92e50bd 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Uploader.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/Uploader.java @@ -80,6 +80,26 @@ public interface Uploader { * @author Rogiel */ public interface UploaderConfiguration { + /** + * Checks whether the configuration object can be casted to + * type + * + * @param type + * the casting type + * @return true if this object can be casted to + * type + */ + boolean is(Class type); + + /** + * Casts this object to type. If cannot be casted, + * null is returned. + * + * @param type + * the casting type + * @return the casted configuration + */ + T as(Class type); } /** diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullAuthenticatorConfiguration.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullAuthenticatorConfiguration.java index 45d7135..abc80ec 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullAuthenticatorConfiguration.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullAuthenticatorConfiguration.java @@ -35,4 +35,14 @@ public final class NullAuthenticatorConfiguration implements private NullAuthenticatorConfiguration() { } + + @Override + public boolean is(Class type) { + return false; + } + + @Override + public T as(Class type) { + return null; + } } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullDownloaderConfiguration.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullDownloaderConfiguration.java index 7d7ab38..690cdf6 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullDownloaderConfiguration.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullDownloaderConfiguration.java @@ -34,4 +34,14 @@ public final class NullDownloaderConfiguration implements private NullDownloaderConfiguration() { } + + @Override + public boolean is(Class type) { + return false; + } + + @Override + public T as(Class type) { + return null; + } } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullUploaderConfiguration.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullUploaderConfiguration.java index 87ace63..a2fea0b 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullUploaderConfiguration.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/config/NullUploaderConfiguration.java @@ -33,4 +33,14 @@ public final class NullUploaderConfiguration implements UploaderConfiguration { private NullUploaderConfiguration() { } + + @Override + public boolean is(Class type) { + return false; + } + + @Override + public T as(Class type) { + return null; + } } diff --git a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/helper/Services.java b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/helper/Services.java index 1c2baa3..ebf7429 100644 --- a/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/helper/Services.java +++ b/httpchannel-api/src/main/java/com/rogiel/httpchannel/service/helper/Services.java @@ -25,6 +25,7 @@ import java.util.ServiceLoader; import com.rogiel.httpchannel.service.DownloadService; import com.rogiel.httpchannel.service.Service; import com.rogiel.httpchannel.service.ServiceID; +import com.rogiel.httpchannel.service.UploadService; /** * @author Rogiel @@ -73,6 +74,36 @@ public class Services { } return null; } + + /** + * Tries to detect which service has the given id + * + * @param id + * the service id + * @return the matched service + */ + public static UploadService getUploadService(ServiceID id) { + for (final Service service : iterate()) { + if (service.getServiceID().equals(id)) + return (UploadService) service; + } + return null; + } + + /** + * Tries to detect which service has the given id + * + * @param id + * the service id + * @return the matched service + */ + public static DownloadService getDownloadService(ServiceID id) { + for (final Service service : iterate()) { + if (service.getServiceID().equals(id)) + return (DownloadService) service; + } + return null; + } /** * Creates a new {@link Iterable} instance to iterate over services diff --git a/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadDownloaderConfiguration.java b/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadDownloaderConfiguration.java index b256c67..7aedf96 100644 --- a/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadDownloaderConfiguration.java +++ b/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadDownloaderConfiguration.java @@ -18,10 +18,11 @@ */ package com.rogiel.httpchannel.service.impl; +import com.rogiel.httpchannel.service.AbstractDownloaderConfiguration; import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration; -public class MegaUploadDownloaderConfiguration implements - DownloaderConfiguration { +public class MegaUploadDownloaderConfiguration extends + AbstractDownloaderConfiguration implements DownloaderConfiguration { private boolean respectWaitTime = true; public boolean getRespectWaitTime() { diff --git a/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java b/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java index 7ec6a83..0a66446 100644 --- a/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java +++ b/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadService.java @@ -74,7 +74,7 @@ public class MegaUploadService extends AbstractHttpService implements Service, */ public static final ServiceID SERVICE_ID = ServiceID.create("megaupload"); - private static final Pattern UPLOAD_URI_PATTERN = Pattern + private static final Pattern UPLOAD_URL_PATTERN = Pattern .compile("http://www([0-9]*)\\.megaupload\\.com/upload_done\\.php\\?UPLOAD_IDENTIFIER=[0-9]*"); private static final Pattern DOWNLOAD_DIRECT_LINK_PATTERN = Pattern @@ -217,7 +217,7 @@ public class MegaUploadService extends AbstractHttpService implements Service, logger.debug("Starting upload to megaupload.com"); final HTMLPage page = get("http://www.megaupload.com/multiupload/") .asPage(); - final String uri = page.findFormAction(UPLOAD_URI_PATTERN); + final String uri = page.findFormAction(UPLOAD_URL_PATTERN); logger.debug("Upload URI is {}", uri); final LinkedUploadChannel channel = createLinkedChannel(this); diff --git a/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadUploaderConfiguration.java b/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadUploaderConfiguration.java index 3825caa..3437f8b 100644 --- a/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadUploaderConfiguration.java +++ b/httpchannel-service/httpchannel-service-megaupload/src/main/java/com/rogiel/httpchannel/service/impl/MegaUploadUploaderConfiguration.java @@ -18,6 +18,7 @@ */ package com.rogiel.httpchannel.service.impl; +import com.rogiel.httpchannel.service.AbstractUploaderConfiguration; import com.rogiel.httpchannel.service.Uploader.DescriptionableUploaderConfiguration; import com.rogiel.httpchannel.service.Uploader.UploaderConfiguration; import com.rogiel.httpchannel.service.impl.MegaUploadService.UploaderImpl; @@ -27,7 +28,8 @@ import com.rogiel.httpchannel.service.impl.MegaUploadService.UploaderImpl; * * @author Rogiel */ -public class MegaUploadUploaderConfiguration implements UploaderConfiguration, +public class MegaUploadUploaderConfiguration extends + AbstractUploaderConfiguration implements UploaderConfiguration, DescriptionableUploaderConfiguration { /** * The upload description diff --git a/httpchannel-service/httpchannel-service-multiupload/src/main/java/com/rogiel/httpchannel/service/impl/MultiUploadUploaderConfiguration.java b/httpchannel-service/httpchannel-service-multiupload/src/main/java/com/rogiel/httpchannel/service/impl/MultiUploadUploaderConfiguration.java index 398d003..42052b2 100644 --- a/httpchannel-service/httpchannel-service-multiupload/src/main/java/com/rogiel/httpchannel/service/impl/MultiUploadUploaderConfiguration.java +++ b/httpchannel-service/httpchannel-service-multiupload/src/main/java/com/rogiel/httpchannel/service/impl/MultiUploadUploaderConfiguration.java @@ -20,6 +20,7 @@ package com.rogiel.httpchannel.service.impl; import java.util.EnumSet; +import com.rogiel.httpchannel.service.AbstractUploaderConfiguration; import com.rogiel.httpchannel.service.Uploader.DescriptionableUploaderConfiguration; import com.rogiel.httpchannel.service.Uploader.UploaderConfiguration; import com.rogiel.httpchannel.service.impl.MultiUploadService.UploaderImpl; @@ -29,7 +30,8 @@ import com.rogiel.httpchannel.service.impl.MultiUploadService.UploaderImpl; * * @author Rogiel */ -public class MultiUploadUploaderConfiguration implements UploaderConfiguration, +public class MultiUploadUploaderConfiguration extends + AbstractUploaderConfiguration implements UploaderConfiguration, DescriptionableUploaderConfiguration { /** * The upload description diff --git a/httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareUploaderConfiguration.java b/httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareUploaderConfiguration.java index 885debf..96b1f6f 100644 --- a/httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareUploaderConfiguration.java +++ b/httpchannel-service/httpchannel-service-zshare/src/main/java/com/rogiel/httpchannel/service/impl/ZShareUploaderConfiguration.java @@ -18,6 +18,7 @@ */ package com.rogiel.httpchannel.service.impl; +import com.rogiel.httpchannel.service.AbstractUploaderConfiguration; import com.rogiel.httpchannel.service.Uploader.DescriptionableUploaderConfiguration; import com.rogiel.httpchannel.service.Uploader.UploaderConfiguration; @@ -26,8 +27,8 @@ import com.rogiel.httpchannel.service.Uploader.UploaderConfiguration; * * @author Rogiel */ -public class ZShareUploaderConfiguration implements UploaderConfiguration, - DescriptionableUploaderConfiguration { +public class ZShareUploaderConfiguration extends AbstractUploaderConfiguration + implements UploaderConfiguration, DescriptionableUploaderConfiguration { /** * The upload description */ diff --git a/httpchannel-service/pom.xml b/httpchannel-service/pom.xml index c389440..a10e4c9 100644 --- a/httpchannel-service/pom.xml +++ b/httpchannel-service/pom.xml @@ -15,11 +15,13 @@ httpchannel-service-megaupload - httpchannel-service-hotfile httpchannel-service-multiupload - httpchannel-service-zshare - + httpchannel-service-uploadking + httpchannel-service-uploadhere + httpchannel-service-depositfiles + httpchannel-service-hotfile httpchannel-service-filesonic + httpchannel-service-zshare diff --git a/httpchannel-service/src/site/site.xml b/httpchannel-service/src/site/site.xml new file mode 100644 index 0000000..7baf509 --- /dev/null +++ b/httpchannel-service/src/site/site.xml @@ -0,0 +1,4 @@ + + \ No newline at end of file diff --git a/httpchannel-service/src/site/xdoc/implementing-services.xml b/httpchannel-service/src/site/xdoc/implementing-services.xml new file mode 100644 index 0000000..5515550 --- /dev/null +++ b/httpchannel-service/src/site/xdoc/implementing-services.xml @@ -0,0 +1,265 @@ + + + + Home + Rogiel Sulzbach + + + + +
+

Implementing services is really easy. There's a lot of abstraction + done in the service layer, that it donesn't even look that you are +

+ +

+ In order to implement a new service, you first need to create a + class that implements + Service + . This interface provides basic information about the service, such + as version and ID. This however, is not enough and you need to + implement other specific interfaces for each type of behavior you + want: +

+ +
    +
  • + UploadService + : implements support for + UploadChannel +
  • +
  • + DownloadService + : implements support for + DownloadChannel +
  • +
  • + AuthenticationService + : implements support for account authentication (such as premium + accounts) +
  • +
+ +

+ Let's first implement an + UploadService + for + megaupload.com + site: +

+ + ]]> + + + We extend + AbstractHttpService + which provides several handy methods for HTTP requests, it also + handles all the cookies for us, so we don't need to deal with + anything else but the HTML parsing. + + +

Now we add a few static fields that are gonna be used later on: +

+ + + + Those patterns will match the URLs we need to upload the file + and find the download link. + + + getPossibleServiceModes() { + return new CapabilityMatrix(ServiceMode.UNAUTHENTICATED); + }]]> + + + This simple service implementation does not support authentication. + As such, the only supported mode is + ServiceMode.UNAUTHENTICATED + . + + + getUploader( + String filename, long filesize, + MegaUploadUploaderConfiguration configuration) { + return new UploaderImpl(filename, filesize, configuration); + } + + @Override + public Uploader getUploader( + String filename, long filesize) { + return getUploader(filename, filesize, newUploaderConfiguration()); + } + + @Override + public MegaUploadUploaderConfiguration newUploaderConfiguration() { + return new MegaUploadUploaderConfiguration(); + } + + @Override + public long getMaximumFilesize() { + return Filesizes.gb(1); + } + + @Override + public String[] getSupportedExtensions() { + return null; // all extensions are suppoted, null need to be returned then + } + + @Override + public CapabilityMatrix getUploadCapabilities() { + return new CapabilityMatrix(UploaderCapability.UNAUTHENTICATED_UPLOAD); + }]]> + + + Again, this simple service implementation does not support + authentication. + As such, the only + upload capability + supported is + UploaderCapability.UNAUTHENTICATED + . + + + implements + Uploader, + LinkedUploadChannelCloseCallback { + private Future uploadFuture; + + public UploaderImpl(String filename, long filesize, + MegaUploadUploaderConfiguration configuration) { + super(MegaUploadService.this, filename, filesize, configuration); + }]]> + +

+ Notice we also implement LinkedUploadChannelCloseCallback. The + single method in this interface is called to finish the upload and + return the download link. Also + AbstractUploader + is implemented because it provides a lot of handy methods that can + shortcut the implementation. +

+ + + +

Here is a bit implementation specific: we load the megaupload.com + page and return it as an HTNLPage. An HTMLPage is an parsed version + of the page, it contains several methods that provide methods for + finding form urls and links. +

+ +

+ Now, once we load the page, we use the HTMLPage object to find a + form action using an Pattern with + findFormAction + . That is the URI we will use to do the upload. +

+ +

The a new UploadChannel is created, internally it uses an + LinkedUploadChannel which is a specific type of channel that gets + linked with another channel, and acts as some kind of "proxy" + channel. +

+ +

Here the fun part, we create a new "multipart HTTP request". + Multipart requests generally contain binary data, so we need to use + those to implement the service. Upload parameters are bound to the + request using a chain method, this makes code compact and easy to + read. +

+ +

+ Finally, we execute + asStringAsync + that will return the page as an java String and executes the request + asynchronously (that is, it is not going to block, but will execute + on another Thread.). The future object returned is stored into an + field, because it will be used later by the + finish() + method. +

+ +

Finally, we wait for the channel to be effectivelly linked and + return it. Channel link may take some time until the HTTP request + estabilishes the connection and is ready to receive data, that is + why waiting for the link is of extreme importance. +

+ +

+ Now the channel is returned to the user which will write data and + perform all kind of cool things with the channel. When the user + calls the + close() + method, the + finish() + method (defined by + LinkedUploadChannelCloseCallback + ) is invoked and the upload is finished. +

+ + + +

This portion of code is fairly easy to understand, it uses the + future that we previously created to get the resulting page. This + does not need to be an string, it can be any of the supported types. + Since MegaUpload retuns a JSON string, we need to use a string to + match it against an Pattern. Once the URL is matched, it is + returned, if no link is found, null should be returned and the + channel close() method will deal will all the exception throwing. +

+ +

Your service is now ready. You can starting using it!

+
+ +
\ No newline at end of file diff --git a/httpchannel-service/src/site/xdoc/service-table.xml b/httpchannel-service/src/site/xdoc/service-table.xml new file mode 100644 index 0000000..e1bff25 --- /dev/null +++ b/httpchannel-service/src/site/xdoc/service-table.xml @@ -0,0 +1,115 @@ + + + + Home + Rogiel Sulzbach + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Service NameService IDAuthenticationUploadDownload
+ DepositFiles + depositfilesYesYesup to 1GBNo
+ FileSonic + filesonicYesYesup to 1GBNo
+ HotFile + hotfileYesYesup to 1GBNo
+ MegaUpload + megauploadYesYes + up to 1GB non-premium, 2GB premium +
+ DescriptionableUploaderConfiguration +
Yesresumable, extended configuration
+ MultiUpload + multiuploadYesYes + up to 1GB +
+ extended configuration, + DescriptionableUploaderConfiguration +
Yesresumable
+ UploadHere + uploadhereYesYesup to 1GBYesresumable, captcha
+ UploadKing + uploadkingYesYesup to 1GBYesresumable, captcha
+
+ +
\ No newline at end of file diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractAuthenticatorConfiguration.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractAuthenticatorConfiguration.java new file mode 100644 index 0000000..5d70f35 --- /dev/null +++ b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractAuthenticatorConfiguration.java @@ -0,0 +1,25 @@ +/** + * + */ +package com.rogiel.httpchannel.service; + +import com.rogiel.httpchannel.service.Authenticator.AuthenticatorConfiguration; + +/** + * @author Rogiel + * + */ +public class AbstractAuthenticatorConfiguration implements + AuthenticatorConfiguration { + @Override + public boolean is(Class type) { + return type.isAssignableFrom(this.getClass()); + } + + @Override + public T as(Class type) { + if (!is(type)) + return null; + return type.cast(this); + } +} diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractDownloaderConfiguration.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractDownloaderConfiguration.java new file mode 100644 index 0000000..62b1f80 --- /dev/null +++ b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractDownloaderConfiguration.java @@ -0,0 +1,24 @@ +/** + * + */ +package com.rogiel.httpchannel.service; + +import com.rogiel.httpchannel.service.Downloader.DownloaderConfiguration; + +/** + * @author Rogiel + * + */ +public class AbstractDownloaderConfiguration implements DownloaderConfiguration { + @Override + public boolean is(Class type) { + return type.isAssignableFrom(this.getClass()); + } + + @Override + public T as(Class type) { + if (!is(type)) + return null; + return type.cast(this); + } +} diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractUploaderConfiguration.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractUploaderConfiguration.java new file mode 100644 index 0000000..0042043 --- /dev/null +++ b/httpchannel-util/src/main/java/com/rogiel/httpchannel/service/AbstractUploaderConfiguration.java @@ -0,0 +1,24 @@ +/** + * + */ +package com.rogiel.httpchannel.service; + +import com.rogiel.httpchannel.service.Uploader.UploaderConfiguration; + +/** + * @author Rogiel + * + */ +public class AbstractUploaderConfiguration implements UploaderConfiguration { + @Override + public boolean is(Class type) { + return type.isAssignableFrom(this.getClass()); + } + + @Override + public T as(Class type) { + if (!is(type)) + return null; + return type.cast(this); + } +} diff --git a/httpchannel-util/src/main/java/com/rogiel/httpchannel/util/Filesizes.java b/httpchannel-util/src/main/java/com/rogiel/httpchannel/util/Filesizes.java new file mode 100644 index 0000000..fb1bab5 --- /dev/null +++ b/httpchannel-util/src/main/java/com/rogiel/httpchannel/util/Filesizes.java @@ -0,0 +1,22 @@ +/** + * + */ +package com.rogiel.httpchannel.util; + +/** + * @author Rogiel + * + */ +public class Filesizes { + public static long kb(long kb) { + return kb * 1024; + } + + public static long mb(long mb) { + return kb(mb) * 1024; + } + + public static long gb(long gb) { + return mb(gb) * 1024; + } +} diff --git a/src/site/site.xml b/src/site/site.xml new file mode 100644 index 0000000..b64cd59 --- /dev/null +++ b/src/site/site.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml new file mode 100644 index 0000000..4e5176b --- /dev/null +++ b/src/site/xdoc/index.xml @@ -0,0 +1,105 @@ + + + + Home + Rogiel Sulzbach + + + + +
+

+ The HttpChannel library is a library that povides downloading and + uploading capaibilities to several share-sites (such as + MegaUpload + and + FileSonic + ). Obviously, the API supports a lot more services, but those are + the most commonly used. Aside from that, the biggest point of the + library is its simple usage, you don't need to use any customized + API to perform download or uploads, you simply use the standard Java + NIO Channels for both upload and download. +

+ + service = Services.getUploadService("megaupload"); +final Uploader uploader = UploadServices.upload(service, Path.get("test-file.txt")); +final UploadChannel channel = uploader.openChannel(); +// now, you can perform any operation you want with this channel! +ChannelUtils.copy(inputChannel, channel); +// this may take some time, it will finish the upload and generate the download link +channel.close(); +System.out.println("Download Link: "+channel.getDownloadLink());]]> + + +

Yeah! This is the fastest way to start an upload, you can also + customize a bit your upload. MegaUpload supports upload + configuration, the most common configuration options has an + interface which all service that supports it should extent, see + above: +

+ + +

You have two ways of setting and upload description. The way + showed previously, supports all the services which provide + description supported, howerver, if this is not intented, you can + cast it directly to the service configuration interface: +

+ + Although this does not give any compilation error, this is + not the correct way to do. If you ever remove the MegaUpload + service, you compilation will break and you will need to fix this + manually. Also, changes to the internal service implementation + could change and your compilation would break, again! + +

Now, only uploads to MegaUpload.com will have a description. + Aside + from that, all configuration objects have a default + description + value: "Uploaded by httpchannel". This cannot be + overriden and if + you want to, you need to set the description to all + services that + support description. +

+
+ + +

+ The library also support CAPTCHA solving, not automatically but + through + CAPTCHA solving services + . To bind an + CaptchaService + to an HttpChannel service, all you need to do is: +

+ + + +

+ Now, all CAPTCHAs that need to be solved, will be forwarded to + CaptchaTrader + for solving. +

+
+
+ +
+

+ To implement new services, you can follow + this guide + or look at the sources. +

+
+ +
\ No newline at end of file