Skip to content

Commit 7717395

Browse files
author
updating-bot
committed
mirroring bot - 2025/08/13
1 parent f8fa9ed commit 7717395

File tree

6 files changed

+269
-122
lines changed

6 files changed

+269
-122
lines changed

svn_trunk/src/jd/plugins/decrypter/ThreeCatCat.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
import jd.plugins.PluginForDecrypt;
3838
import jd.plugins.hoster.DirectHTTP;
3939

40-
@DecrypterPlugin(revision = "$Revision: 51291 $", interfaceVersion = 3, names = {}, urls = {})
40+
@DecrypterPlugin(revision = "$Revision: 51318 $", interfaceVersion = 3, names = {}, urls = {})
4141
public class ThreeCatCat extends PluginForDecrypt {
4242
public ThreeCatCat(PluginWrapper wrapper) {
4343
super(wrapper);
@@ -105,10 +105,14 @@ public ArrayList<DownloadLink> decryptIt(final CryptedLink param, ProgressContro
105105
final Map<String, Object> images = (Map<String, Object>) entries.get("imatges");
106106
final List<Map<String, Object>> subtitles = (List<Map<String, Object>>) entries.get("subtitols");
107107
final Map<String, Object> media = (Map<String, Object>) entries.get("media");
108-
String title = (String) info.get("titol_complet");
109-
if (StringUtils.isEmpty(title)) {
110-
title = info.get("titol").toString();
111-
}
108+
// String title = (String) info.get("titol_complet");
109+
// if (StringUtils.isEmpty(title)) {
110+
// title = info.get("titol").toString();
111+
// }
112+
/* Mimic title which website is using for <title> html tag */
113+
String title = info.get("titol").toString();
114+
final String programme = info.get("programa").toString();
115+
title = programme + " - " + title;
112116
final String description = (String) info.get("descripcio");
113117
/* Add video qualities */
114118
String lastMediaTitle = null;

svn_trunk/src/jd/plugins/download/raf/HTTPDownloader.java

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@
2929
import java.util.concurrent.atomic.AtomicInteger;
3030
import java.util.concurrent.atomic.AtomicReference;
3131

32+
import org.appwork.exceptions.WTFException;
33+
import org.appwork.net.protocol.http.HTTPConstants;
34+
import org.appwork.storage.config.JsonConfig;
35+
import org.appwork.utils.StringUtils;
36+
import org.appwork.utils.formatter.TimeFormatter;
37+
import org.appwork.utils.logging2.LogInterface;
38+
import org.appwork.utils.logging2.LogSource;
39+
import org.appwork.utils.net.HTTPHeader;
40+
import org.appwork.utils.net.httpconnection.HTTPConnectionUtils;
41+
import org.appwork.utils.os.CrossSystem;
42+
import org.jdownloader.plugins.DownloadPluginProgress;
43+
import org.jdownloader.plugins.SkipReason;
44+
import org.jdownloader.plugins.SkipReasonException;
45+
import org.jdownloader.settings.GeneralSettings;
46+
import org.jdownloader.translate._JDT;
47+
import org.jdownloader.updatev2.InternetConnectionSettings;
48+
3249
import jd.controlling.downloadcontroller.DiskSpaceReservation;
3350
import jd.controlling.downloadcontroller.DownloadSession;
3451
import jd.controlling.downloadcontroller.ExceptionRunnable;
@@ -53,23 +70,6 @@
5370
import jd.plugins.download.raf.FileBytesMap.FileBytesMapView;
5471
import jd.plugins.download.raf.HTTPChunk.ERROR;
5572

56-
import org.appwork.exceptions.WTFException;
57-
import org.appwork.net.protocol.http.HTTPConstants;
58-
import org.appwork.storage.config.JsonConfig;
59-
import org.appwork.utils.StringUtils;
60-
import org.appwork.utils.formatter.TimeFormatter;
61-
import org.appwork.utils.logging2.LogInterface;
62-
import org.appwork.utils.logging2.LogSource;
63-
import org.appwork.utils.net.HTTPHeader;
64-
import org.appwork.utils.net.httpconnection.HTTPConnectionUtils;
65-
import org.appwork.utils.os.CrossSystem;
66-
import org.jdownloader.plugins.DownloadPluginProgress;
67-
import org.jdownloader.plugins.SkipReason;
68-
import org.jdownloader.plugins.SkipReasonException;
69-
import org.jdownloader.settings.GeneralSettings;
70-
import org.jdownloader.translate._JDT;
71-
import org.jdownloader.updatev2.InternetConnectionSettings;
72-
7373
public class HTTPDownloader extends DownloadInterface implements FileBytesCacheFlusher, BytesMappedFileCallback {
7474
public static enum STATEFLAG {
7575
RUN,
@@ -662,7 +662,7 @@ public static HashInfo getHashInfoFromHeaders(final LogInterface logger, final U
662662
public static HashInfo parseXGoogHash(LogInterface logger, final URLConnectionAdapter con) {
663663
HashInfo ret = null;
664664
final List<String> googleHashList = con.getRequest().getResponseHeaders("X-Goog-Hash");
665-
if (googleHashList != null && googleHashList.size() > 0) {
665+
if (googleHashList != null && !googleHashList.isEmpty()) {
666666
for (final String googleHash : googleHashList) {
667667
if (googleHash == null) {
668668
continue;
@@ -696,7 +696,7 @@ public static HashInfo parseXGoogHash(LogInterface logger, final URLConnectionAd
696696

697697
public static HashInfo parseAmazonHash(final LogInterface logger, final URLConnectionAdapter con) {
698698
final List<String> amazonHashList = con.getRequest().getResponseHeaders("x-amz-meta-md5-hash");
699-
if (amazonHashList != null && amazonHashList.size() > 0) {
699+
if (amazonHashList != null && !amazonHashList.isEmpty()) {
700700
for (final String amazonHash : amazonHashList) {
701701
if (amazonHash == null) {
702702
continue;
@@ -708,6 +708,23 @@ public static HashInfo parseAmazonHash(final LogInterface logger, final URLConne
708708
}
709709
}
710710
}
711+
final List<String> amazonRequestIDList = con.getRequest().getResponseHeaders("x-amz-request-id");
712+
final List<String> etagList = con.getRequest().getResponseHeaders("etag");
713+
if (amazonRequestIDList != null && !amazonRequestIDList.isEmpty() && etagList != null && !etagList.isEmpty()) {
714+
/**
715+
* 2025-08-12: e.g. thumbnail and subtitles from orf.at: /video/14285832/schlosshotel-orth-220-alles-verspielt <br>
716+
* Reference: https://board.jdownloader.org/showthread.php?t=97742
717+
*/
718+
for (final String etag : etagList) {
719+
final String md5hash = new Regex(etag, "W/\"([a-f0-9]{32})\"").getMatch(0);
720+
if (md5hash == null) {
721+
continue;
722+
}
723+
final HashInfo ret = newConnectionHashInfo(logger, md5hash, HashInfo.TYPE.MD5);
724+
/* Take first result */
725+
return ret;
726+
}
727+
}
711728
return null;
712729
}
713730

svn_trunk/src/jd/plugins/hoster/SendCm.java

Lines changed: 50 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,6 @@
4444
import org.jdownloader.gui.translate._GUI;
4545
import org.jdownloader.plugins.accounts.AccountBuilderInterface;
4646
import org.jdownloader.plugins.components.XFileSharingProBasic;
47-
import org.jdownloader.plugins.components.config.XFSConfigSendCm;
48-
import org.jdownloader.plugins.components.config.XFSConfigSendCm.LoginMode;
49-
import org.jdownloader.plugins.config.PluginJsonConfig;
50-
import org.jdownloader.plugins.controller.LazyPlugin;
5147
import org.jdownloader.plugins.controller.LazyPlugin.FEATURE;
5248
import org.jdownloader.scripting.JavaScriptEngineFactory;
5349

@@ -62,14 +58,13 @@
6258
import jd.plugins.Account.AccountType;
6359
import jd.plugins.AccountInfo;
6460
import jd.plugins.AccountInvalidException;
65-
import jd.plugins.DefaultEditAccountPanelAPIKeyLogin;
6661
import jd.plugins.DownloadLink;
6762
import jd.plugins.DownloadLink.AvailableStatus;
6863
import jd.plugins.HostPlugin;
6964
import jd.plugins.LinkStatus;
7065
import jd.plugins.PluginException;
7166

72-
@HostPlugin(revision = "$Revision: 51314 $", interfaceVersion = 3, names = {}, urls = {})
67+
@HostPlugin(revision = "$Revision: 51323 $", interfaceVersion = 3, names = {}, urls = {})
7368
public class SendCm extends XFileSharingProBasic {
7469
public SendCm(final PluginWrapper wrapper) {
7570
super(wrapper);
@@ -79,21 +74,6 @@ public SendCm(final PluginWrapper wrapper) {
7974
private static final String PROPERTY_ACCOUNT_FORCE_API_LOGIN = "force_api_login";
8075
private static final String PROPERTY_ACCOUNT_FORCE_WEBSITE_LOGIN = "force_website_login";
8176

82-
@Override
83-
public LazyPlugin.FEATURE[] getFeatures() {
84-
if (DebugMode.TRUE_IN_IDE_ELSE_FALSE) {
85-
final List<LazyPlugin.FEATURE> ret = new ArrayList<LazyPlugin.FEATURE>();
86-
if (requiresCookieLogin()) {
87-
ret.add(LazyPlugin.FEATURE.COOKIE_LOGIN_ONLY);
88-
} else {
89-
ret.add(LazyPlugin.FEATURE.COOKIE_LOGIN_OPTIONAL);
90-
}
91-
return ret.toArray(new LazyPlugin.FEATURE[0]);
92-
} else {
93-
return super.getFeatures();
94-
}
95-
}
96-
9777
/**
9878
* DEV NOTES XfileSharingProBasic Version SEE SUPER-CLASS<br />
9979
* mods: See overridden functions<br />
@@ -381,7 +361,40 @@ protected String regexAPIKey(final Browser br) {
381361
public AccountInfo fetchAccountInfo(final Account account) throws Exception {
382362
if (account.hasProperty(PROPERTY_ACCOUNT_FORCE_WEBSITE_LOGIN)) {
383363
return this.fetchAccountInfoWebsite(account);
384-
} else if (this.enableAccountApiOnlyMode() || account.hasProperty(PROPERTY_ACCOUNT_FORCE_API_LOGIN)) {
364+
} else if (account.hasProperty(PROPERTY_ACCOUNT_FORCE_API_LOGIN)) {
365+
return this.fetchAccountInfoAPI(this.br, account);
366+
} else if (this.looksLikeValidAPIKey(account.getPass())) {
367+
/* Auto mode e.g. headless login */
368+
try {
369+
logger.info("Attempting API login");
370+
/* Important for getAPIKeyFromAccount !! */
371+
account.setProperty(PROPERTY_ACCOUNT_apikey, account.getPass());
372+
final AccountInfo ai_api = this.fetchAccountInfoAPI(this.br, account);
373+
/* API login successful -> Always login via API with this account in the future */
374+
account.setProperty(PROPERTY_ACCOUNT_FORCE_API_LOGIN, true);
375+
// account.setProperty(PROPERTY_ACCOUNT_apikey, account.getPass());
376+
return ai_api;
377+
} catch (final InterruptedException ie1) {
378+
throw ie1;
379+
} catch (final Exception pe1) {
380+
logger.info("API login failed -> Trying website login");
381+
/* Remove property again as API login failed. */
382+
account.removeProperty(PROPERTY_ACCOUNT_apikey);
383+
try {
384+
final AccountInfo ai_website = this.fetchAccountInfoWebsite(account);
385+
/* Website login successful -> Always login via website with this account in the future */
386+
account.setProperty(PROPERTY_ACCOUNT_FORCE_WEBSITE_LOGIN, true);
387+
return ai_website;
388+
} catch (final InterruptedException ie2) {
389+
throw ie2;
390+
} catch (final PluginException pe2) {
391+
logger.log(pe2);
392+
logger.info("API login and website login failed -> Throwing API login exception");
393+
throw pe1;
394+
}
395+
}
396+
} else if (this.enableAccountApiOnlyMode()) {
397+
/* This should never happen (for this particular plugin). */
385398
return this.fetchAccountInfoAPI(this.br, account);
386399
} else {
387400
return this.fetchAccountInfoWebsite(account);
@@ -470,14 +483,15 @@ protected AccountInfo fetchAccountInfoAPI(final Browser br, final Account accoun
470483
ai.setUsedSpace(SizeFormatter.getSize(storage_used_bytesO.toString()));
471484
}
472485
}
473-
if (this.enableAccountApiOnlyMode() && !account.hasProperty(PROPERTY_ACCOUNT_FORCE_WEBSITE_LOGIN) && !StringUtils.isEmpty(email)) {
486+
if (!account.hasProperty(PROPERTY_ACCOUNT_FORCE_WEBSITE_LOGIN) && !StringUtils.isEmpty(email) && !StringUtils.equals(account.getUser(), email)) {
474487
/*
475488
* Each account is unique. Do not care what the user entered - trust what API returns! </br> This is not really important - more
476489
* visually so that something that makes sense is displayed to the user in his account managers' "Username" column!
477490
*/
491+
logger.info("User has entered API key into username field -> Correcting username to email: " + email);
478492
account.setUser(email);
479493
} else if (StringUtils.equals(account.getUser(), this.getAPIKeyFromAccount(account))) {
480-
logger.info("User has entered API key as username & password -> Set email as username");
494+
logger.info("User has entered API key as username & password -> Set email as username: " + email);
481495
account.setUser(email);
482496
}
483497
if (DebugMode.TRUE_IN_IDE_ELSE_FALSE) {
@@ -542,17 +556,6 @@ protected boolean supportsAPIMassLinkcheck() {
542556
}
543557
}
544558

545-
@Override
546-
protected boolean enableAccountApiOnlyMode() {
547-
// TODO: Try to remove this override
548-
final XFSConfigSendCm cfg = PluginJsonConfig.get(XFSConfigSendCm.class);
549-
if (cfg.getLoginMode() == LoginMode.API) {
550-
return true;
551-
} else {
552-
return false;
553-
}
554-
}
555-
556559
@Override
557560
protected boolean supportsAPISingleLinkcheck() {
558561
return looksLikeValidAPIKey(this.getAPIKey());
@@ -588,7 +591,7 @@ public boolean massLinkcheckerAPI(final DownloadLink[] urls, final String apikey
588591
index++;
589592
}
590593
}
591-
final ArrayList<DownloadLink> apiLinkcheckLinks = new ArrayList<DownloadLink>();
594+
final List<DownloadLink> apiLinkcheckLinks = new ArrayList<DownloadLink>();
592595
sb.delete(0, sb.capacity());
593596
for (final DownloadLink link : links) {
594597
try {
@@ -730,24 +733,19 @@ public boolean massLinkcheckerAPI(final DownloadLink[] urls, final String apikey
730733
}
731734

732735
@Override
733-
public Class<? extends XFSConfigSendCm> getConfigInterface() {
734-
return XFSConfigSendCm.class;
736+
protected boolean looksLikeValidAPIKey(final String str) {
737+
if (str == null) {
738+
return false;
739+
} else if (str.matches("^[a-z0-9]{20,}$")) {
740+
return true;
741+
} else {
742+
return false;
743+
}
735744
}
736745

737746
@Override
738747
public AccountBuilderInterface getAccountFactory(final InputChangedCallbackInterface callback) {
739-
if (DebugMode.TRUE_IN_IDE_ELSE_FALSE) {
740-
/* 2025-08-07: Testing */
741-
return new SendCmAccountFactory(callback, this);
742-
} else {
743-
/* Website login */
744-
final XFSConfigSendCm cfg = PluginJsonConfig.get(XFSConfigSendCm.class);
745-
if (cfg.getLoginMode() == LoginMode.API || cfg.getLoginMode() == LoginMode.AUTO || cfg.getLoginMode() == LoginMode.DEFAULT) {
746-
return new DefaultEditAccountPanelAPIKeyLogin(callback, this);
747-
} else {
748-
return super.getAccountFactory(callback);
749-
}
750-
}
748+
return new SendCmAccountFactory(callback, this);
751749
}
752750

753751
public static class SendCmAccountFactory extends MigPanel implements AccountBuilderInterface {
@@ -1014,23 +1012,14 @@ public boolean validateInputs() {
10141012

10151013
@Override
10161014
public Account getAccount() {
1017-
if (plg.looksLikeValidAPIKey(this.getApikey())) {
1015+
final String apikey = this.getApikey();
1016+
if (plg.looksLikeValidAPIKey(apikey)) {
10181017
/* Use API key as password */
1019-
final String apikey = this.getApikey();
10201018
final Account account = new Account(getUsername(), apikey);
10211019
account.setProperty(PROPERTY_ACCOUNT_apikey, apikey);
10221020
account.setProperty(PROPERTY_ACCOUNT_FORCE_API_LOGIN, true);
10231021
return account;
10241022
} else {
1025-
/**
1026-
* Workaround for users who set this setting to API but login via website/free-account <br>
1027-
* The API login mode is still needed for headless installations! <br>
1028-
*
1029-
* This workaround is required so that PluginForHost.validateLogins will not fail due to API key validation when
1030-
* enableAccountApiOnlyMode() returns true.
1031-
*/
1032-
final XFSConfigSendCm cfg = PluginJsonConfig.get(XFSConfigSendCm.class);
1033-
cfg.setLoginMode(LoginMode.DEFAULT);
10341023
final Account account = new Account(getUsername(), getPassword());
10351024
account.setProperty(PROPERTY_ACCOUNT_FORCE_WEBSITE_LOGIN, true);
10361025
return account;

svn_trunk/src/jd/plugins/hoster/TerabytezOrg.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.util.List;
2121
import java.util.regex.Pattern;
2222

23+
import org.jdownloader.plugins.components.XFileSharingProBasic;
24+
2325
import jd.PluginWrapper;
2426
import jd.http.Browser;
2527
import jd.parser.Regex;
@@ -30,9 +32,7 @@
3032
import jd.plugins.HostPlugin;
3133
import jd.plugins.PluginException;
3234

33-
import org.jdownloader.plugins.components.XFileSharingProBasic;
34-
35-
@HostPlugin(revision = "$Revision: 50268 $", interfaceVersion = 3, names = {}, urls = {})
35+
@HostPlugin(revision = "$Revision: 51318 $", interfaceVersion = 3, names = {}, urls = {})
3636
public class TerabytezOrg extends XFileSharingProBasic {
3737
public TerabytezOrg(final PluginWrapper wrapper) {
3838
super(wrapper);
@@ -192,4 +192,33 @@ public String getFUIDFromURL(final DownloadLink link) {
192192
return getFUID(link, type);
193193
}
194194
}
195+
// @Override
196+
// protected String getNormalizedDownloadURL(final DownloadLink link) {
197+
// final String url = super.getNormalizedDownloadURL(link);
198+
// final String url_without_filename = new Regex(url, "^(https?://[^/]+/[a-z0-9]{12})").getMatch(0);
199+
// if (url_without_filename != null) {
200+
// /*
201+
// * 2025-08-12: Small workaround to allow "massLinkcheckerWebsite" to work, else it may fail with error "Filename don't match!".
202+
// */
203+
// return url_without_filename;
204+
// } else {
205+
// return url;
206+
// }
207+
// }
208+
209+
@Override
210+
protected String getContentURL(final DownloadLink link) {
211+
final String url = super.getContentURL(link);
212+
final String url_without_filename = new Regex(url, "^(https?://[^/]+/[a-z0-9]{12})").getMatch(0);
213+
if (url_without_filename != null) {
214+
/**
215+
* 2025-08-12: Small workaround to allow "massLinkcheckerWebsite" to work, else it may fail with error "Filename don't match!".
216+
* <br>
217+
* More details: https://board.jdownloader.org/showthread.php?p=550013#post550013
218+
*/
219+
return url_without_filename;
220+
} else {
221+
return url;
222+
}
223+
}
195224
}

0 commit comments

Comments
 (0)