*Plugins: Fixes/Changes/Maintenance*

- HighWayCore: overrides enoughTrafficFor
- AllDebridCom: refactored error handling
- XHamsterCom: fixed faphousecom trailer download RE ticket #GJSP7622-OGBH-2922YNUH
- PornComixInfoPornComixOne: moved porncomixonenet into PornComixInfoIComixzillaCom
PornComixInfoPornComixOne: RE forum 90641
- renamed to PornComixInfoPornIlikecomixCom
- added domain ilikecomixcom
- updated pattern and fixed crawler
PornComixInfoIComixzillaCom: RE forum 90641
- added ilikecomix.io to list of dead domains
- added domain porncomixonline (new domain of comixzillacom)
- updated pattern and fixed crawler

*Plugins: RIP*
- ishare.iask.sina.com.cn RE forum 95847

git-svn-id: svn://svn.jdownloader.org/jdownloader/trunk@49704 ebf7c1c2-ba36-0410-9fe8-c592906822b4

Former-commit-id: 32f56992aaf3e6e977042fdd8bd27f975d0e9053
This commit is contained in:
psp 2024-09-04 10:55:10 +00:00
parent eb4564ce29
commit def81134a7
11 changed files with 395 additions and 566 deletions

View File

@ -16,6 +16,7 @@ import jd.plugins.FilePackage;
import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
import jd.plugins.PluginForDecrypt;
import jd.plugins.hoster.DirectHTTP;
@DecrypterPlugin(revision = "$Revision$", interfaceVersion = 3, names = {}, urls = {})
public class PornComixInfoIComixzillaCom extends PluginForDecrypt {
@ -27,10 +28,16 @@ public class PornComixInfoIComixzillaCom extends PluginForDecrypt {
public static List<String[]> getPluginDomains() {
final List<String[]> ret = new ArrayList<String[]>();
// each entry in List<String[]> will result in one PluginForDecrypt, Plugin.getHost() will return String[0]->main domain
ret.add(new String[] { "comixzilla.com", "ilikecomix.io" });
ret.add(new String[] { "porncomix.online", "comixzilla.com", "ilikecomix.io" });
return ret;
}
private List<String> getDeadDomains() {
final ArrayList<String> deadDomains = new ArrayList<String>();
deadDomains.add("ilikecomix.io"); // 2024-09-04
return deadDomains;
}
public static String[] getAnnotationNames() {
return buildAnnotationNames(getPluginDomains());
}
@ -47,50 +54,46 @@ public class PornComixInfoIComixzillaCom extends PluginForDecrypt {
public static String[] buildAnnotationUrls(final List<String[]> pluginDomains) {
final List<String> ret = new ArrayList<String>();
for (final String[] domains : pluginDomains) {
ret.add("https?://(?:www\\.)?" + buildHostsPatternPart(domains) + "/(?:[a-z]{2}/)?comic-g/([a-z0-9\\-]+)/?");
ret.add("https?://(?:www\\.)?" + buildHostsPatternPart(domains) + "/comic/([\\w-]+)/([\\w-]+)/?");
}
return ret.toArray(new String[0]);
}
@Override
public ArrayList<DownloadLink> decryptIt(final CryptedLink param, ProgressController progress) throws Exception {
final ArrayList<DownloadLink> decryptedLinks = new ArrayList<DownloadLink>();
final ArrayList<DownloadLink> ret = new ArrayList<DownloadLink>();
br.setFollowRedirects(true);
final String addedurl = param.getCryptedUrl();
br.getPage(addedurl);
String contenturl = param.getCryptedUrl();
for (final String deadDomain : getDeadDomains()) {
contenturl = contenturl.replace(deadDomain, this.getHost());
}
br.getPage(contenturl);
if (br.getHttpConnection().getResponseCode() == 404) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
final String urltitle = new Regex(br.getURL(), "/([^/]+)/?$").getMatch(0);
/* Allow to pickup quotes */
String postTitle = br.getRegex("itemprop=\"headline\">([^<>\"]+)</h1>").getMatch(0);
if (postTitle == null) {
postTitle = br.getRegex("<title>([^<>\"]+) \\| Porn comics</title>").getMatch(0);
}
String postTitle = br.getRegex("<title>Reading ([^<]+) PornComix Online - Porn Comics</title>").getMatch(0);
if (StringUtils.isEmpty(postTitle)) {
/* Fallback */
postTitle = urltitle.replace("-", " ");
postTitle = urltitle.replace("-", " ").trim();
}
String[] images = br.getRegex("class='dgwt-jg-item' data-size='\\d+x\\d+'><a href='(https?://[^/]+/img/[^<>\"\\']+)").getColumn(0);
if (images.length == 0) {
/* Fallback */
images = br.getRegex("<a href=.(https?://[^/]+/img/[^<>\"\\']+)").getColumn(0);
String[] images = br.getRegex("img id=\"image-\\d+\" src=\"([^\"]+)").getColumn(0);
if (images == null || images.length == 0) {
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
if (images.length > 0) {
for (final String imageurl : images) {
/* 2020-11-13: Not needed anymore */
// imageurl = Encoding.htmlDecode(imageurl).replaceFirst("(-\\d+x\\d+)\\.(jpe?g|gif|png)$", ".$2");
final DownloadLink link = createDownloadlink(imageurl);
link.setAvailable(true);
link.setContainerUrl(param.getCryptedUrl());
decryptedLinks.add(link);
}
for (String imageurl : images) {
imageurl = imageurl.trim();
final DownloadLink link = createDownloadlink(DirectHTTP.createURLForThisPlugin(imageurl));
link.setAvailable(true);
link.setContainerUrl(param.getCryptedUrl());
ret.add(link);
}
if (postTitle != null) {
final FilePackage fp = FilePackage.getInstance();
fp.setName(Encoding.htmlDecode(postTitle));
fp.addLinks(decryptedLinks);
fp.addLinks(ret);
}
return decryptedLinks;
return ret;
}
}

View File

@ -1,58 +0,0 @@
package jd.plugins.decrypter;
import java.util.ArrayList;
import org.appwork.utils.StringUtils;
import org.jdownloader.plugins.controller.LazyPlugin;
import jd.controlling.ProgressController;
import jd.nutils.encoding.Encoding;
import jd.parser.Regex;
import jd.plugins.CryptedLink;
import jd.plugins.DecrypterPlugin;
import jd.plugins.DownloadLink;
import jd.plugins.FilePackage;
import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
import jd.plugins.PluginForDecrypt;
@DecrypterPlugin(revision = "$Revision$", interfaceVersion = 3, names = { "porncomixone.net" }, urls = { "https?://(?:www\\.)?porncomixone\\.net/comic/([a-z0-9\\-]+)" })
/** Formerly known as: porncomix.one */
public class PornComixInfoPornComixOne extends PluginForDecrypt {
@Override
public LazyPlugin.FEATURE[] getFeatures() {
return new LazyPlugin.FEATURE[] { LazyPlugin.FEATURE.XXX };
}
@Override
public ArrayList<DownloadLink> decryptIt(final CryptedLink param, ProgressController progress) throws Exception {
final ArrayList<DownloadLink> decryptedLinks = new ArrayList<DownloadLink>();
br.setFollowRedirects(true);
br.getPage(param.getCryptedUrl());
if (br.getHttpConnection().getResponseCode() == 404) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
final String urltitle = new Regex(param.getCryptedUrl(), this.getSupportedLinks()).getMatch(0);
String postTitle = br.getRegex("(?i)<title>([^<>\"]+) \\&bull; Porn Comics One</title>").getMatch(0);
if (StringUtils.isEmpty(postTitle)) {
/* Fallback */
postTitle = urltitle.replace("-", " ").trim();
} else {
postTitle = Encoding.htmlDecode(postTitle);
}
String[] images = br.getRegex("(/gallery/[^<>\"\\']+)").getColumn(0);
if (images != null) {
for (String imageurl : images) {
imageurl = br.getURL(imageurl).toString();
final DownloadLink link = createDownloadlink(imageurl);
link.setAvailable(true);
link.setContainerUrl(param.getCryptedUrl());
decryptedLinks.add(link);
}
}
final FilePackage fp = FilePackage.getInstance();
fp.setName(postTitle);
fp.addLinks(decryptedLinks);
return decryptedLinks;
}
}

View File

@ -0,0 +1,89 @@
package jd.plugins.decrypter;
import java.util.ArrayList;
import java.util.List;
import org.appwork.utils.StringUtils;
import org.jdownloader.plugins.controller.LazyPlugin;
import jd.controlling.ProgressController;
import jd.nutils.encoding.Encoding;
import jd.parser.Regex;
import jd.plugins.CryptedLink;
import jd.plugins.DecrypterPlugin;
import jd.plugins.DownloadLink;
import jd.plugins.FilePackage;
import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
import jd.plugins.PluginForDecrypt;
import jd.plugins.hoster.DirectHTTP;
@DecrypterPlugin(revision = "$Revision$", interfaceVersion = 3, names = {}, urls = {})
/** Formerly known as: porncomix.one */
public class PornComixInfoPornIlikecomixCom extends PluginForDecrypt {
@Override
public LazyPlugin.FEATURE[] getFeatures() {
return new LazyPlugin.FEATURE[] { LazyPlugin.FEATURE.XXX };
}
public static List<String[]> getPluginDomains() {
final List<String[]> ret = new ArrayList<String[]>();
// each entry in List<String[]> will result in one PluginForDecrypt, Plugin.getHost() will return String[0]->main domain
ret.add(new String[] { "ilikecomix.com", "porncomixone.net" });
return ret;
}
public static String[] getAnnotationNames() {
return buildAnnotationNames(getPluginDomains());
}
@Override
public String[] siteSupportedNames() {
return buildSupportedNames(getPluginDomains());
}
public static String[] getAnnotationUrls() {
return buildAnnotationUrls(getPluginDomains());
}
public static String[] buildAnnotationUrls(final List<String[]> pluginDomains) {
final List<String> ret = new ArrayList<String>();
for (final String[] domains : pluginDomains) {
ret.add("https?://(?:www\\.)?" + buildHostsPatternPart(domains) + "/allporn/comics/([\\w-]+)/([\\w-]+)/?");
}
return ret.toArray(new String[0]);
}
@Override
public ArrayList<DownloadLink> decryptIt(final CryptedLink param, ProgressController progress) throws Exception {
final ArrayList<DownloadLink> ret = new ArrayList<DownloadLink>();
br.setFollowRedirects(true);
br.getPage(param.getCryptedUrl());
if (br.getHttpConnection().getResponseCode() == 404) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
final String urltitle = new Regex(param.getCryptedUrl(), this.getSupportedLinks()).getMatch(1);
String postTitle = br.getRegex("\"headline\": \"([^\"]+)").getMatch(0);
if (StringUtils.isEmpty(postTitle)) {
/* Fallback */
postTitle = urltitle.replace("-", " ").trim();
} else {
postTitle = Encoding.htmlDecode(postTitle).trim();
}
String[] images = br.getRegex("img id=\"image-\\d+\" src=\"([^\"]+)").getColumn(0);
if (images == null || images.length == 0) {
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
for (String imageurl : images) {
imageurl = br.getURL(imageurl).toString();
final DownloadLink link = createDownloadlink(DirectHTTP.createURLForThisPlugin(imageurl));
link.setAvailable(true);
link.setContainerUrl(param.getCryptedUrl());
ret.add(link);
}
final FilePackage fp = FilePackage.getInstance();
fp.setName(postTitle);
fp.addLinks(ret);
return ret;
}
}

View File

@ -27,12 +27,14 @@ import java.util.Map.Entry;
import java.util.WeakHashMap;
import org.appwork.net.protocol.http.HTTPConstants;
import org.appwork.storage.JSonMapperException;
import org.appwork.storage.TypeRef;
import org.appwork.storage.config.annotations.AboutConfig;
import org.appwork.storage.config.annotations.DefaultBooleanValue;
import org.appwork.uio.ConfirmDialogInterface;
import org.appwork.uio.UIOManager;
import org.appwork.utils.Application;
import org.appwork.utils.Exceptions;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
@ -80,7 +82,7 @@ public class AllDebridCom extends PluginForHost {
super(wrapper);
/* 2020-03-27: As long as we're below 4 API requests per second we're fine according to admin. */
setStartIntervall(1000);
this.enablePremium("https://alldebrid.com/offer/");
this.enablePremium("https://" + getHost() + "/offer/");
}
@Override
@ -128,15 +130,16 @@ public class AllDebridCom extends PluginForHost {
}
}
private static MultiHosterManagement mhm = new MultiHosterManagement("alldebrid.com");
public static final String api_base = "https://api.alldebrid.com/v4";
private static MultiHosterManagement mhm = new MultiHosterManagement("alldebrid.com");
private static WeakHashMap<Account, HashSet<String>> RATE_LIMITED = new WeakHashMap<Account, HashSet<String>>();
public static final String api_base = "https://api.alldebrid.com/v4";
// this is used by provider which calculates unique token to agent/client.
public static final String agent_raw = "JDownloader";
private static final String agent = "agent=" + agent_raw;
private final String PROPERTY_APIKEY_CREATED_TIMESTAMP = "APIKEY_CREATED_TIMESTAMP";
private static final String PROPERTY_apikey = "apiv4_apikey";
private final String PROPERTY_maxchunks = "alldebrid_maxchunks";
private final AccountInvalidException exceptionFreeAccountsAreNotSupported = new AccountInvalidException("Free accounts are not supported!");
public static final String agent_raw = "JDownloader";
private static final String agent = "agent=" + agent_raw;
private final String PROPERTY_APIKEY_CREATED_TIMESTAMP = "APIKEY_CREATED_TIMESTAMP";
private static final String PROPERTY_apikey = "apiv4_apikey";
private final String PROPERTY_maxchunks = "alldebrid_maxchunks";
private static final String ERROR_CODE_LINK_PASSWORD_PROTECTED = "LINK_PASS_PROTECTED";
public String login(final Account account, final AccountInfo accountInfo, final boolean validateApikey) throws Exception {
synchronized (account) {
@ -154,16 +157,17 @@ public class AllDebridCom extends PluginForHost {
/* Full login */
logger.info("Performing full login");
br.getPage(api_base + "/pin/get?" + agent);
final Map<String, Object> entries = this.handleErrors(account, null);
final Map<String, Object> data = (Map<String, Object>) entries.get("data");
final Map<String, Object> data = this.handleErrors(account, null);
final String user_url = data.get("user_url").toString();
final String check_url = data.get("check_url").toString();
final int maxSecondsServerside = ((Number) data.get("expires_in")).intValue();
final Thread dialog = showPINLoginInformation(user_url, maxSecondsServerside);
final int maxWaitSecondsClientside = 1200;
final int waitSecondsForDialog = Math.min(maxSecondsServerside, maxWaitSecondsClientside);
final Thread dialog = showPINLoginInformation(user_url, waitSecondsForDialog);
int secondsWaited = 0;
final int waitSecondsPerLoop = 3;
try {
for (int i = 0; i <= 23; i++) {
while (true) {
logger.info("Waiting for user to authorize application. Seconds waited: " + secondsWaited + "/" + maxSecondsServerside);
Thread.sleep(waitSecondsPerLoop * 1000);
secondsWaited += waitSecondsPerLoop;
@ -174,18 +178,26 @@ public class AllDebridCom extends PluginForHost {
}
/** Example response: { "status": "success", "data": { "activated": false, "expires_in": 590 }}} */
final Map<String, Object> resp = this.handleErrors(account, null);
final Map<String, Object> respData = (Map<String, Object>) resp.get("data");
apikey = (String) respData.get("apikey");
apikey = (String) resp.get("apikey");
final int secondsLeftServerside = ((Number) data.get("expires_in")).intValue();
if (!StringUtils.isEmpty(apikey)) {
logger.info("Stopping because: Found apikey!");
break;
} else if (secondsLeftServerside < waitSecondsPerLoop) {
} else if (secondsWaited >= maxSecondsServerside) {
logger.info("Stopping because: Timeout #1 | User did not perform authorization within " + maxSecondsServerside + " seconds");
break;
} else if (secondsLeftServerside <= waitSecondsPerLoop) {
logger.info("Stopping because: Timeout #2");
break;
} else if (secondsWaited >= maxWaitSecondsClientside) {
logger.info("Stopping because: Timeout #3");
break;
} else if (!dialog.isAlive()) {
logger.info("Stopping because: Dialog closed!");
break;
} else if (this.isAbort()) {
logger.info("Stopping because: Aborted by user");
break;
}
}
} finally {
@ -207,9 +219,9 @@ public class AllDebridCom extends PluginForHost {
synchronized (account) {
setAuthHeader(br, apikey);
br.getPage(api_base + "/user?" + agent);
final Map<String, Object> root = handleErrors(account, null);
final Map<String, Object> data = (Map<String, Object>) root.get("data");
final Map<String, Object> data = handleErrors(account, null);
final Map<String, Object> user = (Map<String, Object>) data.get("user");
// final List<String> notifications = (List<String>) user.get("notifications");
final String userName = (String) user.get("username");
if (!StringUtils.isEmpty(userName)) {
account.setUser(userName);
@ -219,39 +231,39 @@ public class AllDebridCom extends PluginForHost {
* property in our Account object!
*/
account.setPass(null);
if ((Boolean) user.get("isPremium") == Boolean.TRUE) {
final Number premiumUntil = (Number) user.get("premiumUntil");
if (premiumUntil != null) {
ai.setValidUntil(premiumUntil.longValue() * 1000l, br);
}
if ((Boolean) user.get("isTrial") == Boolean.TRUE) {
/*
* 2020-03-27: Premium "test" accounts which last 7 days and have a total of 25GB as quota. Once that limit is reached,
* they can only download from "Free" hosts (only a hand full of hosts).
*/
ai.setStatus("Premium Account (Free trial, reverts to free once traffic is used up)");
final Number remainingTrialQuota = (Number) user.get("remainingTrialQuota");
if (remainingTrialQuota != null) {
/* 2020-03-27: Hardcoded maxTraffic value */
final long maxTraffic = SizeFormatter.getSize("25GB");
final long remainingTrialTraffic = remainingTrialQuota.longValue() * 1000 * 1000;
ai.setTrafficLeft(remainingTrialTraffic);
if (remainingTrialTraffic <= maxTraffic) {
ai.setTrafficMax(maxTraffic);
}
}
} else {
/* "Real" premium account. */
ai.setStatus("Premium Account");
}
account.setType(AccountType.PREMIUM);
} else {
if ((Boolean) user.get("isPremium") == Boolean.FALSE) {
/*
* "Real" free account (or expired trial premium [= user downloaded more than 25GB trial quota]) --> Cannot download and
* cannot even login via API officially!
*/
throw exceptionFreeAccountsAreNotSupported;
throw new AccountInvalidException("Free accounts are not supported!");
}
final Number premiumUntil = (Number) user.get("premiumUntil");
if (premiumUntil != null) {
ai.setValidUntil(premiumUntil.longValue() * 1000l, br);
}
if ((Boolean) user.get("isTrial") == Boolean.TRUE) {
/*
* 2020-03-27: Premium "test" accounts which last 7 days and have a total of 25GB as quota. Once that limit is reached, they
* can only download from "Free" hosts (only a hand full of hosts).
*/
ai.setStatus("Premium Account (Free trial, reverts to free once traffic is used up)");
final Number remainingTrialQuota = (Number) user.get("remainingTrialQuota");
if (remainingTrialQuota != null) {
/* 2020-03-27: Hardcoded maxTraffic value */
final long maxTraffic = SizeFormatter.getSize("25GB");
final long remainingTrialTraffic = remainingTrialQuota.longValue() * 1000 * 1000;
ai.setTrafficLeft(remainingTrialTraffic);
if (remainingTrialTraffic <= maxTraffic) {
ai.setTrafficMax(maxTraffic);
}
}
}
final Number fidelityPoints = (Number) user.get("fidelityPoints");
if (fidelityPoints != null) {
ai.setPremiumPoints(fidelityPoints.longValue());
}
account.setType(AccountType.PREMIUM);
}
}
@ -266,56 +278,51 @@ public class AllDebridCom extends PluginForHost {
final Iterator<Entry<String, Object>> iterator = supportedHostsInfo.entrySet().iterator();
final ArrayList<String> supportedHosts = new ArrayList<String>();
while (iterator.hasNext()) {
try {
final Entry<String, Object> hostO = iterator.next();
final Map<String, Object> entry = (Map<String, Object>) hostO.getValue();
String host_without_tld = (String) entry.get("name");
if (StringUtils.isEmpty(host_without_tld)) {
host_without_tld = hostO.getKey();
final Entry<String, Object> hostO = iterator.next();
final Map<String, Object> entry = (Map<String, Object>) hostO.getValue();
String host_without_tld = (String) entry.get("name");
if (StringUtils.isEmpty(host_without_tld)) {
host_without_tld = hostO.getKey();
}
/*
* 2020-04-01: This check will most likely never be required as free accounts officially cannot be used via API at all and JD
* also does not accept them but we're doing this check nevertheless.
*/
final String type = (String) entry.get("type");
final Boolean status = (Boolean) entry.get("status"); // optional field
// final Number quota = (Number) entry.get("quota");
if (account.getType() == AccountType.FREE && !"free".equalsIgnoreCase(type)) {
logger.info("Skipping host because it cannot be used with free accounts: " + host_without_tld);
continue;
}
/*
* Most hosts either have no limit or traffic limit ("traffic"). Some have a 'max downloads per day' limit instead -->
* "nb_download". We cannot handle this and thus ignore it. Also ignore trafficlimit because they could always deliver cached
* content for which the user will not be charged traffic at all!
*/
// final String quotaType = (String) entries.get("quotaType");
// final long quotaLeft = JavaScriptEngineFactory.toLong(entries.get("quota"), -1);
/* Skip currently disabled hosts --> 2020-03-26: Do not skip any hosts anymore, display all in JD RE: admin */
if (Boolean.FALSE.equals(status)) {
/* Log hosts which look to be non working according to API. */
logger.info("Host which might currently be broken: " + host_without_tld);
/* 2024-09-03: Do not ignore/skip such entries */
// continue;
}
/* Add all domains of host */
final List<String> domains = (List<String>) entry.get("domains");
if (domains == null && StringUtils.isEmpty(host_without_tld)) {
logger.info("WTF, unexpected format of field 'domains': " + host_without_tld);
continue;
}
if (domains != null) {
for (final String domain : domains) {
supportedHosts.add(domain);
}
/*
* 2020-04-01: This check will most likely never be required as free accounts officially cannot be used via API at all and
* JD also does not accept them but we're doing this check nevertheless.
*/
final String type = (String) entry.get("type");
final Boolean status = (Boolean) entry.get("status"); // optional field
if (account.getType() == AccountType.FREE && !"free".equalsIgnoreCase(type)) {
logger.info("Skipping host because it cannot be used with free accounts: " + host_without_tld);
continue;
}
/*
* Most hosts either have no limit or traffic limit ("traffic"). Some have a 'max downloads per day' limit instead -->
* "nb_download". We cannot handle this and thus ignore it. Also ignore trafficlimit because they could always deliver
* cached content for which the user will not be charged traffic at all!
*/
// final String quotaType = (String) entries.get("quotaType");
// final long quotaLeft = JavaScriptEngineFactory.toLong(entries.get("quota"), -1);
/* Skip currently disabled hosts --> 2020-03-26: Do not skip any hosts anymore, display all in JD RE: admin */
if (Boolean.FALSE.equals(status)) {
/* Log hosts which look to be non working according to API. */
logger.info("Host which might currently be broken: " + host_without_tld);
// continue;
}
/* Add all domains of host */
final Object domainsO = entry.get("domains");
if (domainsO == null && StringUtils.isEmpty(host_without_tld)) {
logger.info("WTF, unexpected format of field 'domains': " + host_without_tld);
continue;
}
if (domainsO != null) {
final List<String> domains = (List<String>) entry.get("domains");
for (final String domain : domains) {
supportedHosts.add(domain);
}
} else {
/* Fallback - this should usually not happen */
logger.info("Adding host_without_tld: " + host_without_tld);
supportedHosts.add(host_without_tld);
}
} catch (final Throwable e) {
/* Skip broken/unexpected json objects */
logger.log(e);
logger.warning("Skipped item due to unexpected json structure");
} else {
/* Fallback - this should usually not happen */
logger.info("Adding host_without_tld: " + host_without_tld);
supportedHosts.add(host_without_tld);
}
}
accountInfo.setMultiHostSupport(this, supportedHosts);
@ -406,8 +413,7 @@ public class AllDebridCom extends PluginForHost {
break;
}
/** Example response: { "status": "success", "data": { "activated": false, "expires_in": 590 }}} */
final Map<String, Object> resp = this.handleErrors(account, link);
final Map<String, Object> data = (Map<String, Object>) resp.get("data");
final Map<String, Object> data = this.handleErrors(account, link);
final String verifStatus = data.get("verif").toString();
if (verifStatus.equals("denied")) {
/* User opened link from email and denied this login-attempt. */
@ -493,78 +499,83 @@ public class AllDebridCom extends PluginForHost {
return thread;
}
/** See https://docs.alldebrid.com/v4/#all-errors */
/** See https://docs.alldebrid.com/#all-errors */
private Map<String, Object> handleErrors(final Account account, final DownloadLink link) throws PluginException, Exception {
/* 2020-03-25: E.g. {"status": "error", "error": {"code": "AUTH_BAD_APIKEY","message": "The auth apikey is invalid"}} */
Map<String, Object> entries = restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
Map<String, Object> entries = null;
try {
entries = restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
} catch (final JSonMapperException jme) {
if (link != null) {
mhm.handleErrorGeneric(account, link, "Bad API answer", 50, 5 * 60 * 1000l);
} else {
throw Exceptions.addSuppressed(new AccountUnavailableException("Bad API answer", 1 * 60 * 1000l), jme);
}
}
final String status = (String) entries.get("status");
if (!"error".equalsIgnoreCase(status)) {
return entries;
final Map<String, Object> data = (Map<String, Object>) entries.get("data");
return data;
}
final boolean isSelfhosted = this.isSelfhosted(link);
final Map<String, Object> errormap = (Map<String, Object>) entries.get("error");
final String code = (String) errormap.get("code");
final String errorcode = (String) errormap.get("code");
String message = (String) errormap.get("message");
if (StringUtils.isEmpty(message)) {
/* We always want to have a human readable errormessage */
message = "Unknown error";
}
if (code.equalsIgnoreCase("AUTH_BAD_APIKEY")) {
/* This is the only error which allows us to remove the apikey and re-login. */
account.removeProperty(PROPERTY_apikey);
throw new AccountInvalidException("Invalid login: " + message + "\r\nRefresh account to renew apikey.");
} else if (code.equalsIgnoreCase("AUTH_BLOCKED")) {
/* Apikey GEO-blocked or IP blocked */
this.authBlockedLogin(account, link, errormap);
} else if (code.equalsIgnoreCase("AUTH_USER_BANNED")) {
throw new AccountInvalidException(message);
} else if (code.equalsIgnoreCase("DELAYED_INVALID_ID")) {
/* This can only happen in '/link/delayed' handling */
mhm.handleErrorGeneric(account, link, message, 10);
} else if (code.equalsIgnoreCase("NO_SERVER")) {
/*
* 2020-03-26: Formerly known as "/alldebrid_server_not_allowed.txt" --> "Servers are not allowed to use this feature" --> Retry
* later
*/
mhm.handleErrorGeneric(account, link, message, 50);
} else if (code.equalsIgnoreCase("LINK_HOST_NOT_SUPPORTED")) {
final HashSet<String> accountErrorsPermanent = new HashSet<String>();
accountErrorsPermanent.add("AUTH_MISSING_APIKEY");
accountErrorsPermanent.add("AUTH_BAD_APIKEY");
accountErrorsPermanent.add("AUTH_USER_BANNED");
accountErrorsPermanent.add("PIN_EXPIRED");
accountErrorsPermanent.add("PIN_INVALID");
accountErrorsPermanent.add("ACCOUNT_INVALID");
final HashSet<String> accountErrorsTemporary = new HashSet<String>();
accountErrorsTemporary.add("MAINTENANCE");
accountErrorsTemporary.add("AUTH_BLOCKED");
accountErrorsTemporary.add("ALREADY_SENT");
accountErrorsTemporary.add("NO_SERVER");
accountErrorsTemporary.add("FREE_TRIAL_LIMIT_REACHED");
accountErrorsTemporary.add("PIN_ALREADY_AUTHED");
accountErrorsTemporary.add("PIN_EXPIRED");
accountErrorsTemporary.add("INSUFFICIENT_BALANCE");
final HashSet<String> downloadErrorsHostUnavailable = new HashSet<String>();
downloadErrorsHostUnavailable.add("LINK_HOST_NOT_SUPPORTED");
downloadErrorsHostUnavailable.add("LINK_HOST_UNAVAILABLE");
downloadErrorsHostUnavailable.add("LINK_HOST_FULL");
downloadErrorsHostUnavailable.add("LINK_HOST_LIMIT_REACHED");
downloadErrorsHostUnavailable.add("USER_LINK_INVALID");
final HashSet<String> downloadErrorsFileUnavailable = new HashSet<String>();
downloadErrorsFileUnavailable.add("LINK_IS_MISSING");
downloadErrorsFileUnavailable.add("BAD_LINK");
downloadErrorsFileUnavailable.add("LINK_TOO_MANY_DOWNLOADS");
downloadErrorsFileUnavailable.add("LINK_ERROR");
downloadErrorsFileUnavailable.add("LINK_TEMPORARY_UNAVAILABLE");
downloadErrorsFileUnavailable.add("MUST_BE_PREMIUM");
downloadErrorsFileUnavailable.add("DOWNLOAD_FAILED");
downloadErrorsFileUnavailable.add("DELAYED_INVALID_ID");
if (errorcode.equalsIgnoreCase("LINK_HOST_NOT_SUPPORTED")) {
if (isSelfhosted) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
} else {
mhm.putError(account, link, 5 * 60 * 1000l, message);
}
} else if (code.equalsIgnoreCase("LINK_TEMPORARY_UNAVAILABLE")) {
throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, message, 30 * 1000l);
} else if (code.equalsIgnoreCase("LINK_DOWN")) {
/* URL is offline according to multihoster --> Do not trust this error --> Skip to next download candidate instead! */
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
} else if (code.equalsIgnoreCase("LINK_PASS_PROTECTED")) {
throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, "URL is password protected", 5 * 60 * 1000l);
} else if (code.equalsIgnoreCase("LINK_HOST_UNAVAILABLE")) {
/* Host under maintenance or not available */
mhm.putError(account, link, 5 * 60 * 1000l, message);
} else if (code.equalsIgnoreCase("LINK_HOST_LIMIT_REACHED")) {
mhm.putError(account, link, 5 * 60 * 1000l, message);
} else if (code.equalsIgnoreCase("LINK_TOO_MANY_DOWNLOADS")) {
/* Some hosts' simultaneous downloads are limited by this multihost - this may sometimes happen. */
mhm.putError(account, link, 5 * 60 * 1000l, message);
} else if (code.equalsIgnoreCase("LINK_HOST_FULL")) {
/* API docs: 'All servers are full for this host please retry later' */
mhm.putError(account, link, 5 * 60 * 1000l, message);
} else if (code.equalsIgnoreCase("FREE_TRIAL_LIMIT_REACHED")) {
/*
* Traffic of free trial account is used-up --> Account is now basically a free account and free accounts are unsupported!
*/
throw exceptionFreeAccountsAreNotSupported;
} else if (code.equalsIgnoreCase("MUST_BE_PREMIUM")) {
/* Single URL is not downloadable with current (free?) alldebrid account */
throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, message, 5 * 60 * 1000l);
} else if (code.equalsIgnoreCase("PIN_ALREADY_AUTHED")) {
/* "You already have a valid auth apikey" --> Not sure about this --> Temp. disable account */
} else if (errorcode.equalsIgnoreCase(ERROR_CODE_LINK_PASSWORD_PROTECTED)) {
link.setDownloadPassword(null);
link.setPasswordProtected(true);
throw new PluginException(LinkStatus.ERROR_RETRY, "URL is password protected", 5 * 60 * 1000l);
} else if (accountErrorsPermanent.contains(errorcode)) {
/* This is the only error which allows us to remove the apikey and re-login. */
account.removeProperty(PROPERTY_apikey);
throw new AccountInvalidException(message);
} else if (downloadErrorsFileUnavailable.contains(errorcode)) {
throw new AccountUnavailableException(message, 5 * 60 * 1000);
} else if (code.equalsIgnoreCase("PIN_EXPIRED") || code.equalsIgnoreCase("PIN_INVALID")) {
/* Do not use given errormessage here as it is irritating. */
throw new AccountInvalidException("Invalid login!");
} else if (downloadErrorsHostUnavailable.contains(errorcode)) {
mhm.putError(accountErrorsTemporary, link, 5 * 60 * 1000l, message);
} else if (downloadErrorsFileUnavailable.contains(errorcode)) {
mhm.handleErrorGeneric(account, link, message, 20);
} else {
/*
* Unknown/Generic error --> Assume it is a download issue but display it as temp. account issue if no DownloadLink is given.
@ -578,6 +589,7 @@ public class AllDebridCom extends PluginForHost {
if (link != null) {
mhm.handleErrorGeneric(account, link, message, 50);
} else {
/* Temp disable account */
throw new AccountUnavailableException(message, 5 * 60 * 1000);
}
}
@ -629,7 +641,7 @@ public class AllDebridCom extends PluginForHost {
}
try {
dl.startDownload();
} catch (PluginException e) {
} catch (final PluginException e) {
if (StringUtils.containsIgnoreCase(e.getMessage(), "Server: Too Many Requests")) {
setRateLimit(link, account, url);
}
@ -778,11 +790,10 @@ public class AllDebridCom extends PluginForHost {
}
dlform.put("link", Encoding.urlEncode(url));
dlform.put("agent", agent_raw);
if (!StringUtils.isEmpty(downloadPassword)) {
if (downloadPassword != null) {
dlform.put("password", Encoding.urlEncode(downloadPassword));
}
int counter = 0;
final String pwprotectedErrorString = "LINK_PASS_PROTECTED";
do {
counter++;
if (counter > 1) {
@ -793,7 +804,7 @@ public class AllDebridCom extends PluginForHost {
try {
handleErrors(account, link);
} catch (final PluginException e) {
if (br.containsHTML(pwprotectedErrorString)) {
if (br.containsHTML(ERROR_CODE_LINK_PASSWORD_PROTECTED)) {
/*
* Stored password was wrong or this was the first attempt and we didn't know the item was password protected so now we
* know we need to ask the user to enter a download password.
@ -807,19 +818,18 @@ public class AllDebridCom extends PluginForHost {
logger.info("Breaking loop because: User entered correct password or none was needed");
break;
} while (counter <= 3);
final Map<String, Object> data = handleErrors(account, link);
if (!StringUtils.isEmpty(downloadPassword)) {
/* Entered password looks to be correct -> Store password */
link.setDownloadPassword(downloadPassword);
}
final Map<String, Object> entries = handleErrors(account, link);
final Map<String, Object> data = (Map<String, Object>) entries.get("data");
if (isSelfhosted) {
link.setFinalFileName(data.get("filename").toString());
link.setVerifiedFileSize(((Number) data.get("filesize")).longValue());
}
final Object delayID = data.get("delayed");
if (delayID != null) {
/* See https://docs.alldebrid.com/v4/#delayed-links */
/* See https://docs.alldebrid.com/#delayed-links */
if (!cacheDLChecker(link, account, delayID.toString())) {
/* Error or serverside download not finished in given time. */
logger.info("Delayed handling failure");
@ -907,7 +917,7 @@ public class AllDebridCom extends PluginForHost {
waitProgress.setProgressSource(this);
int lastProgress = -1;
try {
/* See https://docs.alldebrid.com/v4/#delayed-links */
/* See https://docs.alldebrid.com/#delayed-links */
final Form dlform = new Form();
dlform.setMethod(MethodType.GET);
dlform.setAction(api_base + "/link/delayed");
@ -938,8 +948,7 @@ public class AllDebridCom extends PluginForHost {
br.submitForm(dlform);
try {
/* We have to use the parser here because json contains two 'status' objects ;) */
final Map<String, Object> entries = handleErrors(account, link);
final Map<String, Object> data = (Map<String, Object>) entries.get("data");
final Map<String, Object> data = handleErrors(account, link);
delayedStatus = (int) JavaScriptEngineFactory.toLong(data.get("status"), 3);
final int tmpCurrentProgress = (int) ((Number) data.get("progress")).doubleValue() * 100;
if (tmpCurrentProgress > currentProgress) {
@ -1027,8 +1036,6 @@ public class AllDebridCom extends PluginForHost {
return chunks;
}
private static WeakHashMap<Account, HashSet<String>> RATE_LIMITED = new WeakHashMap<Account, HashSet<String>>();
private void checkRateLimit(Browser br, URLConnectionAdapter con, final Account account, final DownloadLink link) throws PluginException {
if (br.containsHTML("rate limiting, please retry") || con.getResponseCode() == 429) {
Browser.setRequestIntervalLimitGlobal(br.getHost(), 2000);
@ -1051,14 +1058,13 @@ public class AllDebridCom extends PluginForHost {
if (account == null) {
/* Account needed to check such links. */
return AvailableStatus.UNCHECKABLE;
} else {
if (!link.isNameSet()) {
link.setName(this.getFID(link));
}
generteFreshDirecturl(link, account);
/* No exception = File is online */
return AvailableStatus.TRUE;
}
if (!link.isNameSet()) {
link.setName(this.getFID(link));
}
generteFreshDirecturl(link, account);
/* No exception = File is online */
return AvailableStatus.TRUE;
}
@Override

View File

@ -58,6 +58,7 @@ import jd.plugins.Account.AccountType;
import jd.plugins.AccountInfo;
import jd.plugins.AccountInvalidException;
import jd.plugins.AccountRequiredException;
import jd.plugins.AccountTrafficView;
import jd.plugins.AccountUnavailableException;
import jd.plugins.DownloadLink;
import jd.plugins.DownloadLink.AvailableStatus;
@ -170,17 +171,52 @@ public abstract class HighWayCore extends UseNet {
}
}
/** For some hosts this multihost calculates less/more traffic than the actual filesize --> Take this into account here */
/** For some hosts this multihost calculates less/more traffic than the real file size --> Calculate this here */
@Override
public void update(final DownloadLink link, final Account account, long bytesTransfered) throws PluginException {
final int trafficCalc = getTrafficCalc(link);
bytesTransfered = (bytesTransfered * trafficCalc) / 100;
super.update(link, account, bytesTransfered);
}
/** Returns percentage factor used for traffic calculation. */
private int getTrafficCalc(final DownloadLink link) {
synchronized (getMapLock()) {
final Map<String, Integer> map = getMap(hostTrafficCalculationMap);
final Integer trafficCalc = map.get(link.getHost());
if (trafficCalc != null) {
bytesTransfered = (bytesTransfered * trafficCalc) / 100;
return trafficCalc.intValue();
} else {
return 100;
}
}
super.update(link, account, bytesTransfered);
}
@Override
public boolean enoughTrafficFor(final DownloadLink link, final Account account) throws Exception {
if (this.getStoredDirectlink(link) != null) {
/* Assume that no traffic is needed to download stored direct urls. */
return true;
}
final AccountTrafficView accountTrafficView = getAccountTrafficView(account);
if (accountTrafficView == null) {
return true;
} else if (accountTrafficView.isUnlimitedTraffic()) {
return true;
}
final long downloadSize = link.getView().getBytesTotalEstimated();
if (downloadSize <= 0) {
/* Size is unknown -> Assume we got enough traffic to download that link. */
return true;
}
final int trafficCalc = getTrafficCalc(link);
final long trafficNeeded = (downloadSize * trafficCalc) / 100;
final long trafficLeft = accountTrafficView.getTrafficLeft();
if (trafficNeeded <= trafficLeft) {
return true;
} else {
return false;
}
}
@Override
@ -199,7 +235,7 @@ public abstract class HighWayCore extends UseNet {
} else if (link.getPluginPatternMatcher().matches(PATTERN_TV)) {
try {
return UrlQuery.parse(link.getPluginPatternMatcher()).get("id");
} catch (MalformedURLException e) {
} catch (final MalformedURLException e) {
/* This should never happen! */
e.printStackTrace();
return null;
@ -427,7 +463,7 @@ public abstract class HighWayCore extends UseNet {
boolean resume = this.isResumeable(link, account);
final int maxChunks = this.getMaxChunks(link, account);
int statuscode;
if (!this.attemptStoredDownloadurlDownload(link, this.getHost() + "directlink", resume, maxChunks)) {
if (!this.attemptStoredDownloadurlDownload(link, resume, maxChunks)) {
this.login(account, false);
/* Request creation of downloadlink */
Map<String, Object> entries = null;
@ -442,7 +478,7 @@ public abstract class HighWayCore extends UseNet {
getdata += "&pass=" + Encoding.urlEncode(passCode);
}
br.getPage(getWebsiteBase() + "load.php?" + getdata);
entries = restoreFromString(br.toString(), TypeRef.MAP);
entries = restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
statuscode = ((Number) entries.get("code")).intValue();
if (statuscode != STATUSCODE_PASSWORD_NEEDED_OR_WRONG) {
break;
@ -494,7 +530,7 @@ public abstract class HighWayCore extends UseNet {
logger.info("Unsupported file-hash string: " + hash);
}
}
link.setProperty(this.getHost() + "directlink", dllink);
link.setProperty(getDirectlinkProperty(), dllink);
br.setAllowedResponseCodes(new int[] { 503 });
dl = jd.plugins.BrowserAdapter.openDownload(br, link, dllink, resume, maxChunks);
if (!this.looksLikeDownloadableContent(dl.getConnection())) {
@ -513,8 +549,16 @@ public abstract class HighWayCore extends UseNet {
}
}
private boolean attemptStoredDownloadurlDownload(final DownloadLink link, final String directlinkproperty, final boolean resumable, final int maxchunks) throws Exception {
final String url = link.getStringProperty(directlinkproperty);
private String getStoredDirectlink(final DownloadLink link) {
return link.getStringProperty(getDirectlinkProperty());
}
private String getDirectlinkProperty() {
return this.getHost() + "directlink";
}
private boolean attemptStoredDownloadurlDownload(final DownloadLink link, final boolean resumable, final int maxchunks) throws Exception {
final String url = this.getStoredDirectlink(link);
if (StringUtils.isEmpty(url)) {
return false;
}
@ -652,7 +696,7 @@ public abstract class HighWayCore extends UseNet {
this.login(account, true);
this.getPage(this.getAPIBase() + "?hoster&user");
final AccountInfo ai = new AccountInfo();
final Map<String, Object> entries = this.checkErrors(this.br, this.getDownloadLink(), account);
final Map<String, Object> entries = this.checkErrors(this.br, null, account);
final Map<String, Object> accountInfo = (Map<String, Object>) entries.get("user");
final int accountResume = ((Number) accountInfo.get("resume")).intValue();
final long premiumUntil = ((Number) accountInfo.get("premium_bis")).longValue();
@ -830,7 +874,7 @@ public abstract class HighWayCore extends UseNet {
query.appendEncoded("pass", account.getPass());
}
br.postPage(getAPIBase() + "?login", query);
this.checkErrors(this.br, this.getDownloadLink(), account);
this.checkErrors(this.br, null, account);
/* No Exception --> Assume that login was successful */
account.saveCookies(br.getCookies(br.getHost()), "");
}

View File

@ -49,12 +49,12 @@ public class HighWayMe2 extends HighWayCore {
public HighWayMe2(PluginWrapper wrapper) {
super(wrapper);
this.enablePremium("https://high-way.me/pages/tariffs/");
this.enablePremium("https://" + getHost() + "/pages/tariffs/");
}
@Override
public String getAGBLink() {
return "https://high-way.me/help/terms";
return "https://" + getHost() + "/help/terms";
}
@Override

View File

@ -1,265 +0,0 @@
//jDownloader - Downloadmanager
//Copyright (C) 2010 JD-Team support@jdownloader.org
//
//This program 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.
//
//This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
package jd.plugins.hoster;
import java.io.IOException;
import org.appwork.utils.formatter.SizeFormatter;
import jd.PluginWrapper;
import jd.config.Property;
import jd.http.Browser;
import jd.http.Cookies;
import jd.http.URLConnectionAdapter;
import jd.nutils.encoding.Encoding;
import jd.parser.Regex;
import jd.plugins.Account;
import jd.plugins.Account.AccountType;
import jd.plugins.AccountInfo;
import jd.plugins.AccountRequiredException;
import jd.plugins.DownloadLink;
import jd.plugins.DownloadLink.AvailableStatus;
import jd.plugins.HostPlugin;
import jd.plugins.LinkStatus;
import jd.plugins.PluginException;
import jd.plugins.PluginForHost;
import jd.plugins.components.PluginJSonUtils;
@HostPlugin(revision = "$Revision$", interfaceVersion = 2, names = { "ishare.iask.sina.com.cn" }, urls = { "https?://(?:www\\.)?ishare\\.iask\\.sina\\.com\\.cn/f/\\d+\\.html" })
public class IshareIaskSinaComCn extends PluginForHost {
public IshareIaskSinaComCn(PluginWrapper wrapper) {
super(wrapper);
this.enablePremium("http://ishare.iask.sina.com.cn/");
}
@Override
public String getAGBLink() {
return "http://iask.com/help/mzsm.html";
}
/* Connection stuff */
private final boolean FREE_RESUME = false;
private final int FREE_MAXCHUNKS = 1;
private final int FREE_MAXDOWNLOADS = 3;
private final boolean ACCOUNT_FREE_RESUME = true;
private final int ACCOUNT_FREE_MAXCHUNKS = 0;
private final int ACCOUNT_FREE_MAXDOWNLOADS = 20;
// private final boolean ACCOUNT_PREMIUM_RESUME = true;
// private final int ACCOUNT_PREMIUM_MAXCHUNKS = 0;
private final int ACCOUNT_PREMIUM_MAXDOWNLOADS = 20;
@SuppressWarnings("deprecation")
@Override
public AvailableStatus requestFileInformation(final DownloadLink link) throws IOException, PluginException {
this.setBrowserExclusive();
br.getPage(link.getDownloadURL());
if (br.containsHTML("<title>共享资料</title>|<br>5秒钟后跳转到首页</div>|近期共享资料正在配合有关部门进行淫秽、色情、|无法查看!<") || this.br.getHttpConnection().getResponseCode() == 404) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
String filename = br.getRegex("<title>(.*?) - 免费高速下载 - 共享资料</title>").getMatch(0);
if (filename == null) {
filename = br.getRegex("name=\"file_title\" id=\"file_des\" value=\"(.*?)\"").getMatch(0);
}
if (filename == null) {
filename = br.getRegex("name=\"hiddenfile_title\" id=\"hiddenfile_title\" value=\"(.*?)\"").getMatch(0);
}
if (filename == null) {
filename = br.getRegex("<h1 class=\"f14\" style=\"display:inline;\">(.*?)</h1></div>").getMatch(0);
}
if (filename == null) {
filename = br.getRegex("<input type=\"hidden\" name=\"title\" value=\"(.*?)\">").getMatch(0);
}
if (filename == null) {
filename = br.getRegex("<h2 title=\"([^<>\"]+)\">").getMatch(0);
}
String filesize = br.getRegex("class=\"f10\">0分<br>(.*?)</span></td>").getMatch(0);
if (filename != null) {
link.setName(filename.trim());
}
if (filesize != null) {
link.setDownloadSize(SizeFormatter.getSize(filesize));
}
return AvailableStatus.TRUE;
}
@Override
public void handleFree(final DownloadLink link) throws Exception, PluginException {
requestFileInformation(link);
doFree(link, FREE_RESUME, FREE_MAXCHUNKS, "free_directlink");
}
private void doFree(final DownloadLink link, final boolean resumable, final int maxchunks, final String directlinkproperty) throws Exception, PluginException {
String dllink = checkDirectLink(link, directlinkproperty);
if (dllink == null) {
if (br.containsHTML("<a class=\"btn-download btn-m-not\"><i class=\"icon-iShare\"></i>下载</a>")) {
throw new AccountRequiredException();
} else if (true) {
/* 2020-11-19: Account required for all files?! */
throw new AccountRequiredException();
}
br.setFollowRedirects(false);
this.br.getHeaders().put("Accept", "application/json, text/javascript, */*; q=0.01");
this.br.getHeaders().put("X-Requested-With", "XMLHttpRequest");
br.getPage("http://ishare.iask.sina.com.cn/f/download/" + new Regex(link.getDownloadURL(), "/(\\d+)\\.html").getMatch(0));
final String code = PluginJSonUtils.getJsonValue(this.br, "code");
if ("102".equals(code)) {
throw new PluginException(LinkStatus.ERROR_PREMIUM, PluginException.VALUE_ID_PREMIUM_ONLY);
}
dllink = PluginJSonUtils.getJsonValue(this.br, "data");
if (dllink == null) {
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
}
dl = jd.plugins.BrowserAdapter.openDownload(br, link, dllink, false, 1);
if (dl.getConnection().getContentType().contains("html")) {
br.followConnection();
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
link.setProperty(directlinkproperty, dllink);
dl.startDownload();
}
private String checkDirectLink(final DownloadLink downloadLink, final String property) {
String dllink = downloadLink.getStringProperty(property);
if (dllink != null) {
URLConnectionAdapter con = null;
try {
final Browser br2 = br.cloneBrowser();
con = br2.openHeadConnection(dllink);
if (con.getContentType().contains("html") || con.getLongContentLength() == -1) {
downloadLink.setProperty(property, Property.NULL);
dllink = null;
}
} catch (final Exception e) {
downloadLink.setProperty(property, Property.NULL);
dllink = null;
} finally {
try {
con.disconnect();
} catch (final Throwable e) {
}
}
}
return dllink;
}
@Override
public int getMaxSimultanFreeDownloadNum() {
return FREE_MAXDOWNLOADS;
}
private static Object LOCK = new Object();
private void login(final Account account, final boolean force) throws Exception {
synchronized (LOCK) {
try {
br.setFollowRedirects(true);
br.setCookiesExclusive(true);
final Cookies cookies = account.loadCookies("");
if (cookies != null && !force) {
this.br.setCookies(this.getHost(), cookies);
return;
}
final String username_b64 = Encoding.urlEncode(Encoding.Base64Encode(Encoding.urlEncode(account.getUser())));
br.getPage("http://" + this.getHost() + "/login?loginType=SINA&location=http://ishare.iask.sina.com.cn/");
final String pagerefer = Encoding.urlEncode(this.br.getURL());
br.getPage("https://login.sina.com.cn/sso/prelogin.php?entry=openapi&callback=sinaSSOController.preloginCallBack&su=" + username_b64 + "&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.18)&_=1483727712973");
final String is_openlock = PluginJSonUtils.getJsonValue(this.br, "is_openlock");
String pcid = PluginJSonUtils.getJsonValue(this.br, "pcid");
final String servertime = PluginJSonUtils.getJsonValue(this.br, "servertime");
final String rsakv = PluginJSonUtils.getJsonValue(this.br, "rsakv");
final String nonce = PluginJSonUtils.getJsonValue(this.br, "nonce");
final String pubkey = PluginJSonUtils.getJsonValue(this.br, "pubkey");
if (!"0".equals(is_openlock)) {
/* Wrong username */
if ("de".equalsIgnoreCase(System.getProperty("user.language"))) {
throw new PluginException(LinkStatus.ERROR_PREMIUM, "\r\nUngültiger Benutzername oder ungültiges Passwort!\r\nSchnellhilfe: \r\nDu bist dir sicher, dass dein eingegebener Benutzername und Passwort stimmen?\r\nFalls dein Passwort Sonderzeichen enthält, ändere es und versuche es erneut!", PluginException.VALUE_ID_PREMIUM_DISABLE);
} else {
throw new PluginException(LinkStatus.ERROR_PREMIUM, "\r\nInvalid username/password!\r\nQuick help:\r\nYou're sure that the username and password you entered are correct?\r\nIf your password contains special characters, change it (remove them) and try again!", PluginException.VALUE_ID_PREMIUM_DISABLE);
}
} else if (pcid == null || pcid.equals("") || servertime == null || servertime.equals("") || rsakv == null || rsakv.equals("") || nonce == null || nonce.equals("") || pubkey == null || pubkey.equals("")) {
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
pcid = Encoding.urlEncode(pcid);
final String captchaurl = "https://login.sina.com.cn/cgi/pin.php?r=" + rsakv + "&s=0&p=" + Encoding.urlEncode(pcid);
final DownloadLink dummyLink = new DownloadLink(this, "Account", this.getHost(), "http://" + this.getHost(), true);
final String c = getCaptchaCode(captchaurl, dummyLink);
String postdata = "entry=openapi&gateway=1&from=&savestate=0&useticket=1&pagerefer=" + pagerefer + "&wsseretry=servertime_error&ct=1800&s=1&vsnf=1&vsnval=&door=fBubv&appkey=1t4elW&pcid=" + pcid + "&su=" + username_b64 + "&service=miniblog&servertime=" + servertime + "&nonce=" + Encoding.urlEncode(nonce) + "&pwencode=rsa2&rsakv=" + Encoding.urlEncode(rsakv) + "&sp=" + pubkey.toLowerCase() + "&sr=1920*1080&encoding=UTF-8&cdult=2&domain=weibo.com&prelt=370&returntype=TEXT";
this.br.postPage("https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)&_=" + System.currentTimeMillis() + "&openapilogin=qrcode", postdata);
this.br.postPage("https://api.weibo.com/oauth2/authorize", "");
br.postPage("", "username=" + Encoding.urlEncode(account.getUser()) + "&password=" + Encoding.urlEncode(account.getPass()));
if (!isLoggedIn()) {
if ("de".equalsIgnoreCase(System.getProperty("user.language"))) {
throw new PluginException(LinkStatus.ERROR_PREMIUM, "\r\nUngültiger Benutzername oder ungültiges Passwort!\r\nSchnellhilfe: \r\nDu bist dir sicher, dass dein eingegebener Benutzername und Passwort stimmen?\r\nFalls dein Passwort Sonderzeichen enthält, ändere es und versuche es erneut!", PluginException.VALUE_ID_PREMIUM_DISABLE);
} else {
throw new PluginException(LinkStatus.ERROR_PREMIUM, "\r\nInvalid username/password!\r\nQuick help:\r\nYou're sure that the username and password you entered are correct?\r\nIf your password contains special characters, change it (remove them) and try again!", PluginException.VALUE_ID_PREMIUM_DISABLE);
}
}
account.saveCookies(this.br.getCookies(this.getHost()), "");
} catch (final PluginException e) {
account.clearCookies("");
throw e;
}
}
}
@SuppressWarnings("deprecation")
@Override
public AccountInfo fetchAccountInfo(final Account account) throws Exception {
final AccountInfo ai = new AccountInfo();
try {
login(account, true);
} catch (PluginException e) {
account.setValid(false);
throw e;
}
/* 2017-01-06: At the moment we only support free accounts. */
ai.setUnlimitedTraffic();
account.setType(AccountType.FREE);
account.setMaxSimultanDownloads(ACCOUNT_PREMIUM_MAXDOWNLOADS);
account.setConcurrentUsePossible(true);
ai.setStatus("Registered (free) user");
account.setValid(true);
return ai;
}
private boolean isLoggedIn() throws IOException {
this.br.getPage("http://" + this.getHost() + "/user/checkLogin");
final String success = PluginJSonUtils.getJsonValue(this.br, "succ");
return success != null && success.equals("Y") ? true : false;
}
@Override
public void handlePremium(final DownloadLink link, final Account account) throws Exception {
requestFileInformation(link);
login(account, false);
br.getPage(link.getDownloadURL());
doFree(link, ACCOUNT_FREE_RESUME, ACCOUNT_FREE_MAXCHUNKS, "account_free_directlink");
}
@Override
public int getMaxSimultanPremiumDownloadNum() {
return ACCOUNT_PREMIUM_MAXDOWNLOADS;
}
@Override
public void reset() {
}
@Override
public void resetDownloadlink(DownloadLink link) {
}
}

View File

@ -109,7 +109,8 @@ public class Offline extends PluginForHost {
"xshare.club", "creampiewomen.com", "cougarfuckclub.com", "oneload.xyz", "oneload.co", "ero-tik.com", "pornsharing.com", "fastshare.org", "dropcanvas.com", "come2store.com", "imgtiger.com", "imgdino.com", "fileflyer.com", "akatsuki-subs.net", "mega-otr.de", "pornsexwank.com", "allnetcorp.com", "nofile.io", "prochan.com", "freepornvideo.me", "upload2.com", "xxxkingtube.com", "qiannao.com", "uploadocean.com", "tunescoop.com", "udrop.net", "upload-earn.com", "uberupload.net", "xfiles.io", "void.cat", "idtbox.com", "easyfilecloud.com", "dramafever.com", "netdisk.sk", "tu.tv", "trilulilu.ro", "picsee.net", "uplod.ws", "uplod.org", "uploadshub.com", "upload.so", "fxpan.com", "linx.li", "upload.cd", "xfig.net", "vidtome.co", "vidtome.stream", "vidto.me", "vidto.se", "imgant.com", "sendvid.net", "vev.io", "thevideo.me", "thevideo.cc", "vev.red", "vidup.io", "vidup.me",
"vidup.tv", "vidop.icu", "upwap.ru", "snowfiles.com", "oboom.com", "nzblord.com", "fileshark.pl", "depofile.info", "dbupload.co", "dbupload.in", "luckfile.com", "boostfiles.net", "liveleak.com", "backin.net", "imagezilla.net", "filemia.co", "xtube.com", "imageteam.org", "imgstudio.org", "ge.tt", "datafilehost.com", "easylinkz.net", "jetload.net", "uploadship.com", "inclouddrive.com", "speed-down.org", "4downfiles.co", "4downfile.org", "4downfiles.org", "4downfiles.com", "4downfiles.net", "lunaticfiles.com", "dbree.co", "koofile.com", "up.media1fire.com", "fileup.cc", "sfiles.org", "share-online.to", "ozofiles.com", "public.upera.co", "proxy.nsanedown.com", "rapidu.net", "vidcloud.ru", "vcstream.to", "vidcloud.ru", "pornyeah.com", "vidlox.me", "vidlox.tv", "vivo.sx", "vivo.st", "dateiload.com", "streamon.to", "yunpan.cn", "file-space.org", "freefile.me", "damimage.com",
"imagedecode.com", "dimtus.com", "go-upload.com", "pieshare.me", "oxycloud.com", "overthumbs.com", "saruch.co", "uploadit.eu", "uploadbox.co", "vinload.com", "freaktab.org", "freshfile.pl", "intoupload.net", "duckstream.co", "share2win.xyz", "turbogb.com", "saikocloud.ml", "storex.cc", "sufile.com", "up-myfiles.com", "uploads.mobi", "uploadproper.com", "uploadproper.net", "viperfile.com", "filepup.net", "down4files.com", "faststore.org", "mon-partage.fr", "doraupload.com", "fastix.ru", "play.fm", "fastdrive.io", "imgbabes.com", "vpornvideos.com", "anavidz.com", "anavids.com", "imgflare.com", "imgbabes.com", "vupload.com", "vup.to", "filecad.com", "pornwild.to", "pornwild.com", "pornwild.su", "evilhub.com", "datoporn.com", "dato.porn", "filebit.net", "file4.net", "sexzindian.com", "bin.ge", "datator.cz", "dosyashare.com", "dosya.tv", "downster.net", "dunshare.com",
"dropdoc.ru", "dropmyfiles.com", "dropupload.com", "easyupload.net", "anzfile.net", "eyesfile.ca", "upvideo.to", "fakirdebrid.com", "fakirserver.info", "2file.win", "filelox.com", "filezip.cc", "filetitle.com", "zippyshare.com", "stiahnito.sk", "hubic.com", "egyupload.com", "erai-ddl3.info", "evoload.io", "vishare.pl", "wrzucajpliki.pl", "laraslevelbase.org", "kvid.org", "file4safe.com", "highload.to", "embedo.co", "loadit.io", "zupload.me", "sabercathost.com", "picflash.org", "megaload.co", "cornfile.com", "retro.sx", "videobin.co", "upload.mobi", "uploadmx.com", "woodrocket.com", "sunexenus.com", "upload24x7.com", "userload.co", "yourfilestorage.com", "afile.cloud", "ninjastream.to", "batshare.net", "gottanut.com", "linkbypass.online", "zeroshare.me", "ur-files.com", "linkdrop.net", "ausfile.com", "wplik.com", "expfile.com", "modelhub.com", "pandafiles.com" };
"dropdoc.ru", "dropmyfiles.com", "dropupload.com", "easyupload.net", "anzfile.net", "eyesfile.ca", "upvideo.to", "fakirdebrid.com", "fakirserver.info", "2file.win", "filelox.com", "filezip.cc", "filetitle.com", "zippyshare.com", "stiahnito.sk", "hubic.com", "egyupload.com", "erai-ddl3.info", "evoload.io", "vishare.pl", "wrzucajpliki.pl", "laraslevelbase.org", "kvid.org", "file4safe.com", "highload.to", "embedo.co", "loadit.io", "zupload.me", "sabercathost.com", "picflash.org", "megaload.co", "cornfile.com", "retro.sx", "videobin.co", "upload.mobi", "uploadmx.com", "woodrocket.com", "sunexenus.com", "upload24x7.com", "userload.co", "yourfilestorage.com", "afile.cloud", "ninjastream.to", "batshare.net", "gottanut.com", "linkbypass.online", "zeroshare.me", "ur-files.com", "linkdrop.net", "ausfile.com", "wplik.com", "expfile.com", "modelhub.com", "pandafiles.com",
"ishare.iask.sina.com.cn" };
for (final String singleDomainHost : singleDomainHosts) {
ret.add(new String[] { singleDomainHost });
}

View File

@ -53,12 +53,12 @@ public class SimplyPremiumCom2 extends HighWayCore {
public SimplyPremiumCom2(PluginWrapper wrapper) {
super(wrapper);
this.enablePremium("https://www.simply-premium.com/vip");
this.enablePremium("https://www." + getHost() + "/vip");
}
@Override
public String getAGBLink() {
return "https://www.simply-premium.com/terms";
return "https://www." + getHost() + "/terms";
}
@Override

View File

@ -127,6 +127,10 @@ public class UploadedpremiumlinkNet extends PluginForHost {
/* This should never happen */
throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, "Failed to find final downloadurl", 10 * 1000l);
}
if (passCode != null && link.getDownloadPassword() == null) {
logger.info("User entered valid download password: " + passCode);
link.setDownloadPassword(passCode);
}
dl = jd.plugins.BrowserAdapter.openDownload(br, link, dllink, this.isResumeable(link, account), 0);
if (!this.looksLikeDownloadableContent(dl.getConnection())) {
br.followConnection(true);
@ -263,29 +267,28 @@ public class UploadedpremiumlinkNet extends PluginForHost {
downloadErrorsFileUnavailable.add("MUST_BE_PREMIUM");
downloadErrorsFileUnavailable.add("RESOURCE_RETRIEVAL_FAILURE");
final String message = entries.get("message").toString();
final String category_error = entries.get("category_error").toString();
if (accountErrorsPermanent.contains(category_error)) {
final String errorcode = entries.get("category_error").toString();
if (accountErrorsPermanent.contains(errorcode)) {
throw new AccountInvalidException(message);
} else if (downloadErrorsFileUnavailable.contains(category_error)) {
} else if (downloadErrorsFileUnavailable.contains(errorcode)) {
throw new AccountUnavailableException(message, 5 * 60 * 1000);
} else if (downloadErrorsHostUnavailable.contains(category_error)) {
} else if (downloadErrorsHostUnavailable.contains(errorcode)) {
mhm.putError(accountErrorsTemporary, link, 5 * 60 * 1000l, message);
} else if (downloadErrorsFileUnavailable.contains(category_error)) {
} else if (downloadErrorsFileUnavailable.contains(errorcode)) {
mhm.handleErrorGeneric(account, link, message, 20);
} else if (category_error.equalsIgnoreCase("FILE_NOT_FOUND")) {
} else if (errorcode.equalsIgnoreCase("FILE_NOT_FOUND")) {
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND, message);
} else if (category_error.equalsIgnoreCase("LINK_PASS_PROTECTED")) {
final String dlpw = link.getDownloadPassword();
link.setDownloadPassword(null);
link.setProperty(PROPERTY_UPLOADEDPREMIUMLINK_PASSWORD_REQUIRED, true);
} else if (errorcode.equalsIgnoreCase("LINK_PASS_PROTECTED")) {
final String text;
if (dlpw == null) {
if (link.getDownloadPassword() == null) {
text = "Password required";
} else {
text = "Password wrong";
}
link.setDownloadPassword(null);
link.setProperty(PROPERTY_UPLOADEDPREMIUMLINK_PASSWORD_REQUIRED, true);
throw new PluginException(LinkStatus.ERROR_RETRY, text);
} else if (category_error.equalsIgnoreCase("LINK_THIRD_PARTY_PR_SUB_REQUIRED")) {
} else if (errorcode.equalsIgnoreCase("LINK_THIRD_PARTY_PR_SUB_REQUIRED")) {
/* Extra subscription required to download that item. */
throw new AccountRequiredException(message);
} else {

View File

@ -24,6 +24,18 @@ import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
import org.appwork.storage.JSonMapperException;
import org.appwork.storage.TypeRef;
import org.appwork.utils.DebugMode;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperHostPluginRecaptchaV2;
import org.jdownloader.downloader.hls.HLSDownloader;
import org.jdownloader.plugins.components.hls.HlsContainer;
import org.jdownloader.plugins.controller.LazyPlugin;
import org.jdownloader.scripting.JavaScriptEngineFactory;
import jd.PluginWrapper;
import jd.config.ConfigContainer;
import jd.config.ConfigEntry;
@ -48,18 +60,6 @@ import jd.plugins.PluginException;
import jd.plugins.PluginForHost;
import jd.plugins.components.PluginJSonUtils;
import org.appwork.storage.JSonMapperException;
import org.appwork.storage.TypeRef;
import org.appwork.utils.DebugMode;
import org.appwork.utils.StringUtils;
import org.appwork.utils.formatter.SizeFormatter;
import org.appwork.utils.formatter.TimeFormatter;
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperHostPluginRecaptchaV2;
import org.jdownloader.downloader.hls.HLSDownloader;
import org.jdownloader.plugins.components.hls.HlsContainer;
import org.jdownloader.plugins.controller.LazyPlugin;
import org.jdownloader.scripting.JavaScriptEngineFactory;
@HostPlugin(revision = "$Revision$", interfaceVersion = 3, names = {}, urls = {})
public class XHamsterCom extends PluginForHost {
public XHamsterCom(PluginWrapper wrapper) {
@ -448,7 +448,7 @@ public class XHamsterCom extends PluginForHost {
}
} else {
/* Free / Free-Account users can only download trailers. */
dllink = br.getRegex("<video src=\"(http[^<>\"]+)\"").getMatch(0);
dllink = br.getRegex("<video id=\"video-trailer\"[^<]*src=\"(http[^<>\"]+)\"").getMatch(0);
}
if (title != null) {
title = Encoding.htmlDecode(title).trim();
@ -973,7 +973,8 @@ public class XHamsterCom extends PluginForHost {
public void handleDownload(final DownloadLink link, final Account account) throws Exception {
requestFileInformation(link, account, true);
final String contentURL = getCorrectedURL(link.getPluginPatternMatcher());
if (!this.isPremiumURL(contentURL) && StringUtils.isEmpty(dllink)) {
final boolean isPremiumURL = this.isPremiumURL(contentURL);
if (StringUtils.isEmpty(dllink) && !isPremiumURL) {
// Access the page again to get a new direct link because by checking the availability the first linkisn't valid anymore
String passCode = link.getDownloadPassword();
if (isPasswordProtected(br)) {
@ -1033,6 +1034,8 @@ public class XHamsterCom extends PluginForHost {
throw new AccountRequiredException("You need to be friends with uploader");
} else if (isPaidContent(br)) {
throw new AccountRequiredException("Paid content");
} else if (isPremiumURL) {
throw new AccountRequiredException("Paid content & trailer download failed");
} else {
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
@ -1343,9 +1346,10 @@ public class XHamsterCom extends PluginForHost {
/* Check vja ajax request -> json */
br.getPage(api_base_premium + "/subscription/get");
/**
* Returns "null" if cookies are valid but this is not a premium account. </br> Redirects to mainpage if cookies are invalid.
* </br> Return json if cookies are valid. </br> Can also return json along with http responsecode 400 for valid cookies but
* user is non-premium.
* Returns "null" if cookies are valid but this is not a premium account. </br>
* Redirects to mainpage if cookies are invalid. </br>
* Return json if cookies are valid. </br>
* Can also return json along with http responsecode 400 for valid cookies but user is non-premium.
*/
final boolean looksLikeJsonResponse = br.getRequest().getHtmlCode().startsWith("{");
if (br.getHttpConnection().getContentType().contains("json") && (looksLikeJsonResponse || br.toString().equals("null"))) {
@ -1491,9 +1495,11 @@ public class XHamsterCom extends PluginForHost {
}
}
/**
* 2022-07-22: Workaround for possible serverside bug: </br> In some countries, xhamster seems to redirect users to xhamster2.com.
* </br> If those users send an Accept-Language header of "de,en-gb;q=0.7,en;q=0.3" they can get stuck in a redirect-loop between
* deu.xhamster3.com and deu.xhamster3.com. </br> See initial report: https://board.jdownloader.org/showthread.php?t=91170
* 2022-07-22: Workaround for possible serverside bug: </br>
* In some countries, xhamster seems to redirect users to xhamster2.com. </br>
* If those users send an Accept-Language header of "de,en-gb;q=0.7,en;q=0.3" they can get stuck in a redirect-loop between
* deu.xhamster3.com and deu.xhamster3.com. </br>
* See initial report: https://board.jdownloader.org/showthread.php?t=91170
*/
final String acceptLanguage = "en-gb;q=0.7,en;q=0.3";
br.setAcceptLanguage(acceptLanguage);