mirror of
https://github.com/Rogiel/httpchannel
synced 2025-12-05 23:22:51 +00:00
Implements 2shared service and improves channel link synchronization
This commit is contained in:
@@ -1,5 +1,20 @@
|
|||||||
/**
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
*/
|
*/
|
||||||
package com.rogiel.httpchannel.service;
|
package com.rogiel.httpchannel.service;
|
||||||
|
|
||||||
|
|||||||
14
httpchannel-service/httpchannel-service-2shared/pom.xml
Normal file
14
httpchannel-service/httpchannel-service-2shared/pom.xml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<artifactId>httpchannel-service-2shared</artifactId>
|
||||||
|
<groupId>com.rogiel.httpchannel.service</groupId>
|
||||||
|
<name>HttpChannel/Service/TwoShared</name>
|
||||||
|
<description>Provides download and upload access for 2shared.com</description>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package com.rogiel.httpchannel.service.twoshared;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.rogiel.httpchannel.captcha.exception.UnsolvableCaptchaServiceException;
|
||||||
|
import com.rogiel.httpchannel.service.AbstractHttpDownloader;
|
||||||
|
import com.rogiel.httpchannel.service.AbstractHttpService;
|
||||||
|
import com.rogiel.httpchannel.service.AbstractUploader;
|
||||||
|
import com.rogiel.httpchannel.service.CapabilityMatrix;
|
||||||
|
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.ServiceID;
|
||||||
|
import com.rogiel.httpchannel.service.ServiceMode;
|
||||||
|
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.NullDownloaderConfiguration;
|
||||||
|
import com.rogiel.httpchannel.service.config.NullUploaderConfiguration;
|
||||||
|
import com.rogiel.httpchannel.service.exception.DownloadLimitExceededException;
|
||||||
|
import com.rogiel.httpchannel.service.exception.DownloadLinkNotFoundException;
|
||||||
|
import com.rogiel.httpchannel.service.exception.DownloadNotAuthorizedException;
|
||||||
|
import com.rogiel.httpchannel.service.exception.DownloadNotResumableException;
|
||||||
|
import com.rogiel.httpchannel.service.exception.NoCaptchaServiceException;
|
||||||
|
import com.rogiel.httpchannel.util.ExceptionUtils;
|
||||||
|
import com.rogiel.httpchannel.util.htmlparser.HTMLPage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This service handles uploads to TwoShared.
|
||||||
|
*
|
||||||
|
* @author <a href="http://www.rogiel.com/">Rogiel</a>
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
public class TwoSharedService extends AbstractHttpService implements Service,
|
||||||
|
UploadService<NullUploaderConfiguration>,
|
||||||
|
DownloadService<NullDownloaderConfiguration> {
|
||||||
|
/**
|
||||||
|
* This service ID
|
||||||
|
*/
|
||||||
|
public static final ServiceID SERVICE_ID = ServiceID.create("twoshared");
|
||||||
|
|
||||||
|
private static final Pattern UPLOAD_URL_PATTERN = Pattern
|
||||||
|
.compile("http://dc[0-9]*\\.2shared\\.com/main/upload2\\.jsp\\?sId=[A-z0-9]*");
|
||||||
|
private static final Pattern UPLOAD_ID_PATTERN = Pattern
|
||||||
|
.compile("sId=([A-z0-9]*)");
|
||||||
|
|
||||||
|
private static final Pattern DOWNLOAD_URL_PATTERN = Pattern
|
||||||
|
.compile("http://(www\\.)?2shared\\.com/document/[A-z0-9]*/.*");
|
||||||
|
private static final Pattern DIRECT_DOWNLOAD_URL_PATTERN = Pattern
|
||||||
|
.compile("http://dc[0-9]+\\.2shared\\.com/download/[A-z0-9]+/.+\\?tsid=[0-9]{8}-[0-9]{6}-[A-z0-9]{8}");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServiceID getServiceID() {
|
||||||
|
return SERVICE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMajorVersion() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMinorVersion() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CapabilityMatrix<ServiceMode> getPossibleServiceModes() {
|
||||||
|
return new CapabilityMatrix<ServiceMode>(ServiceMode.UNAUTHENTICATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@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() {
|
||||||
|
// no configuration
|
||||||
|
return NullUploaderConfiguration.SHARED_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getMaximumFilesize() {
|
||||||
|
// no filesize limit
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getSupportedExtensions() {
|
||||||
|
// no extension restriction
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CapabilityMatrix<UploaderCapability> getUploadCapabilities() {
|
||||||
|
return new CapabilityMatrix<UploaderCapability>(
|
||||||
|
UploaderCapability.UNAUTHENTICATED_UPLOAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Downloader<NullDownloaderConfiguration> getDownloader(URI uri,
|
||||||
|
NullDownloaderConfiguration configuration) {
|
||||||
|
return new DownloaderImpl(uri, configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Downloader<NullDownloaderConfiguration> getDownloader(URI uri) {
|
||||||
|
return getDownloader(uri, newDownloaderConfiguration());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NullDownloaderConfiguration newDownloaderConfiguration() {
|
||||||
|
return NullDownloaderConfiguration.SHARED_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchURI(URI uri) {
|
||||||
|
return DOWNLOAD_URL_PATTERN.matcher(uri.toString()).matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CapabilityMatrix<DownloaderCapability> getDownloadCapabilities() {
|
||||||
|
return new CapabilityMatrix<DownloaderCapability>(
|
||||||
|
DownloaderCapability.UNAUTHENTICATED_DOWNLOAD,
|
||||||
|
DownloaderCapability.UNAUTHENTICATED_RESUME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class UploaderImpl extends
|
||||||
|
AbstractUploader<NullUploaderConfiguration> implements
|
||||||
|
Uploader<NullUploaderConfiguration>,
|
||||||
|
LinkedUploadChannelCloseCallback {
|
||||||
|
private Future<HTMLPage> uploadFuture;
|
||||||
|
private String uploadID;
|
||||||
|
|
||||||
|
public UploaderImpl(String filename, long filesize,
|
||||||
|
NullUploaderConfiguration configuration) {
|
||||||
|
super(TwoSharedService.this, filename, filesize, configuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UploadChannel openChannel() throws IOException {
|
||||||
|
logger.debug("Starting upload to TwoShared");
|
||||||
|
final HTMLPage page = get("http://www.2shared.com/").asPage();
|
||||||
|
|
||||||
|
// locate upload uri
|
||||||
|
final String uri = page.findFormAction(UPLOAD_URL_PATTERN);
|
||||||
|
final String mainDC = page.getInputValue("mainDC");
|
||||||
|
uploadID = page.find(UPLOAD_ID_PATTERN, 1);
|
||||||
|
|
||||||
|
logger.debug("Upload URI: {}, DC: {}", uri, mainDC);
|
||||||
|
|
||||||
|
// create a new channel
|
||||||
|
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||||
|
uploadFuture = multipartPost(uri).parameter("fff", channel)
|
||||||
|
.parameter("mainDC", mainDC).asPageAsync();
|
||||||
|
|
||||||
|
// wait for channel link
|
||||||
|
return waitChannelLink(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String finish() throws IOException {
|
||||||
|
try {
|
||||||
|
uploadFuture.get();
|
||||||
|
final HTMLPage page = get(
|
||||||
|
"http://www.2shared.com/uploadComplete.jsp?sId="
|
||||||
|
+ uploadID).asPage();
|
||||||
|
return page.getTextareaValueById("downloadLink");
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return null;
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
ExceptionUtils.asIOException(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DownloaderImpl extends
|
||||||
|
AbstractHttpDownloader<NullDownloaderConfiguration> implements
|
||||||
|
Downloader<NullDownloaderConfiguration> {
|
||||||
|
/**
|
||||||
|
* @param uri
|
||||||
|
* the download uri
|
||||||
|
* @param configuration
|
||||||
|
* the downloader configuration
|
||||||
|
*/
|
||||||
|
protected DownloaderImpl(URI uri,
|
||||||
|
NullDownloaderConfiguration configuration) {
|
||||||
|
super(TwoSharedService.this, uri, configuration);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DownloadChannel openChannel(DownloadListener listener,
|
||||||
|
long position) throws IOException,
|
||||||
|
DownloadLinkNotFoundException, DownloadLimitExceededException,
|
||||||
|
DownloadNotAuthorizedException, DownloadNotResumableException,
|
||||||
|
UnsolvableCaptchaServiceException, NoCaptchaServiceException {
|
||||||
|
final HTMLPage page = get(uri).asPage();
|
||||||
|
final String downloadUri = page.findScript(
|
||||||
|
DIRECT_DOWNLOAD_URL_PATTERN, 0);
|
||||||
|
return download(get(downloadUri));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
com.rogiel.httpchannel.service.twoshared.TwoSharedService
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package com.rogiel.httpchannel.service.twoshared;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.rogiel.httpchannel.service.Downloader;
|
||||||
|
import com.rogiel.httpchannel.util.ChannelUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="http://www.rogiel.com">Rogiel</a>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TwoSharedServiceTest {
|
||||||
|
private final TwoSharedService service = new TwoSharedService();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpload() throws IOException {
|
||||||
|
final Path path = Paths
|
||||||
|
.get("../src/test/resources/upload-test-file.txt");
|
||||||
|
final URI uri = ChannelUtils.upload(service, path);
|
||||||
|
|
||||||
|
Assert.assertNotNull(uri);
|
||||||
|
System.out.println(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDownload() throws IOException {
|
||||||
|
final Downloader<?> downloader = service
|
||||||
|
.getDownloader(URI
|
||||||
|
.create("http://www.2shared.com/document/04tjgnAr/upload-test-file.html"));
|
||||||
|
System.out.println(new String(ChannelUtils.toByteArray(downloader.openChannel())));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -201,7 +201,7 @@ public class FourSharedService extends AbstractHttpService implements Service,
|
|||||||
.parameter("FilePart", channel).asPageAsync();
|
.parameter("FilePart", channel).asPageAsync();
|
||||||
|
|
||||||
// wait for channel link
|
// wait for channel link
|
||||||
return waitChannelLink(channel, uploadFuture);
|
return waitChannelLink(channel);
|
||||||
} catch (ApiException e) {
|
} catch (ApiException e) {
|
||||||
throw new ChannelServiceException(e);
|
throw new ChannelServiceException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.httpchannel.service.fourshared;
|
||||||
|
|
||||||
|
import com.rogiel.httpchannel.service.AbstractUploaderConfiguration;
|
||||||
|
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 FourSharedUploaderConfiguration extends
|
||||||
|
AbstractUploaderConfiguration implements UploaderConfiguration,
|
||||||
|
DescriptionableUploaderConfiguration {
|
||||||
|
/**
|
||||||
|
* The upload description
|
||||||
|
*/
|
||||||
|
private String description = DescriptionableUploaderConfiguration.DEFAULT_DESCRIPTION;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String description() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FourSharedUploaderConfiguration description(String description) {
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -135,7 +135,7 @@ public class ${serviceName}Service extends AbstractHttpService implements
|
|||||||
uploadFuture = multipartPost(uri).parameter("[file-parameter]", channel).asPageAsync();
|
uploadFuture = multipartPost(uri).parameter("[file-parameter]", channel).asPageAsync();
|
||||||
|
|
||||||
// wait for channel link
|
// wait for channel link
|
||||||
return waitChannelLink(channel, uploadFuture);
|
return waitChannelLink(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ public class DepositFilesService extends AbstractHttpService implements
|
|||||||
.parameter("UPLOAD_IDENTIFIER", uploadID)
|
.parameter("UPLOAD_IDENTIFIER", uploadID)
|
||||||
.parameter("agree", true)
|
.parameter("agree", true)
|
||||||
.parameter("MAX_FILE_SIZE", maxFileSize).asPageAsync();
|
.parameter("MAX_FILE_SIZE", maxFileSize).asPageAsync();
|
||||||
return waitChannelLink(channel, uploadFuture);
|
return waitChannelLink(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ public class FileSonicService extends AbstractHttpService implements Service,
|
|||||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||||
uploadFuture = multipartPost(api.getUploadURI().toString())
|
uploadFuture = multipartPost(api.getUploadURI().toString())
|
||||||
.parameter("files[]", channel).asStringAsync();
|
.parameter("files[]", channel).asStringAsync();
|
||||||
return waitChannelLink(channel, uploadFuture);
|
return waitChannelLink(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ public class HotFileService extends AbstractHttpService implements Service,
|
|||||||
|
|
||||||
uploadFuture = multipartPost(action)
|
uploadFuture = multipartPost(action)
|
||||||
.parameter("uploads[]", channel).asPageAsync();
|
.parameter("uploads[]", channel).asPageAsync();
|
||||||
return waitChannelLink(channel, uploadFuture);
|
return waitChannelLink(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ public class MegaUploadService extends AbstractHttpService implements Service,
|
|||||||
uploadFuture = multipartPost(uri)
|
uploadFuture = multipartPost(uri)
|
||||||
.parameter("multimessage_0", configuration.description())
|
.parameter("multimessage_0", configuration.description())
|
||||||
.parameter("multifile_0", channel).asStringAsync();
|
.parameter("multifile_0", channel).asStringAsync();
|
||||||
return waitChannelLink(channel, uploadFuture);
|
return waitChannelLink(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ public class MultiUploadService extends AbstractHttpService implements Service,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uploadFuture = request.asStringAsync();
|
uploadFuture = request.asStringAsync();
|
||||||
return waitChannelLink(channel, uploadFuture);
|
return waitChannelLink(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ public class UploadHereService extends AbstractHttpService implements Service,
|
|||||||
uploadFuture = multipartPost(uri).parameter("file_0", channel)
|
uploadFuture = multipartPost(uri).parameter("file_0", channel)
|
||||||
.parameter("u", userCookie)
|
.parameter("u", userCookie)
|
||||||
.parameter("UPLOAD_IDENTIFIER", uploadID).asStringAsync();
|
.parameter("UPLOAD_IDENTIFIER", uploadID).asStringAsync();
|
||||||
return waitChannelLink(channel, uploadFuture);
|
return waitChannelLink(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ public class UploadKingService extends AbstractHttpService implements Service,
|
|||||||
uploadFuture = multipartPost(uri).parameter("file", channel)
|
uploadFuture = multipartPost(uri).parameter("file", channel)
|
||||||
.parameter("u", userCookie)
|
.parameter("u", userCookie)
|
||||||
.parameter("UPLOAD_IDENTIFIER", uploadID).asStringAsync();
|
.parameter("UPLOAD_IDENTIFIER", uploadID).asStringAsync();
|
||||||
return waitChannelLink(channel, uploadFuture);
|
return waitChannelLink(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ public class WUploadService extends AbstractHttpService implements Service,
|
|||||||
final LinkedUploadChannel channel = createLinkedChannel(this);
|
final LinkedUploadChannel channel = createLinkedChannel(this);
|
||||||
uploadFuture = multipartPost(api.getUploadURI().toString())
|
uploadFuture = multipartPost(api.getUploadURI().toString())
|
||||||
.parameter("files[]", channel).asStringAsync();
|
.parameter("files[]", channel).asStringAsync();
|
||||||
return waitChannelLink(channel, uploadFuture);
|
return waitChannelLink(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ public class ZShareService extends AbstractHttpService implements Service/*
|
|||||||
// .parameter("descr", configuration.description())
|
// .parameter("descr", configuration.description())
|
||||||
// .parameter("TOS", true).parameter("is_private", false)
|
// .parameter("TOS", true).parameter("is_private", false)
|
||||||
// .asStringAsync();
|
// .asStringAsync();
|
||||||
// return waitChannelLink(channel, uploadFuture);
|
// return waitChannelLink(channel);
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// @Override
|
// @Override
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
<module>httpchannel-service-wupload</module>
|
<module>httpchannel-service-wupload</module>
|
||||||
<module>httpchannel-service-zshare</module>
|
<module>httpchannel-service-zshare</module>
|
||||||
<module>httpchannel-service-4shared</module>
|
<module>httpchannel-service-4shared</module>
|
||||||
|
<module>httpchannel-service-2shared</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|||||||
@@ -19,14 +19,14 @@
|
|||||||
package com.rogiel.httpchannel.service;
|
package com.rogiel.httpchannel.service;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import com.rogiel.httpchannel.http.GetRequest;
|
import com.rogiel.httpchannel.http.GetRequest;
|
||||||
import com.rogiel.httpchannel.http.HttpContext;
|
import com.rogiel.httpchannel.http.HttpContext;
|
||||||
import com.rogiel.httpchannel.http.PostMultipartRequest;
|
import com.rogiel.httpchannel.http.PostMultipartRequest;
|
||||||
import com.rogiel.httpchannel.http.PostRequest;
|
import com.rogiel.httpchannel.http.PostRequest;
|
||||||
import com.rogiel.httpchannel.service.channel.LinkedUploadChannel;
|
import com.rogiel.httpchannel.service.channel.LinkedUploadChannel;
|
||||||
import com.rogiel.httpchannel.util.ThreadUtils;
|
import com.rogiel.httpchannel.service.exception.UploadServiceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base service for HTTP enabled services.
|
* Abstract base service for HTTP enabled services.
|
||||||
@@ -38,13 +38,9 @@ public abstract class AbstractHttpService extends AbstractService implements
|
|||||||
Service {
|
Service {
|
||||||
protected final HttpContext http = new HttpContext();
|
protected final HttpContext http = new HttpContext();
|
||||||
|
|
||||||
protected LinkedUploadChannel waitChannelLink(LinkedUploadChannel channel,
|
protected LinkedUploadChannel waitChannelLink(LinkedUploadChannel channel)
|
||||||
Future<?> future) {
|
throws UploadServiceException {
|
||||||
logger.debug("Waiting channel {} to link", channel);
|
return channel.waitLink(20, TimeUnit.SECONDS);
|
||||||
while (!channel.isLinked() && !future.isDone()) {
|
|
||||||
ThreadUtils.sleep(100);
|
|
||||||
}
|
|
||||||
return channel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GetRequest get(String uri) {
|
public GetRequest get(String uri) {
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.channels.Channel;
|
import java.nio.channels.Channel;
|
||||||
import java.nio.channels.ClosedChannelException;
|
import java.nio.channels.ClosedChannelException;
|
||||||
import java.nio.channels.WritableByteChannel;
|
import java.nio.channels.WritableByteChannel;
|
||||||
|
import java.util.concurrent.Phaser;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -32,6 +35,7 @@ import com.rogiel.httpchannel.service.UploadChannel;
|
|||||||
import com.rogiel.httpchannel.service.UploadService;
|
import com.rogiel.httpchannel.service.UploadService;
|
||||||
import com.rogiel.httpchannel.service.Uploader;
|
import com.rogiel.httpchannel.service.Uploader;
|
||||||
import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException;
|
import com.rogiel.httpchannel.service.exception.UploadLinkNotFoundException;
|
||||||
|
import com.rogiel.httpchannel.service.exception.UploadServiceException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This channel is linked onto another {@link Channel} that actually writes data
|
* This channel is linked onto another {@link Channel} that actually writes data
|
||||||
@@ -45,6 +49,11 @@ public class LinkedUploadChannel implements UploadChannel {
|
|||||||
*/
|
*/
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The synchronization phaser
|
||||||
|
*/
|
||||||
|
private final Phaser phaser = new Phaser();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The upload service
|
* The upload service
|
||||||
*/
|
*/
|
||||||
@@ -90,6 +99,9 @@ public class LinkedUploadChannel implements UploadChannel {
|
|||||||
this.closeCallback = closeCallback;
|
this.closeCallback = closeCallback;
|
||||||
this.filename = filename;
|
this.filename = filename;
|
||||||
this.length = filesize;
|
this.length = filesize;
|
||||||
|
|
||||||
|
// register on the phaser
|
||||||
|
phaser.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -167,6 +179,7 @@ public class LinkedUploadChannel implements UploadChannel {
|
|||||||
if (!channel.isOpen())
|
if (!channel.isOpen())
|
||||||
throw new IOException("The destination channel is closed");
|
throw new IOException("The destination channel is closed");
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
|
phaser.arrive();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,4 +189,28 @@ public class LinkedUploadChannel implements UploadChannel {
|
|||||||
public boolean isLinked() {
|
public boolean isLinked() {
|
||||||
return channel != null;
|
return channel != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waits for the channels to get linked
|
||||||
|
*
|
||||||
|
* @param timeout
|
||||||
|
* the amount of time to wait
|
||||||
|
* @param unit
|
||||||
|
* the time unit for the wait
|
||||||
|
*
|
||||||
|
* @throws UploadServiceException
|
||||||
|
* if the channel has not been linked after the timeout has
|
||||||
|
* expired
|
||||||
|
*/
|
||||||
|
public LinkedUploadChannel waitLink(int timeout, TimeUnit unit)
|
||||||
|
throws UploadServiceException {
|
||||||
|
logger.debug("Waiting channel {} to link", this);
|
||||||
|
try {
|
||||||
|
phaser.awaitAdvanceInterruptibly(phaser.getPhase(), timeout, unit);
|
||||||
|
} catch (InterruptedException | TimeoutException e) {
|
||||||
|
throw new UploadServiceException("Channel has not linked in "
|
||||||
|
+ timeout + " " + unit);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import org.htmlparser.tags.ImageTag;
|
|||||||
import org.htmlparser.tags.InputTag;
|
import org.htmlparser.tags.InputTag;
|
||||||
import org.htmlparser.tags.LinkTag;
|
import org.htmlparser.tags.LinkTag;
|
||||||
import org.htmlparser.tags.ScriptTag;
|
import org.htmlparser.tags.ScriptTag;
|
||||||
|
import org.htmlparser.tags.TextareaTag;
|
||||||
import org.htmlparser.util.NodeIterator;
|
import org.htmlparser.util.NodeIterator;
|
||||||
import org.htmlparser.util.NodeList;
|
import org.htmlparser.util.NodeList;
|
||||||
import org.htmlparser.util.ParserException;
|
import org.htmlparser.util.ParserException;
|
||||||
@@ -184,17 +185,21 @@ public class HTMLPage {
|
|||||||
public String getInputValueById(final String id) {
|
public String getInputValueById(final String id) {
|
||||||
return inputValue(filter(InputTag.class, new InputIDFilter(id)));
|
return inputValue(filter(InputTag.class, new InputIDFilter(id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInputValueByIdInt(final String id) {
|
|
||||||
return Integer.parseInt(inputValue(filter(InputTag.class, new InputIDFilter(id))));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public int getInputValueByIdInt(final String id) {
|
||||||
|
return Integer.parseInt(inputValue(filter(InputTag.class,
|
||||||
|
new InputIDFilter(id))));
|
||||||
|
}
|
||||||
|
|
||||||
public String getInputValue(final Pattern pattern) {
|
public String getInputValue(final Pattern pattern) {
|
||||||
return inputValue(filter(InputTag.class, new InputValuePatternFilter(
|
return inputValue(filter(InputTag.class, new InputValuePatternFilter(
|
||||||
pattern)));
|
pattern)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getTextareaValueById(String id) {
|
||||||
|
return ((TextareaTag) getTagByID(id)).getStringText();
|
||||||
|
}
|
||||||
|
|
||||||
public Tag getTagByID(final String id) {
|
public Tag getTagByID(final String id) {
|
||||||
for (final Tag tag : filter(Tag.class, new IDFilter(id))) {
|
for (final Tag tag : filter(Tag.class, new IDFilter(id))) {
|
||||||
return tag;
|
return tag;
|
||||||
|
|||||||
Reference in New Issue
Block a user