mirror of
https://github.com/mirror/jdownloader.git
synced 2024-11-23 12:09:43 +00:00
*Plugins: Fixes/Changes/Maintenance*
- BaixarPremiumNet: improved regex to find list of supported hosts - PornHubCom: added name "pornhub" to list of supported names - XvideosCom: added name "xvideos" to list of supported names - FlickrCom: small refactoring, added IP blocked detection RE ticket #QKUC2561-LVPR-0242ETRM - LeechallIo: added support for hCaptcha during login instead of reCaptcha RE ticket #QTAF8668-ZWXQ-7863RJZJ git-svn-id: svn://svn.jdownloader.org/jdownloader/trunk@49767 ebf7c1c2-ba36-0410-9fe8-c592906822b4 Former-commit-id: 29882d6a816dfe1be114c1a053f247493d50ae61
This commit is contained in:
parent
af59ab4afe
commit
1674e7633c
@ -18,8 +18,11 @@ package jd.plugins.hoster;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.jdownloader.plugins.controller.LazyPlugin;
|
||||
|
||||
import jd.PluginWrapper;
|
||||
import jd.config.Property;
|
||||
import jd.http.Browser;
|
||||
@ -36,8 +39,6 @@ import jd.plugins.PluginException;
|
||||
import jd.plugins.PluginForHost;
|
||||
import jd.utils.JDUtilities;
|
||||
|
||||
import org.jdownloader.plugins.controller.LazyPlugin;
|
||||
|
||||
@HostPlugin(revision = "$Revision$", interfaceVersion = 3, names = { "baixarpremium.net" }, urls = { "" })
|
||||
public class BaixarPremiumNet extends PluginForHost {
|
||||
private static HashMap<Account, HashMap<String, Long>> hostUnavailableMap = new HashMap<Account, HashMap<String, Long>>();
|
||||
@ -92,7 +93,6 @@ public class BaixarPremiumNet extends PluginForHost {
|
||||
final String hoststext = br.getRegex("premium aos servidores <span style=\"[^\"]+\">(.*?)<").getMatch(0);
|
||||
if (br.containsHTML(">\\s*Você não possui nenhum pacote de Conta Premium\\.\\s*<") || !is_premium) {
|
||||
account.setType(AccountType.FREE);
|
||||
ac.setStatus("Free Account");
|
||||
ac.setTrafficLeft(0);
|
||||
} else {
|
||||
/*
|
||||
@ -100,7 +100,6 @@ public class BaixarPremiumNet extends PluginForHost {
|
||||
* much effort for a website without API!
|
||||
*/
|
||||
account.setType(AccountType.PREMIUM);
|
||||
ac.setStatus("Premium Account");
|
||||
ac.setUnlimitedTraffic();
|
||||
}
|
||||
final ArrayList<String> supportedHosts = new ArrayList<String>();
|
||||
@ -109,17 +108,15 @@ public class BaixarPremiumNet extends PluginForHost {
|
||||
crippledHosts = hoststext.split(", ");
|
||||
} else {
|
||||
br.getPage("https://" + account.getHoster() + "/");
|
||||
crippledHosts = br.getRegex("theme/img/([A-Za-z0-9\\-]+)\\.(?:jpg|jpeg|png)\"").getColumn(0);
|
||||
if (crippledHosts.length == 0 || crippledHosts.length <= 5) {
|
||||
/* Especially for comprarpremium.com */
|
||||
crippledHosts = br.getRegex("/srv/([A-Za-z0-9\\-]+)\\-logo\\.(?:jpg|jpeg|png)\"").getColumn(0);
|
||||
}
|
||||
crippledHosts = br.getRegex("data-nome-server=\"([^\"]+)").getColumn(0);
|
||||
}
|
||||
for (String crippledhost : crippledHosts) {
|
||||
crippledhost = crippledhost.trim();
|
||||
crippledhost = crippledhost.toLowerCase();
|
||||
crippledhost = crippledhost.toLowerCase(Locale.ENGLISH);
|
||||
if (crippledhost.equals("icerbox")) {
|
||||
supportedHosts.add("icerbox.com");
|
||||
} else if (crippledhost.equals("bangbros")) {
|
||||
supportedHosts.add("bangbros.com");
|
||||
} else {
|
||||
supportedHosts.add(crippledhost);
|
||||
}
|
||||
@ -222,7 +219,6 @@ public class BaixarPremiumNet extends PluginForHost {
|
||||
|
||||
public boolean login(final Browser br, final Account account, final boolean force) throws Exception {
|
||||
synchronized (account) {
|
||||
try {
|
||||
/* Workaround for static usage */
|
||||
if (this.br == null) {
|
||||
this.br = br;
|
||||
@ -243,6 +239,7 @@ public class BaixarPremiumNet extends PluginForHost {
|
||||
return true;
|
||||
}
|
||||
br.clearCookies(account.getHoster());
|
||||
account.clearCookies("");
|
||||
/* Force full login! */
|
||||
}
|
||||
br.getPage("https://" + currenthost + "/logar/");
|
||||
@ -271,10 +268,6 @@ public class BaixarPremiumNet extends PluginForHost {
|
||||
}
|
||||
account.saveCookies(br.getCookies(currenthost), "");
|
||||
return true;
|
||||
} catch (final PluginException e) {
|
||||
account.clearCookies("");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@
|
||||
//along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package jd.plugins.hoster;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
@ -46,7 +45,6 @@ import jd.controlling.AccountController;
|
||||
import jd.http.Browser;
|
||||
import jd.http.Cookies;
|
||||
import jd.http.URLConnectionAdapter;
|
||||
import jd.nutils.JDHash;
|
||||
import jd.nutils.encoding.Encoding;
|
||||
import jd.parser.Regex;
|
||||
import jd.plugins.Account;
|
||||
@ -119,9 +117,9 @@ public class FlickrCom extends PluginForHost {
|
||||
public static final String PROPERTY_DIRECTURL = "directurl_%s";
|
||||
public static final String PROPERTY_ACCOUNT_CSRF = "csrf";
|
||||
public static final String PROPERTY_ACCOUNT_USERNAME_INTERNAL = "username_internal";
|
||||
private static final String TYPE_PHOTO = "https?://[^/]+/photos/([^<>\"/]+)/(\\d+)$";
|
||||
private static final String TYPE_PHOTO_AS_PART_OF_SET = "https?://[^/]+/photos/([^<>\"/]+)/(\\d+)/in/album-(\\d+)/?$";
|
||||
private static final String TYPE_PHOTO_AS_PART_OF_GALLERY = "https?://[^/]+/photos/([^<>\"/]+)/(\\d+)/in/gallery-(\\d+@N\\d+)-(\\d+)/?$";
|
||||
private static final String TYPE_PHOTO = "(?i)https?://[^/]+/photos/([^<>\"/]+)/(\\d+)$";
|
||||
private static final String TYPE_PHOTO_AS_PART_OF_SET = "(?i)https?://[^/]+/photos/([^<>\"/]+)/(\\d+)/in/album-(\\d+)/?$";
|
||||
private static final String TYPE_PHOTO_AS_PART_OF_GALLERY = "(?i)https?://[^/]+/photos/([^<>\"/]+)/(\\d+)/in/gallery-(\\d+@N\\d+)-(\\d+)/?$";
|
||||
|
||||
/** Max 2000 requests per hour. */
|
||||
@Override
|
||||
@ -133,7 +131,9 @@ public class FlickrCom extends PluginForHost {
|
||||
}
|
||||
}
|
||||
|
||||
public static final Browser prepBrowser(final Browser br) {
|
||||
@Override
|
||||
public Browser createNewBrowserInstance() {
|
||||
final Browser br = super.createNewBrowserInstance();
|
||||
br.setFollowRedirects(true);
|
||||
return br;
|
||||
}
|
||||
@ -171,7 +171,7 @@ public class FlickrCom extends PluginForHost {
|
||||
|
||||
@Override
|
||||
public int getMaxSimultanFreeDownloadNum() {
|
||||
return -1;
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
private String getPublicAPIKey(final Browser br) throws IOException {
|
||||
@ -185,7 +185,6 @@ public class FlickrCom extends PluginForHost {
|
||||
}
|
||||
|
||||
public AvailableStatus requestFileInformation(final DownloadLink link, final Account account, final boolean isDownload) throws Exception {
|
||||
prepBrowser(this.br);
|
||||
correctDownloadLink(link);
|
||||
if (!link.isNameSet()) {
|
||||
/* Set fallback name */
|
||||
@ -266,7 +265,13 @@ public class FlickrCom extends PluginForHost {
|
||||
/* 2021-09-13: Don't do this anymore as it may not always work for videos! */
|
||||
// br.getPage(https://www.flickr.com/photos/<pathAlias>/<photoID> + "/in/photostream");
|
||||
br.getPage(link.getPluginPatternMatcher());
|
||||
if (br.getHttpConnection().getResponseCode() == 404 || br.containsHTML("div class=\"Four04Case\">") || br.containsHTML("(?i)>\\s*This member is no longer active on Flickr") || br.containsHTML("class=\"Problem\"")) {
|
||||
if (br.getHttpConnection().getResponseCode() == 404) {
|
||||
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
|
||||
} else if (br.containsHTML("div class=\"Four04Case\">")) {
|
||||
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
|
||||
} else if (br.containsHTML("(?i)>\\s*This member is no longer active on Flickr")) {
|
||||
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
|
||||
} else if (br.containsHTML("class=\"Problem\"")) {
|
||||
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
|
||||
} else if (br.getHttpConnection().getResponseCode() == 403) {
|
||||
/* This can also happen when user is logged in --> This then probably means that that is private content. */
|
||||
@ -412,7 +417,10 @@ public class FlickrCom extends PluginForHost {
|
||||
}
|
||||
} else {
|
||||
logger.warning("Failed to find json in html");
|
||||
if (!isVideo(link)) {
|
||||
if (isVideo(link)) {
|
||||
/* Do nothing */
|
||||
return;
|
||||
}
|
||||
/* Old website handling */
|
||||
/*
|
||||
* Fast way to get finallink via site as we always try to access the "o" (original) quality. Page might be redirected!
|
||||
@ -474,7 +482,6 @@ public class FlickrCom extends PluginForHost {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks single video/photo via API and sets required DownloadLink properties. */
|
||||
private void availablecheckAPI(final DownloadLink link, final Account account) throws Exception {
|
||||
@ -737,7 +744,9 @@ public class FlickrCom extends PluginForHost {
|
||||
}
|
||||
|
||||
public static String decodeEncoding(final Plugin plugin, final String property, final String value) {
|
||||
if (value != null) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
String decodedValue = Encoding.unicodeDecode(value);
|
||||
try {
|
||||
decodedValue = URLEncode.decodeURIComponent(decodedValue, new URLEncode.Decoder() {
|
||||
@ -761,9 +770,6 @@ public class FlickrCom extends PluginForHost {
|
||||
}
|
||||
decodedValue = Encoding.htmlOnlyDecode(decodedValue);
|
||||
return decodedValue.trim();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkDirecturl(final DownloadLink link, final String directurl) throws IOException, PluginException {
|
||||
@ -772,18 +778,11 @@ public class FlickrCom extends PluginForHost {
|
||||
final Browser brc = br.cloneBrowser();
|
||||
brc.setFollowRedirects(true);
|
||||
con = brc.openHeadConnection(directurl);
|
||||
if (looksLikeDownloadableContent(con)) {
|
||||
this.handleConnectionErrors(brc, con);
|
||||
if (con.getCompleteContentLength() > 0) {
|
||||
link.setVerifiedFileSize(con.getCompleteContentLength());
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (con.getResponseCode() == 404) {
|
||||
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
|
||||
} else {
|
||||
throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, "Server error");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
con.disconnect();
|
||||
@ -792,6 +791,24 @@ public class FlickrCom extends PluginForHost {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleConnectionErrors(final Browser br, final URLConnectionAdapter con) throws PluginException, IOException {
|
||||
final DownloadLink link = this.getDownloadLink();
|
||||
if (StringUtils.containsIgnoreCase(con.getURL().toExternalForm(), "/photo_unavailable.gif")) {
|
||||
con.disconnect();
|
||||
errorBrokenFile(link);
|
||||
}
|
||||
if (!this.looksLikeDownloadableContent(con)) {
|
||||
br.followConnection(true);
|
||||
if (con.getResponseCode() == 403 && br.containsHTML(">\\s*Request forbidden by administrative rules")) {
|
||||
throw new PluginException(LinkStatus.ERROR_IP_BLOCKED, "Your IP was banned by flickr.com");
|
||||
}
|
||||
errorBrokenFile(link);
|
||||
/* This code should never be reached */
|
||||
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isVideo(final DownloadLink link) {
|
||||
if (StringUtils.equals(link.getStringProperty(PROPERTY_MEDIA_TYPE), "video")) {
|
||||
return true;
|
||||
@ -832,88 +849,37 @@ public class FlickrCom extends PluginForHost {
|
||||
}
|
||||
|
||||
public void handleDownload(final DownloadLink link, final Account account) throws Exception {
|
||||
if (!attemptStoredDownloadurlDownload(link)) {
|
||||
String directurl = getStoredDirecturl(link);
|
||||
if (directurl == null) {
|
||||
requestFileInformation(link, account, true);
|
||||
final String directurl = getStoredDirecturl(link);
|
||||
directurl = getStoredDirecturl(link);
|
||||
if (StringUtils.isEmpty(directurl)) {
|
||||
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
|
||||
}
|
||||
/* chunked transfer */
|
||||
dl = jd.plugins.BrowserAdapter.openDownload(br, link, directurl, isResumable(link), getMaxChunks(link));
|
||||
connectionErrorhandling(dl.getConnection());
|
||||
}
|
||||
dl = jd.plugins.BrowserAdapter.openDownload(br, link, directurl, isResumeable(link, account), getMaxChunks(link));
|
||||
this.handleConnectionErrors(br, dl.getConnection());
|
||||
if (!looksLikeDownloadableContent(dl.getConnection())) {
|
||||
br.followConnection(true);
|
||||
errorBrokenFile(link);
|
||||
/* This code should never be reached */
|
||||
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
|
||||
}
|
||||
}
|
||||
if (dl.startDownload()) {
|
||||
/*
|
||||
* 2016-08-19: Detect "Temporarily unavailable" message inside downloaded picture via md5 hash of the file:
|
||||
* https://board.jdownloader.org/showthread.php?t=70487
|
||||
*/
|
||||
boolean isTempUnavailable = false;
|
||||
try {
|
||||
isTempUnavailable = "e60b98765d26e34bfbb797c1a5f378f2".equalsIgnoreCase(JDHash.getMD5(new File(link.getFileOutput())));
|
||||
} catch (final Throwable ignore) {
|
||||
}
|
||||
if (isTempUnavailable) {
|
||||
/* Reset progress */
|
||||
link.setDownloadCurrent(0);
|
||||
/* Size unknown */
|
||||
link.setDownloadSize(0);
|
||||
errorBrokenImage();
|
||||
}
|
||||
}
|
||||
dl.startDownload();
|
||||
}
|
||||
|
||||
private static void connectionErrorhandling(final URLConnectionAdapter con) throws PluginException {
|
||||
if (StringUtils.containsIgnoreCase(con.getURL().toString(), "/photo_unavailable.gif")) {
|
||||
con.disconnect();
|
||||
errorBrokenImage();
|
||||
}
|
||||
}
|
||||
|
||||
private static void errorBrokenImage() throws PluginException {
|
||||
throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, "Broken image?");
|
||||
}
|
||||
|
||||
private boolean attemptStoredDownloadurlDownload(final DownloadLink link) throws Exception {
|
||||
final String url = getStoredDirecturl(link);
|
||||
if (StringUtils.isEmpty(url)) {
|
||||
return false;
|
||||
}
|
||||
final Browser brc = br.cloneBrowser();
|
||||
try {
|
||||
dl = new jd.plugins.BrowserAdapter().openDownload(brc, link, url, this.isResumable(link), this.getMaxChunks(link));
|
||||
} catch (final Throwable e) {
|
||||
logger.log(e);
|
||||
try {
|
||||
dl.getConnection().disconnect();
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
connectionErrorhandling(dl.getConnection());
|
||||
if (this.looksLikeDownloadableContent(dl.getConnection())) {
|
||||
return true;
|
||||
private void errorBrokenFile(final DownloadLink link) throws PluginException {
|
||||
final String errortext;
|
||||
if (isVideo(link)) {
|
||||
errortext = "Broken video?";
|
||||
} else {
|
||||
/* Delete stored URL so it won't be tried again. */
|
||||
link.removeProperty(getDirecturlProperty(link));
|
||||
brc.followConnection(true);
|
||||
throw new IOException();
|
||||
errortext = "Broken image?";
|
||||
}
|
||||
throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, errortext);
|
||||
}
|
||||
|
||||
private boolean isResumable(final DownloadLink link) {
|
||||
// if (isVideo(link)) {
|
||||
// return true;
|
||||
// } else {
|
||||
// return true;
|
||||
// }
|
||||
/*
|
||||
* 2021-09-22: Videos are always resumable. For photos it varies but upper handling correctly auto-detects it so let's allow resume
|
||||
* in general.
|
||||
*/
|
||||
@Override
|
||||
public boolean isResumeable(final DownloadLink link, final Account account) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -932,8 +898,8 @@ public class FlickrCom extends PluginForHost {
|
||||
|
||||
@Override
|
||||
public AccountInfo fetchAccountInfo(final Account account) throws Exception {
|
||||
final AccountInfo ai = new AccountInfo();
|
||||
login(account, true);
|
||||
final AccountInfo ai = new AccountInfo();
|
||||
ai.setUnlimitedTraffic();
|
||||
return ai;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ import org.appwork.storage.JSonStorage;
|
||||
import org.appwork.storage.TypeRef;
|
||||
import org.appwork.utils.StringUtils;
|
||||
import org.appwork.utils.formatter.TimeFormatter;
|
||||
import org.jdownloader.captcha.v2.challenge.hcaptcha.CaptchaHelperHostPluginHCaptcha;
|
||||
import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperHostPluginRecaptchaV2;
|
||||
import org.jdownloader.plugins.controller.LazyPlugin;
|
||||
import org.jdownloader.settings.GraphicalUserInterfaceSettings.SIZEUNIT;
|
||||
@ -62,6 +63,7 @@ public class LeechallIo extends PluginForHost {
|
||||
private final String PROPERTY_ACCOUNT_ACCESS_TOKEN = "access_token";
|
||||
private final String PROPERTY_ACCOUNT_RECAPTCHA_SITEKEY = "recaptchasitekey";
|
||||
private final String RECAPTCHA_SITEKEY_STATIC = "6LdqV7AiAAAAAK50kHwrESPTEwVuBpAX0MCrVI0e"; /* 2023-06-27 */
|
||||
private final String H_CAPTCHA_SITEKEY_STATIC = "b858042e-5b84-454c-8eda-5b3e670486d4"; /* 2024-09-12 */
|
||||
/* Don't touch the following! */
|
||||
private static final AtomicInteger runningDls = new AtomicInteger(0);
|
||||
|
||||
@ -302,21 +304,34 @@ public class LeechallIo extends PluginForHost {
|
||||
br.clearCookies(null);
|
||||
}
|
||||
}
|
||||
/* Get reCaptcha siteKey */
|
||||
final Map<String, Object> postdata = new HashMap<String, Object>();
|
||||
postdata.put("email", account.getUser());
|
||||
postdata.put("password", account.getPass());
|
||||
/* Get captcha siteKey */
|
||||
final String websiteloginurl = "https://" + this.getHost() + "/login";
|
||||
final Browser brc = br.cloneBrowser();
|
||||
brc.getHeaders().put(HTTPConstants.HEADER_REQUEST_REFERER, websiteloginurl);
|
||||
brc.getPage("https://" + this.getHost() + "/js/chunk-06b4b5f5.38692513.js");
|
||||
final boolean isHCaptcha = true;
|
||||
if (isHCaptcha) {
|
||||
/* 2024-09-12 */
|
||||
String hCaptchaSiteKey = brc.getRegex("VUE_APP_HCAPTCHA:\"([^\"]+)").getMatch(0);
|
||||
if (hCaptchaSiteKey == null) {
|
||||
logger.warning("Failed to find hCaptchaSiteKey --> Fallback to hardcoded value");
|
||||
hCaptchaSiteKey = H_CAPTCHA_SITEKEY_STATIC;
|
||||
}
|
||||
final String hcaptchaResponse = new CaptchaHelperHostPluginHCaptcha(this, brc, hCaptchaSiteKey).getToken();
|
||||
postdata.put("h-captcha-response", hcaptchaResponse);
|
||||
} else {
|
||||
/* Legacy */
|
||||
String reCaptchaSitekey = brc.getRegex("sitekey\\s*:\"([^\"]+)").getMatch(0);
|
||||
if (reCaptchaSitekey == null) {
|
||||
logger.warning("Failed to find reCaptchaSitekey --> Fallback to hardcoded value");
|
||||
reCaptchaSitekey = RECAPTCHA_SITEKEY_STATIC;
|
||||
}
|
||||
final Map<String, Object> postdata = new HashMap<String, Object>();
|
||||
postdata.put("email", account.getUser());
|
||||
postdata.put("password", account.getPass());
|
||||
final String recaptchaV2Response = new CaptchaHelperHostPluginRecaptchaV2(this, brc, reCaptchaSitekey).getToken();
|
||||
postdata.put("g-recaptcha-response", recaptchaV2Response);
|
||||
}
|
||||
br.getHeaders().put(HTTPConstants.HEADER_REQUEST_REFERER, websiteloginurl);
|
||||
final Map<String, Object> resp = this.accessAPI(null, "/auth/login", postdata, true);
|
||||
access_token = (String) resp.get("access_token");
|
||||
|
@ -163,7 +163,14 @@ public class PornHubCom extends PluginForHost {
|
||||
|
||||
@Override
|
||||
public String[] siteSupportedNames() {
|
||||
return buildSupportedNames(getPluginDomains());
|
||||
final String[] domains = buildSupportedNames(getPluginDomains());
|
||||
String[] supportedNames = new String[domains.length + 1];
|
||||
for (int i = 0; i < domains.length; i++) {
|
||||
supportedNames[i] = domains[i];
|
||||
}
|
||||
/* Add additional names here */
|
||||
supportedNames[supportedNames.length - 1] = "pornhub";
|
||||
return supportedNames;
|
||||
}
|
||||
|
||||
public static String[] getAnnotationUrls() {
|
||||
|
@ -1,417 +0,0 @@
|
||||
//jDownloader - Downloadmanager
|
||||
//Copyright (C) 2009 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.net.SocketTimeoutException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import jd.PluginWrapper;
|
||||
import jd.config.Property;
|
||||
import jd.http.Browser;
|
||||
import jd.http.Cookie;
|
||||
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.DownloadLink;
|
||||
import jd.plugins.DownloadLink.AvailableStatus;
|
||||
import jd.plugins.HostPlugin;
|
||||
import jd.plugins.LinkStatus;
|
||||
import jd.plugins.PluginException;
|
||||
import jd.plugins.PluginForHost;
|
||||
|
||||
import org.jdownloader.plugins.controller.LazyPlugin;
|
||||
import org.jdownloader.plugins.controller.LazyPlugin.FEATURE;
|
||||
|
||||
@HostPlugin(revision = "$Revision$", interfaceVersion = 3, names = { "u-labs.de" }, urls = { "" })
|
||||
public class UlabsDe extends PluginForHost {
|
||||
private static HashMap<Account, HashMap<String, Long>> hostUnavailableMap = new HashMap<Account, HashMap<String, Long>>();
|
||||
private static final String NOCHUNKS = "NOCHUNKS";
|
||||
private static final String MAINPAGE = "http://u-labs.de";
|
||||
private static final String NICE_HOST = MAINPAGE.replaceAll("(https://|http://)", "");
|
||||
private static final String NICE_HOSTproperty = MAINPAGE.replaceAll("(https://|http://|\\.|\\-)", "");
|
||||
private static final String url_accountboerse = "https://u-labs.de/accountBoerse/";
|
||||
/* Contains <host><aavailable_traffic> */
|
||||
private static HashMap<String, Long> hostTrafficleftMap = new HashMap<String, Long>();
|
||||
|
||||
public UlabsDe(PluginWrapper wrapper) {
|
||||
super(wrapper);
|
||||
this.enablePremium("https://u-labs.de/register.php");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAGBLink() {
|
||||
return "https://u-labs.de/impressum.php";
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyPlugin.FEATURE[] getFeatures() {
|
||||
return new LazyPlugin.FEATURE[] { LazyPlugin.FEATURE.MULTIHOST };
|
||||
}
|
||||
|
||||
private boolean useAPI() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccountInfo fetchAccountInfo(final Account account) throws Exception {
|
||||
AccountInfo ac = new AccountInfo();
|
||||
if (this.useAPI()) {
|
||||
ac = api_fetchAccountInfo(account);
|
||||
} else {
|
||||
ac = site_fetchAccountInfo(account);
|
||||
}
|
||||
return ac;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxSimultanFreeDownloadNum() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleFree(DownloadLink downloadLink) throws Exception, PluginException {
|
||||
throw new PluginException(LinkStatus.ERROR_PREMIUM, PluginException.VALUE_ID_PREMIUM_ONLY);
|
||||
}
|
||||
|
||||
/* no override to keep plugin compatible to old stable */
|
||||
public void handleMultiHost(final DownloadLink link, final Account account) throws Exception {
|
||||
synchronized (hostUnavailableMap) {
|
||||
HashMap<String, Long> unavailableMap = hostUnavailableMap.get(account);
|
||||
if (unavailableMap != null) {
|
||||
Long lastUnavailable = unavailableMap.get(link.getHost());
|
||||
if (lastUnavailable != null && System.currentTimeMillis() < lastUnavailable) {
|
||||
final long wait = lastUnavailable - System.currentTimeMillis();
|
||||
throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, "Host is temporarily unavailable via " + this.getHost(), wait);
|
||||
} else if (lastUnavailable != null) {
|
||||
unavailableMap.remove(link.getHost());
|
||||
if (unavailableMap.size() == 0) {
|
||||
hostUnavailableMap.remove(account);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String dllink = checkDirectLink(link, NICE_HOST + "directlink");
|
||||
if (dllink == null) {
|
||||
if (this.useAPI()) {
|
||||
dllink = api_get_dllink(link, account);
|
||||
} else {
|
||||
dllink = site_get_dllink(link, account);
|
||||
}
|
||||
}
|
||||
int maxChunks = 1;
|
||||
if (link.getBooleanProperty(UlabsDe.NOCHUNKS, false)) {
|
||||
maxChunks = 1;
|
||||
}
|
||||
try {
|
||||
dl = jd.plugins.BrowserAdapter.openDownload(br, link, dllink, false, maxChunks);
|
||||
} catch (final SocketTimeoutException e) {
|
||||
handlePluginBroken(account, link, "timeout_dlstart", 5);
|
||||
}
|
||||
if (dl.getConnection().getContentType().contains("html")) {
|
||||
br.followConnection();
|
||||
final String errorcode = new Regex(br.getURL(), "code=(\\d+)").getMatch(0);
|
||||
if ("1".equals(errorcode)) {
|
||||
logger.info("Your registration / account is invalid");
|
||||
throw new PluginException(LinkStatus.ERROR_PREMIUM, "Invalid registration/account", PluginException.VALUE_ID_PREMIUM_DISABLE);
|
||||
} else if ("2".equals(errorcode)) {
|
||||
logger.info("Invalid URL --> Temporarily remove current host from hostlist");
|
||||
tempUnavailableHoster(account, link, 3 * 60 * 60 * 1000);
|
||||
} else if ("3".equals(errorcode)) {
|
||||
logger.info("Not enough traffic to download file --> Temporarily remove current host from hostlist");
|
||||
tempUnavailableHoster(account, link, 10 * 60 * 1000);
|
||||
} else if ("4".equals(errorcode)) {
|
||||
logger.info("Downloadlink seems to be offline");
|
||||
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
|
||||
} else if ("5".equals(errorcode)) {
|
||||
logger.info("An unknown error happened");
|
||||
tempUnavailableHoster(account, link, 10 * 60 * 1000);
|
||||
} else if ("6".equals(errorcode)) {
|
||||
logger.info("An 'API error' happened");
|
||||
tempUnavailableHoster(account, link, 2 * 60 * 1000);
|
||||
} else if ("7".equals(errorcode)) {
|
||||
logger.info("The host whose downloadlink you tried is not supported by this multihost --> Temporarily remove current host from hostlist");
|
||||
tempUnavailableHoster(account, link, 10 * 60 * 1000l);
|
||||
} else if ("8".equals(errorcode)) {
|
||||
logger.info("There are no available host-accounts at the moment --> Temporarily remove current host from hostlist");
|
||||
tempUnavailableHoster(account, link, 15 * 60 * 60 * 1000);
|
||||
} else if ("10".equals(errorcode)) {
|
||||
logger.info("Your account is banned at the moment --> Disable it");
|
||||
throw new PluginException(LinkStatus.ERROR_PREMIUM, "Banned account!", PluginException.VALUE_ID_PREMIUM_DISABLE);
|
||||
} else if (errorcode != null) {
|
||||
logger.warning("Unhandled errorcode: " + errorcode);
|
||||
}
|
||||
logger.info("Unhandled download error on " + NICE_HOST + ": " + br.toString());
|
||||
handlePluginBroken(account, link, "unknown_server_error", 5);
|
||||
}
|
||||
link.setProperty(NICE_HOST + "directlink", dllink);
|
||||
try {
|
||||
if (!this.dl.startDownload()) {
|
||||
try {
|
||||
if (dl.externalDownloadStop()) {
|
||||
return;
|
||||
}
|
||||
} catch (final Throwable e) {
|
||||
}
|
||||
/* unknown error, we disable multiple chunks */
|
||||
if (link.getBooleanProperty(UlabsDe.NOCHUNKS, false) == false) {
|
||||
link.setProperty(UlabsDe.NOCHUNKS, Boolean.valueOf(true));
|
||||
throw new PluginException(LinkStatus.ERROR_RETRY);
|
||||
}
|
||||
}
|
||||
} catch (final PluginException e) {
|
||||
if (maxChunks == 1) {
|
||||
link.setProperty(NICE_HOST + "directlink", Property.NULL);
|
||||
}
|
||||
// New V2 chunk errorhandling
|
||||
/* unknown error, we disable multiple chunks */
|
||||
if (maxChunks > 1 && e.getLinkStatus() != LinkStatus.ERROR_RETRY && link.getBooleanProperty(UlabsDe.NOCHUNKS, false) == false) {
|
||||
link.setProperty(UlabsDe.NOCHUNKS, Boolean.valueOf(true));
|
||||
throw new PluginException(LinkStatus.ERROR_RETRY);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is intended to handle out of date errors which might occur seldom by re-tring a couple of times before we temporarily remove the host
|
||||
* from the host list.
|
||||
*
|
||||
* @param dl
|
||||
* : The DownloadLink
|
||||
* @param error
|
||||
* : The name of the error
|
||||
* @param maxRetries
|
||||
* : Max retries before out of date error is thrown
|
||||
*/
|
||||
private void handlePluginBroken(final Account acc, final DownloadLink dl, final String error, final int maxRetries) throws PluginException {
|
||||
int timesFailed = dl.getIntegerProperty(NICE_HOSTproperty + "failedtimes_" + error, 0);
|
||||
dl.getLinkStatus().setRetryCount(0);
|
||||
if (timesFailed <= maxRetries) {
|
||||
logger.info(NICE_HOST + ": " + error + " -> Retrying");
|
||||
timesFailed++;
|
||||
dl.setProperty(NICE_HOSTproperty + "failedtimes_" + error, timesFailed);
|
||||
throw new PluginException(LinkStatus.ERROR_RETRY, error);
|
||||
} else {
|
||||
dl.setProperty(NICE_HOSTproperty + "failedtimes_" + error, Property.NULL);
|
||||
logger.info(NICE_HOST + ": " + error + " -> Disabling current host");
|
||||
tempUnavailableHoster(acc, dl, 1 * 60 * 60 * 1000l);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AvailableStatus requestFileInformation(DownloadLink link) throws Exception {
|
||||
return AvailableStatus.UNCHECKABLE;
|
||||
}
|
||||
|
||||
private static Object LOCK = new Object();
|
||||
|
||||
private AccountInfo site_fetchAccountInfo(final Account account) throws Exception {
|
||||
final AccountInfo ac = new AccountInfo();
|
||||
if (!site_login(account, true)) {
|
||||
if ("de".equalsIgnoreCase(System.getProperty("user.language"))) {
|
||||
throw new PluginException(LinkStatus.ERROR_PREMIUM, "\r\nUngültiger Benutzername oder 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);
|
||||
}
|
||||
}
|
||||
if (br.getURL() == null || !br.getURL().equals(url_accountboerse)) {
|
||||
br.getPage(url_accountboerse);
|
||||
}
|
||||
final String[] hosts = br.getRegex("\"name\":[\t\n\r ]+\"([^<>\"]*?)\"").getColumn(0);
|
||||
final ArrayList<String> supportedHosts = new ArrayList<String>();
|
||||
long trafficavailable = 0;
|
||||
long trafficmax = 0;
|
||||
final String[] traffics = br.getRegex("\"freeTraffic\":[\t\n\r ]+(\\d+)").getColumn(0);
|
||||
final String[] traffics_max = br.getRegex("\"totalTraffic\":[\t\n\r ]+(\\d+)").getColumn(0);
|
||||
synchronized (hostTrafficleftMap) {
|
||||
for (int i = 0; i < traffics.length; i++) {
|
||||
final String trafficstr = traffics[i];
|
||||
final String host_traffic_maxstr = traffics_max[i];
|
||||
final long trafficlong = Long.parseLong(trafficstr) * 1024 * 1024;
|
||||
final long host_traffic_max = Long.parseLong(host_traffic_maxstr) * 1024 * 1024;
|
||||
trafficavailable += trafficlong;
|
||||
trafficmax += host_traffic_max;
|
||||
final String host = hosts[i].toLowerCase();
|
||||
hostTrafficleftMap.put(host, trafficlong);
|
||||
supportedHosts.add(host);
|
||||
}
|
||||
}
|
||||
ac.setTrafficLeft(trafficavailable);
|
||||
ac.setTrafficMax(trafficmax);
|
||||
/* They only have free accounts */
|
||||
account.setType(AccountType.FREE);
|
||||
account.setMaxSimultanDownloads(-1);
|
||||
account.setConcurrentUsePossible(true);
|
||||
ac.setMultiHostSupport(this, supportedHosts);
|
||||
ac.setStatus("Registered (free) account");
|
||||
return ac;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean site_login(final Account account, final boolean force) throws Exception {
|
||||
synchronized (LOCK) {
|
||||
try {
|
||||
// Load cookies
|
||||
br.setCookiesExclusive(true);
|
||||
final Object ret = account.getProperty("cookies", null);
|
||||
boolean acmatch = Encoding.urlEncode(account.getUser()).equals(account.getStringProperty("name", Encoding.urlEncode(account.getUser())));
|
||||
if (acmatch) {
|
||||
acmatch = Encoding.urlEncode(account.getPass()).equals(account.getStringProperty("pass", Encoding.urlEncode(account.getPass())));
|
||||
}
|
||||
if (acmatch && ret != null && ret instanceof Map<?, ?>) {
|
||||
final Map<String, String> cookies = (Map<String, String>) ret;
|
||||
if (account.isValid()) {
|
||||
for (final Map.Entry<String, String> cookieEntry : cookies.entrySet()) {
|
||||
final String key = cookieEntry.getKey();
|
||||
final String value = cookieEntry.getValue();
|
||||
br.setCookie(MAINPAGE, key, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
br.setFollowRedirects(true);
|
||||
String postData = "cookieuser=1&s=&securitytoken=guest&do=login&url=https%3A%2F%2Fu-labs.de%2FaccountBoerse%2Fhome%2Findex%2F&hiddenlogin=do&vb_login_username=" + Encoding.urlEncode(account.getUser()) + "&vb_login_password=" + Encoding.urlEncode(account.getPass());
|
||||
br.postPage("https://u-labs.de/forum/login.php?do=login", postData);
|
||||
if (br.getCookie(MAINPAGE, "bb_password") == null) {
|
||||
if ("de".equalsIgnoreCase(System.getProperty("user.language"))) {
|
||||
throw new PluginException(LinkStatus.ERROR_PREMIUM, "\r\nUngültiger Benutzername oder 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);
|
||||
}
|
||||
}
|
||||
// Save cookies
|
||||
final HashMap<String, String> cookies = new HashMap<String, String>();
|
||||
final Cookies add = br.getCookies(MAINPAGE);
|
||||
for (final Cookie c : add.getCookies()) {
|
||||
cookies.put(c.getKey(), c.getValue());
|
||||
}
|
||||
account.setProperty("name", Encoding.urlEncode(account.getUser()));
|
||||
account.setProperty("pass", Encoding.urlEncode(account.getPass()));
|
||||
account.setProperty("cookies", cookies);
|
||||
return true;
|
||||
} catch (final PluginException e) {
|
||||
account.setProperty("cookies", Property.NULL);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private String site_get_dllink(final DownloadLink link, final Account acc) throws Exception {
|
||||
String dllink;
|
||||
String hoster;
|
||||
site_login(acc, false);
|
||||
br.getPage(url_accountboerse);
|
||||
final String userid = br.getRegex("\\'userid\\':[\t\n\r ]+(\\d+)").getMatch(0);
|
||||
final String authentificationToken = br.getRegex("\\'authentificationToken\\':[\t\n\r ]+\\'([^<>\"]*?)\\'").getMatch(0);
|
||||
final String externalBackendURL = br.getRegex("\\'externalBackendURL\\':[\t\n\r ]+\\'(http[^<>\"]*?)\\'").getMatch(0);
|
||||
if (userid == null || authentificationToken == null || externalBackendURL == null) {
|
||||
handlePluginBroken(acc, link, "dllink_null", 3);
|
||||
}
|
||||
/* Assumption that they only have 2 supported hosts */
|
||||
if (link.getDownloadURL().contains("share-online")) {
|
||||
hoster = "shareOnlineBiz";
|
||||
} else {
|
||||
hoster = "uploadedNet";
|
||||
}
|
||||
dllink = externalBackendURL + "&url=" + Encoding.urlEncode(link.getDownloadURL()) + "&authentificationToken=" + authentificationToken + "&userid=" + userid + "&hoster=" + hoster;
|
||||
return dllink;
|
||||
}
|
||||
|
||||
private AccountInfo api_fetchAccountInfo(final Account account) throws Exception {
|
||||
if (!api_login(account, true)) {
|
||||
if ("de".equalsIgnoreCase(System.getProperty("user.language"))) {
|
||||
throw new PluginException(LinkStatus.ERROR_PREMIUM, "\r\nUngültiger Benutzername oder 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);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean api_login(final Account account, final boolean force) throws Exception {
|
||||
return false;
|
||||
}
|
||||
|
||||
private String api_get_dllink(final DownloadLink link, final Account acc) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
private String checkDirectLink(final DownloadLink downloadLink, final String property) {
|
||||
String dllink = downloadLink.getStringProperty(property);
|
||||
if (dllink != null) {
|
||||
try {
|
||||
final Browser br2 = br.cloneBrowser();
|
||||
br2.setFollowRedirects(true);
|
||||
URLConnectionAdapter con = br2.openGetConnection(dllink);
|
||||
if (con.getContentType().contains("html") || con.getLongContentLength() == -1) {
|
||||
downloadLink.setProperty(property, Property.NULL);
|
||||
dllink = null;
|
||||
}
|
||||
con.disconnect();
|
||||
} catch (final Exception e) {
|
||||
downloadLink.setProperty(property, Property.NULL);
|
||||
dllink = null;
|
||||
}
|
||||
}
|
||||
return dllink;
|
||||
}
|
||||
|
||||
private void tempUnavailableHoster(Account account, DownloadLink downloadLink, long timeout) throws PluginException {
|
||||
if (downloadLink == null) {
|
||||
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT, "Unable to handle this errorcode!");
|
||||
}
|
||||
synchronized (hostUnavailableMap) {
|
||||
HashMap<String, Long> unavailableMap = hostUnavailableMap.get(account);
|
||||
if (unavailableMap == null) {
|
||||
unavailableMap = new HashMap<String, Long>();
|
||||
hostUnavailableMap.put(account, unavailableMap);
|
||||
}
|
||||
/* wait to retry this host */
|
||||
unavailableMap.put(downloadLink.getHost(), (System.currentTimeMillis() + timeout));
|
||||
}
|
||||
throw new PluginException(LinkStatus.ERROR_RETRY);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public boolean canHandle(final DownloadLink downloadLink, final Account account) throws Exception {
|
||||
synchronized (hostTrafficleftMap) {
|
||||
final String host = downloadLink.getHost();
|
||||
if (hostTrafficleftMap.containsKey(host)) {
|
||||
final long traffic_left = hostTrafficleftMap.get(host);
|
||||
if (downloadLink.getDownloadSize() > traffic_left) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetDownloadlink(DownloadLink link) {
|
||||
}
|
||||
}
|
@ -18,14 +18,14 @@ package jd.plugins.hoster;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jdownloader.plugins.components.config.XvideosComConfig;
|
||||
|
||||
import jd.PluginWrapper;
|
||||
import jd.http.Browser;
|
||||
import jd.plugins.DownloadLink;
|
||||
import jd.plugins.HostPlugin;
|
||||
import jd.plugins.PluginDependencies;
|
||||
|
||||
import org.jdownloader.plugins.components.config.XvideosComConfig;
|
||||
|
||||
@HostPlugin(revision = "$Revision$", interfaceVersion = 2, names = {}, urls = {})
|
||||
@PluginDependencies(dependencies = { jd.plugins.decrypter.XvideosComProfile.class })
|
||||
public class XvideosCom extends XvideosCore {
|
||||
@ -72,7 +72,14 @@ public class XvideosCom extends XvideosCore {
|
||||
|
||||
@Override
|
||||
public String[] siteSupportedNames() {
|
||||
return buildSupportedNames(getPluginDomains());
|
||||
final String[] domains = buildSupportedNames(getPluginDomains());
|
||||
String[] supportedNames = new String[domains.length + 1];
|
||||
for (int i = 0; i < domains.length; i++) {
|
||||
supportedNames[i] = domains[i];
|
||||
}
|
||||
/* Add additional names here */
|
||||
supportedNames[supportedNames.length - 1] = "xvideos";
|
||||
return supportedNames;
|
||||
}
|
||||
|
||||
public static String[] getAnnotationUrls() {
|
||||
|
Loading…
Reference in New Issue
Block a user