From 028dde05b4b8e9154ecd1f5fccb70dabeea7b649 Mon Sep 17 00:00:00 2001 From: updating-bot Date: Tue, 14 Jan 2025 05:29:25 +0000 Subject: [PATCH] mirroring bot - 2025/01/14 --- .../downloadcontroller/DownloadSession.java | 25 +- .../orderpanel/HosterOrderPanel.java | 10 +- .../orderpanel/NewRuleAction.java | 4 +- .../pluginsettings/PluginSettingsPanel.java | 23 +- svn_trunk/src/jd/plugins/PluginForHost.java | 2 +- .../plugins/decrypter/ArchiveOrgCrawler.java | 32 +- .../plugins/decrypter/CivitaiComCrawler.java | 33 +- .../src/jd/plugins/decrypter/HdencodeOrg.java | 70 ++-- .../plugins/decrypter/MissavComCrawler.java | 4 +- .../decrypter/StreamrecorderIoCrawler.java | 360 ++++++++++++++++++ .../decrypter/SwisstransferComFolder.java | 107 +++++- .../plugins/decrypter/VipergirlsToBoard.java | 16 +- .../jd/plugins/download/raf/ChunkRange.java | 13 +- .../src/jd/plugins/hoster/CivitaiCom.java | 11 +- .../KernelVideoSharingComBabestubeCom.java | 4 +- .../KernelVideoSharingComThepornbangCom.java | 113 +++--- .../hoster/KernelVideoSharingComV2.java | 7 +- svn_trunk/src/jd/plugins/hoster/KwikCx.java | 103 +++-- .../src/jd/plugins/hoster/ModsfireCom.java | 164 ++++++-- .../src/jd/plugins/hoster/MydaddyCc.java | 7 +- svn_trunk/src/jd/plugins/hoster/SeedrCc.java | 6 +- .../jd/plugins/hoster/StreamrecorderIo.java | 311 +++++++++++++++ .../src/jd/plugins/hoster/TeraboxCom.java | 4 +- svn_trunk/src/jd/plugins/hoster/XbabeCom.java | 11 +- .../container/InternetShortcut.java | 21 +- .../hosterrule/HosterRuleController.java | 38 +- .../components/config/CivitaiComConfig.java | 9 + .../components/config/MissavComConfig.java | 2 +- .../controller/host/HostPluginController.java | 20 +- .../controller/host/LazyHostPlugin.java | 13 +- .../controller/host/LazyHostPluginCache.java | 32 +- svn_utils/libs/publicsuffix-list.dep.json | 99 ++++- .../jna/windows/wmi/tests/WMITests.java | 2 + .../appwork/remoteapi/test/RemoteAPITest.java | 15 +- .../org/appwork/storage/config/test/Test.java | 21 +- .../test/WeakValueProviderBridgeTest.java | 10 +- .../mapper/test/SpecialMappers.java | 2 + .../tests/RemoteAPI1InterfaceValidator.java | 2 + .../testframework/PostBuildRunner.java | 40 +- .../org/appwork/utils/awfc/test/AWFCTest.java | 2 + .../utils/crypto/tests/AWSignTest.java | 9 +- .../appwork/utils/net/effective_tld_names.dat | 87 +++-- .../reflection/tests/CompiledTypeTests.java | 2 + .../utils/swing/tests/CheckGraphicsProxy.java | 2 + .../appwork/utils/swing/tests/EDTTest.java | 2 + .../org/appwork/utils/test/LEB128Test.java | 2 + .../zip/tests/CompressedEntriesIndexTest.java | 2 + .../utils/zip/tests/SignedZipsTest.java | 2 + 48 files changed, 1506 insertions(+), 370 deletions(-) create mode 100644 svn_trunk/src/jd/plugins/decrypter/StreamrecorderIoCrawler.java create mode 100644 svn_trunk/src/jd/plugins/hoster/StreamrecorderIo.java diff --git a/svn_trunk/src/jd/controlling/downloadcontroller/DownloadSession.java b/svn_trunk/src/jd/controlling/downloadcontroller/DownloadSession.java index 8fe4aea2..45fbb131 100644 --- a/svn_trunk/src/jd/controlling/downloadcontroller/DownloadSession.java +++ b/svn_trunk/src/jd/controlling/downloadcontroller/DownloadSession.java @@ -563,7 +563,7 @@ public AccountCache getAccountCache(final DownloadLink link) { cachedGroups.add(hosterFreeGroup); } /* free(no account) */ - final CachedAccount noAccount = new CachedAccount(host, null, defaulPlugin); + CachedAccount noAccount = new CachedAccount(host, null, defaulPlugin); final boolean addNoAccountGroup; if (numberofPremiumAccounts > 0) { /* At least one premium account is available -> Do not allow non-account download. */ @@ -575,11 +575,26 @@ public AccountCache getAccountCache(final DownloadLink link) { /* Allow download without account */ addNoAccountGroup = true; } - if (addNoAccountGroup) { - final CachedAccountGroup freeGroup = new CachedAccountGroup(Rules.ORDER); - freeGroup.add(noAccount); - cachedGroups.add(freeGroup); + if (!addNoAccountGroup) { + noAccount = new CachedAccount(host, null, defaulPlugin) { + final List finalCachedGroups = new ArrayList(cachedGroups); + + @Override + public boolean canHandle(DownloadLink link) throws Exception { + for (final CachedAccountGroup cachedGroup : finalCachedGroups) { + for (final CachedAccount cachedAccount : cachedGroup) { + if (cachedAccount.canHandle(link)) { + return false; + } + } + } + return super.canHandle(link); + } + }; } + final CachedAccountGroup freeGroup = new CachedAccountGroup(Rules.ORDER); + freeGroup.add(noAccount); + cachedGroups.add(freeGroup); ret = new AccountCache(cachedGroups); } } diff --git a/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/accountmanager/orderpanel/HosterOrderPanel.java b/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/accountmanager/orderpanel/HosterOrderPanel.java index ebd7ea13..f151ddec 100644 --- a/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/accountmanager/orderpanel/HosterOrderPanel.java +++ b/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/accountmanager/orderpanel/HosterOrderPanel.java @@ -118,15 +118,7 @@ public void onRuleAdded(AccountUsageRule parameter) { if (!isShown()) { return; } - if (HosterRuleController.getInstance().showEditPanel(parameter)) { - updateTable(); - } else { - /** - * User closed/cancelled edit rule dialog.
- * Remove rule and don't refresh table so it looks as if this rule has never been added. - */ - HosterRuleController.getInstance().remove(parameter); - } + updateTable(); } @Override diff --git a/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/accountmanager/orderpanel/NewRuleAction.java b/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/accountmanager/orderpanel/NewRuleAction.java index f5e1126c..922c3575 100644 --- a/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/accountmanager/orderpanel/NewRuleAction.java +++ b/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/accountmanager/orderpanel/NewRuleAction.java @@ -50,7 +50,9 @@ public void actionPerformed(ActionEvent e) { /* Add rule for selected item. */ final AccountUsageRule rule = new AccountUsageRule(di.getTld()); rule.setEnabled(true); - hrc.add(rule); + if (HosterRuleController.getInstance().validateRule(rule) && HosterRuleController.getInstance().showEditPanel(rule)) { + hrc.add(rule); + } } } catch (DialogClosedException e1) { e1.printStackTrace(); diff --git a/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/pluginsettings/PluginSettingsPanel.java b/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/pluginsettings/PluginSettingsPanel.java index da71116c..2b613b92 100644 --- a/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/pluginsettings/PluginSettingsPanel.java +++ b/svn_trunk/src/jd/gui/swing/jdgui/views/settings/panels/pluginsettings/PluginSettingsPanel.java @@ -19,16 +19,6 @@ import javax.swing.Scrollable; import javax.swing.SwingUtilities; -import jd.gui.swing.jdgui.JDGui; -import jd.gui.swing.jdgui.interfaces.SwitchPanel; -import jd.gui.swing.jdgui.views.settings.components.SettingsComponent; -import jd.gui.swing.jdgui.views.settings.components.StateUpdateListener; -import jd.gui.swing.jdgui.views.settings.sidebar.AddonConfig; -import jd.plugins.Account; -import jd.plugins.Plugin; -import jd.plugins.PluginConfigPanelNG; -import net.miginfocom.swing.MigLayout; - import org.appwork.exceptions.WTFException; import org.appwork.storage.config.JsonConfig; import org.appwork.swing.MigPanel; @@ -51,6 +41,7 @@ import org.jdownloader.images.AbstractIcon; import org.jdownloader.logging.LogController; import org.jdownloader.plugins.controller.LazyPlugin; +import org.jdownloader.plugins.controller.LazyPlugin.FEATURE; import org.jdownloader.plugins.controller.UpdateRequiredClassNotFoundException; import org.jdownloader.plugins.controller.crawler.CrawlerPluginController; import org.jdownloader.plugins.controller.crawler.LazyCrawlerPlugin; @@ -58,6 +49,16 @@ import org.jdownloader.plugins.controller.host.LazyHostPlugin; import org.jdownloader.settings.GraphicalUserInterfaceSettings; +import jd.gui.swing.jdgui.JDGui; +import jd.gui.swing.jdgui.interfaces.SwitchPanel; +import jd.gui.swing.jdgui.views.settings.components.SettingsComponent; +import jd.gui.swing.jdgui.views.settings.components.StateUpdateListener; +import jd.gui.swing.jdgui.views.settings.sidebar.AddonConfig; +import jd.plugins.Account; +import jd.plugins.Plugin; +import jd.plugins.PluginConfigPanelNG; +import net.miginfocom.swing.MigLayout; + public class PluginSettingsPanel extends JPanel implements SettingsComponent, ActionListener { /** * @@ -276,7 +277,7 @@ private void fill() { public List> fillModel() { final List> lst = new ArrayList>(); for (final LazyHostPlugin plg : HostPluginController.getInstance().list()) { - if (plg.isHasConfig() || plg.isPremium()) { + if (plg.isHasConfig() || (plg.isPremium() && (plg.isHasPremiumConfig() || plg.hasFeature(FEATURE.MULTIHOST)))) { lst.add(plg); } } diff --git a/svn_trunk/src/jd/plugins/PluginForHost.java b/svn_trunk/src/jd/plugins/PluginForHost.java index 0ec70d01..8961651b 100644 --- a/svn_trunk/src/jd/plugins/PluginForHost.java +++ b/svn_trunk/src/jd/plugins/PluginForHost.java @@ -854,7 +854,7 @@ public SubConfiguration getPluginConfig() { } protected PluginConfigPanelNG createConfigPanel() { - if (getConfigInterface() == null && !isPremiumEnabled()) { + if (getConfigInterface() == null && (!isPremiumEnabled() || getAccountConfigInterface(null) == null)) { return null; } final PluginConfigPanelNG ret = new PluginConfigPanelNG() { diff --git a/svn_trunk/src/jd/plugins/decrypter/ArchiveOrgCrawler.java b/svn_trunk/src/jd/plugins/decrypter/ArchiveOrgCrawler.java index 44ba1aad..b47546f6 100644 --- a/svn_trunk/src/jd/plugins/decrypter/ArchiveOrgCrawler.java +++ b/svn_trunk/src/jd/plugins/decrypter/ArchiveOrgCrawler.java @@ -73,7 +73,7 @@ import jd.plugins.download.HashInfo; import jd.plugins.hoster.ArchiveOrg; -@DecrypterPlugin(revision = "$Revision: 50222 $", interfaceVersion = 2, names = { "archive.org", "subdomain.archive.org" }, urls = { "https?://(?:www\\.)?archive\\.org/((?:details|download|stream|embed)/.+|search\\?query=.+)", "https?://[^/]+\\.archive\\.org/view_archive\\.php\\?archive=[^\\&]+(?:\\&file=[^\\&]+)?" }) +@DecrypterPlugin(revision = "$Revision: 50435 $", interfaceVersion = 2, names = { "archive.org", "subdomain.archive.org" }, urls = { "https?://(?:www\\.)?archive\\.org/((?:details|download|stream|embed)/.+|search\\?query=.+)", "https?://[^/]+\\.archive\\.org/view_archive\\.php\\?archive=[^\\&]+(?:\\&file=[^\\&]+)?" }) public class ArchiveOrgCrawler extends PluginForDecrypt { public ArchiveOrgCrawler(PluginWrapper wrapper) { super(wrapper); @@ -874,7 +874,8 @@ private ArrayList crawlMetadataJsonV2(final String identifier, fin final boolean crawlMetadataFiles = cfg.isFileCrawlerCrawlMetadataFiles(); final boolean crawlThumbnails = cfg.isFileCrawlerCrawlThumbnails(); final List skippedItemsFilepaths = new ArrayList(); - String totalLengthSecondsStr = null; + String totalLengthSecondsOriginalStr = null; + String totalLengthSecondsDerivativeStr = null; Object desiredFileArchiveFileCount = null; final HashSet originalFilenamesDupeCollection = new HashSet(); /** Restricted access usually means that original files are not downloadable or only DRM protected / encrypted items exist. */ @@ -947,8 +948,14 @@ private ArrayList crawlMetadataJsonV2(final String identifier, fin itemMapping.put(name, file); if (isOriginal) { originalMapping.put(name, null); + if (totalLengthSecondsOriginalStr == null) { + totalLengthSecondsOriginalStr = (String) filemap.get("length"); + } } else if ("derivative".equals(source) && originalO instanceof String) { originalMapping.put(name, originalO.toString()); + if (totalLengthSecondsDerivativeStr == null && StringUtils.endsWithCaseInsensitive(name, ".mp4")) { + totalLengthSecondsDerivativeStr = (String) filemap.get("length"); + } } file.setProperty(ArchiveOrg.PROPERTY_FILENAME, filename); file.setProperty(ArchiveOrg.PROPERTY_ARTIST, filemap.get("artist")); // Optional field @@ -1009,9 +1016,6 @@ private ArrayList crawlMetadataJsonV2(final String identifier, fin desiredFileArchiveFileCount = filemap.get("filecount"); singleDesiredFile2 = file; } - if (isOriginal && totalLengthSecondsStr == null) { - totalLengthSecondsStr = (String) filemap.get("length"); - } /* Add items to list of all results. */ /* Check some skip conditions */ if (isOldVersion) { @@ -1158,14 +1162,22 @@ private ArrayList crawlMetadataJsonV2(final String identifier, fin } } else if (StringUtils.equalsIgnoreCase(mediatype, "movies") && identifierDotMp4Exists) { /* Video "playlist" handling */ - if (totalLengthSecondsStr == null || !totalLengthSecondsStr.matches("\\d+(\\.\\d+)?")) { + if (totalLengthSecondsOriginalStr == null || !totalLengthSecondsOriginalStr.matches("\\d+(\\.\\d+)?")) { /* This should never happen */ logger.warning("Detected mediatype 'movies' item but failed to determine video playtime"); /* Return original files */ return selectedItems; } final int secondsPerSegment = 60; - final double totalLengthSeconds = Double.parseDouble(totalLengthSecondsStr); + double totalLengthSeconds = Double.parseDouble(totalLengthSecondsOriginalStr); + if (totalLengthSeconds == 0 && (totalLengthSecondsDerivativeStr != null && totalLengthSecondsDerivativeStr.matches("\\d+(\\.\\d+)?"))) { + /** + * Edge case: Looks like archive.org original data may be corrupt sometimes, prividing "0.00" as length value.
+ * Example: https://archive.org/details/KNTV_20200205_073400_The_Tonight_Show_Starring_Jimmy_Fallon + */ + logger.info("Failed to find video length via info from original item -> Fallback to length from derivative -> " + totalLengthSecondsDerivativeStr); + totalLengthSeconds = Double.parseDouble(totalLengthSecondsDerivativeStr); + } final int numberofVideoSegments; final double remainingSeconds = totalLengthSeconds % secondsPerSegment; if (remainingSeconds == 0) { @@ -1174,6 +1186,12 @@ private ArrayList crawlMetadataJsonV2(final String identifier, fin /* Uneven total runtime -> Last segment will be shorter than the others. */ numberofVideoSegments = (int) ((totalLengthSeconds / secondsPerSegment) + 1); } + if (totalLengthSeconds == 0) { + /* This should never happen */ + logger.warning("Detected mediatype 'movies' item but determined playtime of 0 seconds is unplausible"); + /* Return original files */ + return selectedItems; + } int offsetSeconds = 0; /* * Video can't be officially downloaded but it can be streamed in segments of X seconds each -> Generate those stream-links diff --git a/svn_trunk/src/jd/plugins/decrypter/CivitaiComCrawler.java b/svn_trunk/src/jd/plugins/decrypter/CivitaiComCrawler.java index f5a1cfa9..6f7601ff 100644 --- a/svn_trunk/src/jd/plugins/decrypter/CivitaiComCrawler.java +++ b/svn_trunk/src/jd/plugins/decrypter/CivitaiComCrawler.java @@ -21,6 +21,12 @@ import java.util.List; import java.util.Map; +import org.appwork.storage.JSonStorage; +import org.appwork.storage.TypeRef; +import org.appwork.utils.parser.UrlQuery; +import org.jdownloader.plugins.components.config.CivitaiComConfig; +import org.jdownloader.plugins.config.PluginJsonConfig; + import jd.PluginWrapper; import jd.controlling.ProgressController; import jd.http.Browser; @@ -39,13 +45,7 @@ import jd.plugins.hoster.CivitaiCom; import jd.plugins.hoster.DirectHTTP; -import org.appwork.storage.JSonStorage; -import org.appwork.storage.TypeRef; -import org.appwork.utils.parser.UrlQuery; -import org.jdownloader.plugins.components.config.CivitaiComConfig; -import org.jdownloader.plugins.config.PluginJsonConfig; - -@DecrypterPlugin(revision = "$Revision: 50389 $", interfaceVersion = 3, names = {}, urls = {}) +@DecrypterPlugin(revision = "$Revision: 50439 $", interfaceVersion = 3, names = {}, urls = {}) @PluginDependencies(dependencies = { CivitaiCom.class }) public class CivitaiComCrawler extends PluginForDecrypt { public CivitaiComCrawler(PluginWrapper wrapper) { @@ -94,6 +94,7 @@ public ArrayList decryptIt(final CryptedLink param, ProgressContro final String itemType = urlregex.getMatch(0); final String itemID = urlregex.getMatch(1); final CivitaiCom hosterplugin = (CivitaiCom) this.getNewPluginForHostInstance(this.getHost()); + final CivitaiComConfig cfg = PluginJsonConfig.get(CivitaiComConfig.class); /* * Using API: https://github.com/civitai/civitai/wiki/REST-API-Reference, * https://wiki.civitai.com/wiki/Civitai_API#GET_/api/v1/images @@ -137,9 +138,14 @@ public ArrayList decryptIt(final CryptedLink param, ProgressContro fp.setPackageKey("civitai://post/" + itemID); for (final Map image : images) { final String imageurl = image.get("url").toString(); - final String tempName = getFileNameFromURL(new URL(imageurl)); final DownloadLink link = this.createDownloadlink(br.getURL("/images/" + image.get("id")).toExternalForm()); link._setFilePackage(fp); + final String tempName; + if (cfg.isUseIndexIDForImageFilename()) { + tempName = image.get("id").toString() + ".jpg"; + } else { + tempName = getFileNameFromURL(new URL(imageurl)); + } if (tempName != null) { link.setName(tempName); } @@ -147,7 +153,6 @@ public ArrayList decryptIt(final CryptedLink param, ProgressContro ret.add(link); } } else if (itemType.equals("user")) { - final CivitaiComConfig cfg = PluginJsonConfig.get(CivitaiComConfig.class); final FilePackage fp = FilePackage.getInstance(); fp.setName(itemID); fp.setPackageKey("civitai://user/" + itemID); @@ -156,7 +161,8 @@ public ArrayList decryptIt(final CryptedLink param, ProgressContro /* 2024-07-17: use small limit/pagination size to avoid timeout issues */ /** * 2024-07-18: About the "nsfw" parameter: According to their docs, without nsfw parameter, all items will be rerturned but that - * is wrong --> Wrong API docs or bug in API.
Only with the nsfw parameter set to "X", all items will be returned. + * is wrong --> Wrong API docs or bug in API.
+ * Only with the nsfw parameter set to "X", all items will be returned. */ final int maxItemsPerPage = cfg.getProfileCrawlerMaxPaginationItems(); final int paginationSleepMillis = cfg.getProfileCrawlerPaginationSleepMillis(); @@ -182,7 +188,6 @@ public ArrayList decryptIt(final CryptedLink param, ProgressContro int numberofNewItems = 0; for (final Map image : images) { final String imageurl = image.get("url").toString(); - final String tempName = getFileNameFromURL(new URL(imageurl)); final String imageid = image.get("id").toString(); if (!dupes.add(imageid)) { continue; @@ -190,6 +195,12 @@ public ArrayList decryptIt(final CryptedLink param, ProgressContro numberofNewItems++; final DownloadLink link = this.createDownloadlink(br.getURL("/images/" + imageid).toExternalForm()); link._setFilePackage(fp); + final String tempName; + if (cfg.isUseIndexIDForImageFilename()) { + tempName = imageid + ".jpg"; + } else { + tempName = getFileNameFromURL(new URL(imageurl)); + } if (tempName != null) { link.setName(tempName); } diff --git a/svn_trunk/src/jd/plugins/decrypter/HdencodeOrg.java b/svn_trunk/src/jd/plugins/decrypter/HdencodeOrg.java index ac3b7fb7..f252cf46 100644 --- a/svn_trunk/src/jd/plugins/decrypter/HdencodeOrg.java +++ b/svn_trunk/src/jd/plugins/decrypter/HdencodeOrg.java @@ -34,7 +34,7 @@ import jd.plugins.PluginException; import jd.plugins.PluginForDecrypt; -@DecrypterPlugin(revision = "$Revision: 50407 $", interfaceVersion = 3, names = {}, urls = {}) +@DecrypterPlugin(revision = "$Revision: 50430 $", interfaceVersion = 3, names = {}, urls = {}) public class HdencodeOrg extends PluginForDecrypt { public HdencodeOrg(PluginWrapper wrapper) { super(wrapper); @@ -80,35 +80,47 @@ public ArrayList decryptIt(final CryptedLink param, ProgressContro if (br.getHttpConnection().getResponseCode() == 404) { throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND); } - final Form captchaform = br.getFormByRegex(".*content-protector-access-form.*"); - if (captchaform == null) { - throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); - } - /* Add special values to Form - without them, captcha will not be accepted (in browser, js needs to be active for this to work). */ - final String[][] specialFormKeyValuePairs = br.getRegex("data\\.data\\.append\\(\"([^\"]+)\", \"([^\"]+)\"\\);").getMatches(); - if (specialFormKeyValuePairs == null || specialFormKeyValuePairs.length == 0) { - throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); - } - for (final String[] keyValuePair : specialFormKeyValuePairs) { - captchaform.put(Encoding.urlEncode(keyValuePair[0]), Encoding.urlEncode(keyValuePair[1])); - } - final CaptchaHelperCrawlerPluginRecaptchaV2 helper; - if (br.containsHTML("\"version\"\\s*:\\s*\"(invisible|v3)")) { - /* Invisible reCaptchaV2 */ - helper = new CaptchaHelperCrawlerPluginRecaptchaV2(this, br) { - public TYPE getType() { - return TYPE.INVISIBLE; - } - }; - } else { - /* reCaptchaV2 auto handling */ - helper = new CaptchaHelperCrawlerPluginRecaptchaV2(this, br); - } - if (helper.getSiteKey() != null) { - captchaform.put("g-recaptcha-response", helper.getToken()); + int maxCaptchaForm = 3; + String[] htmls = null; + while (maxCaptchaForm-- >= 0) { + final Form captchaform = br.getFormByRegex(".*content-protector-access-form.*"); + if (captchaform == null) { + break; + } + if (isAbort()) { + return ret; + } + /* + * Add special values to Form - without them, captcha will not be accepted (in browser, js needs to be active for this to work). + */ + final String[][] specialFormKeyValuePairs = br.getRegex("data\\.data\\.append\\(\"([^\"]+)\", \"([^\"]+)\"\\);").getMatches(); + if (specialFormKeyValuePairs == null || specialFormKeyValuePairs.length == 0) { + throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); + } + for (final String[] keyValuePair : specialFormKeyValuePairs) { + captchaform.put(Encoding.urlEncode(keyValuePair[0]), Encoding.urlEncode(keyValuePair[1])); + } + final CaptchaHelperCrawlerPluginRecaptchaV2 helper; + if (br.containsHTML("\"version\"\\s*:\\s*\"(invisible|v3)")) { + /* Invisible reCaptchaV2 */ + helper = new CaptchaHelperCrawlerPluginRecaptchaV2(this, br) { + public TYPE getType() { + return TYPE.INVISIBLE; + } + }; + } else { + /* reCaptchaV2 auto handling */ + helper = new CaptchaHelperCrawlerPluginRecaptchaV2(this, br); + } + if (helper.getSiteKey() != null) { + captchaform.put("g-recaptcha-response", helper.getToken()); + } + br.submitForm(captchaform); + htmls = br.getRegex("
(.*?)
").getColumn(0); + if (htmls != null && htmls.length > 0) { + break; + } } - br.submitForm(captchaform); - final String[] htmls = br.getRegex("
(.*?)
").getColumn(0); if (htmls == null || htmls.length == 0) { /* This should never happen. */ logger.warning("Somehow wrong captcha or plugin broken"); diff --git a/svn_trunk/src/jd/plugins/decrypter/MissavComCrawler.java b/svn_trunk/src/jd/plugins/decrypter/MissavComCrawler.java index fe68f012..3cf74ff2 100644 --- a/svn_trunk/src/jd/plugins/decrypter/MissavComCrawler.java +++ b/svn_trunk/src/jd/plugins/decrypter/MissavComCrawler.java @@ -29,7 +29,7 @@ import jd.plugins.PluginForDecrypt; import jd.plugins.hoster.MissavCom; -@DecrypterPlugin(revision = "$Revision: 48809 $", interfaceVersion = 3, names = {}, urls = {}) +@DecrypterPlugin(revision = "$Revision: 50430 $", interfaceVersion = 3, names = {}, urls = {}) public class MissavComCrawler extends PluginForDecrypt { public MissavComCrawler(PluginWrapper wrapper) { super(wrapper); @@ -45,7 +45,7 @@ public Browser createNewBrowserInstance() { public static List getPluginDomains() { final List ret = new ArrayList(); // each entry in List will result in one PluginForDecrypt, Plugin.getHost() will return String[0]->main domain - ret.add(new String[] { "missav.com" }); + ret.add(new String[] { "missav.ws", "missav.com" }); return ret; } diff --git a/svn_trunk/src/jd/plugins/decrypter/StreamrecorderIoCrawler.java b/svn_trunk/src/jd/plugins/decrypter/StreamrecorderIoCrawler.java new file mode 100644 index 00000000..1c86ecbc --- /dev/null +++ b/svn_trunk/src/jd/plugins/decrypter/StreamrecorderIoCrawler.java @@ -0,0 +1,360 @@ +//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 . +package jd.plugins.decrypter; + +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.appwork.storage.TypeRef; +import org.appwork.utils.StringUtils; +import org.appwork.utils.parser.UrlQuery; + +import jd.PluginWrapper; +import jd.controlling.AccountController; +import jd.controlling.ProgressController; +import jd.http.Browser; +import jd.parser.Regex; +import jd.plugins.Account; +import jd.plugins.AccountRequiredException; +import jd.plugins.CryptedLink; +import jd.plugins.DecrypterPlugin; +import jd.plugins.DecrypterRetryException; +import jd.plugins.DecrypterRetryException.RetryReason; +import jd.plugins.DownloadLink; +import jd.plugins.FilePackage; +import jd.plugins.LinkStatus; +import jd.plugins.PluginDependencies; +import jd.plugins.PluginException; +import jd.plugins.PluginForDecrypt; +import jd.plugins.hoster.DirectHTTP; +import jd.plugins.hoster.StreamrecorderIo; + +@DecrypterPlugin(revision = "$Revision: 50439 $", interfaceVersion = 3, names = {}, urls = {}) +@PluginDependencies(dependencies = { StreamrecorderIo.class }) +public class StreamrecorderIoCrawler extends PluginForDecrypt { + public StreamrecorderIoCrawler(PluginWrapper wrapper) { + super(wrapper); + } + + @Override + public Browser createNewBrowserInstance() { + final Browser br = super.createNewBrowserInstance(); + br.setFollowRedirects(true); + return br; + } + + public static List getPluginDomains() { + return StreamrecorderIo.getPluginDomains(); + } + + 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 pluginDomains) { + final List ret = new ArrayList(); + for (final String[] domains : pluginDomains) { + ret.add("https?://(?:www\\.)?" + buildHostsPatternPart(domains) + "(/userrecordings(/(recording|playlist)/\\d+)?|/clip/[^/\\?#]+)"); + } + return ret.toArray(new String[0]); + } + + @Override + public ArrayList decryptIt(final CryptedLink param, ProgressController progress) throws Exception { + final Account account = AccountController.getInstance().getValidAccount(this.getHost()); + return crawlAllAccountRecordings(param, account); + } + + private StreamrecorderIo hosterplugin = null; + + @Override + public void clean() { + hosterplugin = null; + super.clean(); + } + + public ArrayList crawlAllAccountRecordings(final CryptedLink param, final Account account) throws Exception { + if (account == null) { + throw new AccountRequiredException(); + } + hosterplugin = (StreamrecorderIo) this.getNewPluginForHostInstance(this.getHost()); + hosterplugin.login(account, false); + final ArrayList ret = new ArrayList(); + if (param.getCryptedUrl().matches("(?i).*/clip/.+")) { + br.getPage(param.getCryptedUrl()); + if (br.getHttpConnection().getResponseCode() == 404 || br.containsHTML("\\s*Error 404")) { + throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND); + } + final String directurl = br.getRegex("<meta property=\"og:video\" content=\"(.*?)\"").getMatch(0); + final String video_Resolution_height = br.getRegex("<meta property=\"og:video:height\" content=\"(\\d+)\"").getMatch(0); + final String recordingID = br.getRegex("/recording/(\\d+)").getMatch(0); + final String username = br.getRegex("<meta property=\"og:video:tag\" content=\"(.*?) (clip|vod|stream|download)\">").getMatch(0); + final String clipID = new Regex(param.getCryptedUrl(), "/clip/([^/\\?#]+)").getMatch(0); + final String userID = br.getRegex("/img/profile_image/(\\d+)").getMatch(0); + final DownloadLink video = this.createDownloadlink(directurl); + video.setDefaultPlugin(hosterplugin); + video.setHost(getHost()); + video.setProperty(StreamrecorderIo.PROPERTY_user_id, userID); + video.setProperty(StreamrecorderIo.PROPERTY_username, username); + video.setProperty(StreamrecorderIo.PROPERTY_record_id, recordingID); + video.setProperty(StreamrecorderIo.PROPERTY_clip_id, clipID); + video.setProperty(StreamrecorderIo.PROPERTY_video_resolution_height, video_Resolution_height); + video.setProperty(StreamrecorderIo.PROPERTY_directurl, directurl); + video.setProperty(StreamrecorderIo.PROPERTY_type, StreamrecorderIo.PROPERTY_TYPE_CLIP); + video.setProperty(StreamrecorderIo.PROPERTY_downloadable_via_account_id, account.getUser()); + final String filename = getFileNameFromURL(new URL(directurl)); + if (filename != null) { + video.setFinalFileName(filename.replace("+", " ")); + } + video.setAvailable(true); + ret.add(video); + return ret; + } + if (param.getCryptedUrl().matches("(?i).*/playlist/\\d+")) { + br.getPage(param.getCryptedUrl()); + if (br.getHttpConnection().getResponseCode() == 404 || br.containsHTML("<title>\\s*Error 404")) { + throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND); + } + final String recordingIDs[] = br.getRegex("loadModalPlayer\\((\\d+)").getColumn(0); + final String displayName = br.getRegex("<span class\\s*=\\s*\"user-name[^\"]*\"\\s*>\\s*<span>\\s*(.*?)\\s*</span>").getMatch(0); + if (displayName != null) { + String title = br.getRegex("</span>\\s*([^>]*?\\s*Stream\\s*from\\s*<span sr-date-time.*?</span>\\s*to\\s*<span sr-date-time[^<]*</span>)\\s*</?span").getMatch(0); + final List<DownloadLink> results = findUserRecordings(account, br.cloneBrowser(), displayName, new HashSet<String>(Arrays.asList(recordingIDs))); + if (results.size() > 0) { + ret.addAll(results); + if (title != null) { + title = title.replaceAll("<span[^>]*>", "").replaceAll("</span>", ""); + final FilePackage fp = FilePackage.getInstance(); + fp.setName(title); + fp.addLinks(ret); + } + return ret; + } + } + for (String recordingID : recordingIDs) { + ret.add(createDownloadlink("https://streamrecorder.io/userrecordings/recording/" + recordingID)); + } + return ret; + } + if (param.getCryptedUrl().matches("(?i).*/recording/\\d+")) { + final String recordingID = new Regex(param.getCryptedUrl(), "/recording/(\\d+)").getMatch(0); + br.getPage("https://streamrecorder.io/recordings/stream/" + recordingID); + final Map<String, Object> recordingEntry = restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP); + if ("no access".equals(recordingEntry.get("error"))) { + throw new DecrypterRetryException(RetryReason.FILE_NOT_FOUND); + } + final String displayName = (String) recordingEntry.get("displayname"); + List<DownloadLink> results = null; + if (displayName != null) { + results = findUserRecordings(account, br.cloneBrowser(), displayName, new HashSet<String>(Arrays.asList(recordingID))); + } + if (results == null || results.size() == 0) { + results = parseRecordingEntry(account, null, displayName, recordingID, recordingEntry); + } + final String title = (String) recordingEntry.get("title"); + ret.addAll(results); + if (title != null) { + final FilePackage fp = FilePackage.getInstance(); + fp.setName(title); + fp.addLinks(ret); + } + return ret; + } + ret.addAll(findUserRecordings(account, br, null, null)); + return ret; + } + + private List<DownloadLink> findUserRecordings(final Account account, final Browser br, final String displayName, final Set<String> recordingIDs) throws Exception { + final List<DownloadLink> ret = new ArrayList<DownloadLink>(); + br.getPage("https://" + getHost() + "/userrecordings"); + if (br.getHttpConnection().getResponseCode() == 404) { + throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND); + } + final String[] favinfos = br.getRegex("togglefavorite\\((\\d+, [^\\)]+)\\)").getColumn(0); + if (favinfos == null || favinfos.length == 0) { + // TODO: Add check for case that user has zero recordings + throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); + } + final HashSet<String> dupes_user_ids = new HashSet<String>(); + userloop: for (final String favinfo : favinfos) { + final String[] vars = favinfo.replace("'", "").split(", "); + final String userID = vars[0]; + final String username = vars[1]; + if (displayName != null && !StringUtils.equalsIgnoreCase(displayName, username)) { + continue userloop; + } + if (!dupes_user_ids.add(userID)) { + /* Skip duplicates */ + continue userloop; + } + int offset = 0; + final int maxItemsPerPage = 20; + final FilePackage fp = FilePackage.getInstance(); + fp.setName(username); + fetchUserVideoLoop: do { + final UrlQuery query = new UrlQuery(); + query.appendEncoded("targetid", userID); + query.appendEncoded("offset", Integer.toString(offset)); + query.appendEncoded("limit", Integer.toString(maxItemsPerPage)); + final Browser brc = br.cloneBrowser(); + brc.getPage("/api/user/recordingsv2?" + query.toString()); + final Map<String, Object> entries = restoreFromString(brc.getRequest().getHtmlCode(), TypeRef.MAP); + final String errorStr = (String) entries.get("error"); + if (errorStr != null) { + /* This should never happen */ + throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND, errorStr); + } + final int count = ((Number) entries.get("count")).intValue(); + final List<Map<String, Object>> recordings = (List<Map<String, Object>>) entries.get("data"); + int newItemsThisPage = 0; + final ArrayList<DownloadLink> thisresults = new ArrayList<DownloadLink>(); + recordingsLoop: for (final Map<String, Object> recordingMap : recordings) { + if (recordingIDs != null) { + if (!recordingIDs.remove(StringUtils.valueOfOrNull(recordingMap.get("id")))) { + continue recordingsLoop; + } + } + final List<DownloadLink> results = parseRecordingEntry(account, userID, username, null, recordingMap); + // parentID -> another recording that belongs to same "recording" session, see /playlist/ or playListMode + newItemsThisPage += results.size(); + thisresults.addAll(results); + } + for (final DownloadLink thisresult : thisresults) { + ret.add(thisresult); + if (displayName == null) { + thisresult._setFilePackage(fp); + distribute(thisresult); + } + } + logger.info("UserID" + userID + " | Crawled page: " + "" + " | Offset: " + offset + "/" + count + " | Found items so far: " + ret.size()); + offset += recordings.size(); + if (recordingIDs != null && recordingIDs.size() == 0) { + break fetchUserVideoLoop; + } + if (newItemsThisPage == 0 && recordingIDs == null) { + logger.info("UserID " + userID + ": Stopping because: Reached end?"); + break fetchUserVideoLoop; + } else if (this.isAbort()) { + /* Aborted by user */ + throw new InterruptedException(); + } else if (offset >= count) { + logger.info("UserID " + userID + ": Stopping because: Reached end"); + break fetchUserVideoLoop; + } + } while (!this.isAbort()); + } + return ret; + } + + private List<DownloadLink> parseRecordingEntry(final Account account, String userID, String username, String recordingID, Map<String, Object> recording) throws Exception { + List<DownloadLink> ret = new ArrayList<DownloadLink>(); + if (recordingID == null) { + recordingID = recording.get("id").toString(); + } + String title = (String) recording.get("streamtitle"); + if (title == null) { + // https://streamrecorder.io/recordings/stream/ + title = (String) recording.get("title"); + if (title == null) { + throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); + } + } + if (userID == null) { + // https://streamrecorder.io/recordings/stream/ + userID = new Regex(StringUtils.valueOfOrNull(recording.get("profile_image_url")), "/img/profile_image/(\\d+)").getMatch(0); + } + final String status = recording.get("status").toString(); + if (username == null) { + // https://streamrecorder.io/recordings/stream/ + username = (String) recording.get("displayname"); + } + if (Boolean.TRUE.equals(recording.get("premium_required"))) { + logger.info("Skipping recordingID " + recordingID + " | Reason: Premium-only"); + return ret; + } else if (!StringUtils.equalsIgnoreCase(status, "finished")) { + logger.info("Skipping recordingID " + recordingID + " | Reason: status != 'finished'"); + return ret; + } + final List<Map<String, Object>> sources = (List<Map<String, Object>>) recording.get("sources"); + for (final Map<String, Object> source : sources) { + String directurl = (String) source.get("downloadlink"); + if (directurl == null) { + // https://streamrecorder.io/recordings/stream/ + directurl = (String) source.get("src"); + if (directurl == null) { + throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); + } + } + String video_Resolution_height = StringUtils.valueOfOrNull(source.get("resolution")); + if (video_Resolution_height == null) { + // https://streamrecorder.io/recordings/stream/ + video_Resolution_height = StringUtils.valueOfOrNull(source.get("size")); + if (video_Resolution_height == null) { + throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); + } + } + final DownloadLink video = this.createDownloadlink(directurl); + video.setDefaultPlugin(hosterplugin); + video.setHost(getHost()); + video.setProperty(StreamrecorderIo.PROPERTY_streamcategory, recording.get("streamcategory")); + video.setProperty(StreamrecorderIo.PROPERTY_recorded_at, recording.get("recorded_at")); + video.setProperty(StreamrecorderIo.PROPERTY_title, title); + video.setProperty(StreamrecorderIo.PROPERTY_user_id, userID); + video.setProperty(StreamrecorderIo.PROPERTY_username, username); + video.setProperty(StreamrecorderIo.PROPERTY_record_id, recordingID); + video.setProperty(StreamrecorderIo.PROPERTY_video_resolution_height, video_Resolution_height); + video.setProperty(StreamrecorderIo.PROPERTY_directurl, directurl); + video.setProperty(StreamrecorderIo.PROPERTY_type, StreamrecorderIo.PROPERTY_TYPE_RECORDING); + video.setProperty(StreamrecorderIo.PROPERTY_downloadable_via_account_id, account.getUser()); + video.setFinalFileName(username + "_" + title + "_" + video_Resolution_height + ".mp4"); + video.setVerifiedFileSize(((Number) source.get("filesize")).longValue()); + video.setAvailable(true); + ret.add(video); + } + String url_thumb_large = (String) recording.get("thumb_large"); + if (url_thumb_large == null) { + // https://streamrecorder.io/recordings/stream/ + url_thumb_large = (String) recording.get("poster"); + } + if (!StringUtils.isEmpty(url_thumb_large)) { + final DownloadLink thumbnail = this.createDownloadlink(DirectHTTP.createURLForThisPlugin(url_thumb_large)); + thumbnail.setProperty(DirectHTTP.PROPERTY_CUSTOM_HOST, getHost()); + thumbnail.setFinalFileName(title + "_thumb_large.jpg"); + thumbnail.setAvailable(true); + ret.add(thumbnail); + } + return ret; + } + + @Override + public int getMaxConcurrentProcessingInstances() { + return 1; + } +} diff --git a/svn_trunk/src/jd/plugins/decrypter/SwisstransferComFolder.java b/svn_trunk/src/jd/plugins/decrypter/SwisstransferComFolder.java index 92ba2239..50b1d687 100644 --- a/svn_trunk/src/jd/plugins/decrypter/SwisstransferComFolder.java +++ b/svn_trunk/src/jd/plugins/decrypter/SwisstransferComFolder.java @@ -20,8 +20,17 @@ import java.util.Locale; import java.util.Map; +import org.appwork.storage.config.annotations.AboutConfig; +import org.appwork.storage.config.annotations.DefaultEnumValue; +import org.appwork.storage.config.annotations.DefaultOnNull; +import org.appwork.storage.config.annotations.LabelInterface; import org.appwork.utils.StringUtils; import org.appwork.utils.formatter.TimeFormatter; +import org.jdownloader.plugins.config.Order; +import org.jdownloader.plugins.config.PluginConfigInterface; +import org.jdownloader.plugins.config.PluginHost; +import org.jdownloader.plugins.config.PluginJsonConfig; +import org.jdownloader.plugins.config.Type; import org.jdownloader.scripting.JavaScriptEngineFactory; import jd.PluginWrapper; @@ -35,9 +44,10 @@ import jd.plugins.LinkStatus; import jd.plugins.PluginException; import jd.plugins.PluginForDecrypt; +import jd.plugins.decrypter.SwisstransferComFolder.SwisstransferComConfig.CrawlMode; import jd.plugins.hoster.DirectHTTP; -@DecrypterPlugin(revision = "$Revision: 48366 $", interfaceVersion = 3, names = { "swisstransfer.com" }, urls = { "https?://(?:www\\.)?swisstransfer\\.com/d/([a-z0-9\\-]+)" }) +@DecrypterPlugin(revision = "$Revision: 50439 $", interfaceVersion = 3, names = { "swisstransfer.com" }, urls = { "https?://(?:www\\.)?swisstransfer\\.com/d/([a-z0-9\\-]+)" }) public class SwisstransferComFolder extends PluginForDecrypt { public SwisstransferComFolder(PluginWrapper wrapper) { super(wrapper); @@ -69,8 +79,39 @@ public ArrayList<DownloadLink> decryptIt(final CryptedLink param, ProgressContro } final String downloadHost = data.get("downloadHost").toString(); final Map<String, Object> container = (Map<String, Object>) data.get("container"); - final Number downloadLimit = (Number) container.get("downloadLimit"); final List<Map<String, Object>> ressourcelist = (List<Map<String, Object>>) container.get("files"); + final Number downloadLimit = (Number) container.get("downloadLimit"); + final SwisstransferComConfig cfg = PluginJsonConfig.get(SwisstransferComConfig.class); + final CrawlMode crawlMode = cfg.getCrawlMode().getMode(); + if (ressourcelist.size() > 1 && !CrawlMode.FILES_FOLDERS.equals(crawlMode)) { + final String expiredDate = (String) data.get("expiredDate"); + final String deletedDate = (String) data.get("deletedDate"); + final String containerUUID = (String) data.get("containerUUID"); + final String directurl = "https://" + downloadHost + "/api/download/" + folderUUID; + final DownloadLink dl = createDownloadlink(DirectHTTP.createURLForThisPlugin(directurl)); + // TODO: verify if resume is possible + dl.setProperty(DirectHTTP.NORESUME, true); + dl.setProperty(DirectHTTP.PROPERTY_CUSTOM_HOST, getHost()); + dl.setFinalFileName("swisstransfer_" + containerUUID + ".zip"); + if (deletedDate != null) { + /* Deleted */ + dl.setAvailable(false); + } else if (expiredDate != null) { + final long timeStamp = TimeFormatter.getMilliSeconds(expiredDate, "yyyy-MM-dd HH:mm:ss", Locale.ENGLISH); + if (System.currentTimeMillis() < timeStamp) { + dl.setAvailable(true); + } else { + dl.setAvailable(false); + } + } else { + dl.setAvailable(true); + } + ret.add(dl); + distribute(dl); + if (CrawlMode.ZIP.equals(crawlMode)) { + return ret; + } + } String fpName = (String) container.get("message"); final FilePackage fp = FilePackage.getInstance(); if (fpName != null) { @@ -106,6 +147,7 @@ public ArrayList<DownloadLink> decryptIt(final CryptedLink param, ProgressContro // final String directurl = String.format("https://www.swisstransfer.com/api/download/%s/%s", linkUUID, fileid); final String directurl = "https://" + downloadHost + "/api/download/" + folderUUID + "/" + fileid; final DownloadLink dl = createDownloadlink(DirectHTTP.createURLForThisPlugin(directurl)); + dl.setProperty(DirectHTTP.PROPERTY_CUSTOM_HOST, getHost()); if (filesize != null) { dl.setVerifiedFileSize(filesize.longValue()); } @@ -149,4 +191,65 @@ public ArrayList<DownloadLink> decryptIt(final CryptedLink param, ProgressContro } while (true); return ret; } + + @Override + public Class<? extends PluginConfigInterface> getConfigInterface() { + return SwisstransferComConfig.class; + } + + @PluginHost(host = "swisstransfer.com", type = Type.CRAWLER) + public static interface SwisstransferComConfig extends PluginConfigInterface { + public static final TRANSLATION TRANSLATION = new TRANSLATION(); + public static final CrawlMode DEFAULT_MODE = CrawlMode.FILES_FOLDERS; + + public static class TRANSLATION { + public String getCrawlMode2_label() { + return "Crawl mode"; + } + } + + public static enum CrawlMode implements LabelInterface { + ZIP { + @Override + public String getLabel() { + return "Add .zip only"; + } + }, + FILES_FOLDERS { + @Override + public String getLabel() { + return "Add loose files & folders"; + } + }, + ALL { + @Override + public String getLabel() { + return "Add loose files & folders AND .zip with all items"; + } + }, + DEFAULT { + @Override + public String getLabel() { + return "Default: " + DEFAULT_MODE.getLabel(); + } + + @Override + public CrawlMode getMode() { + return DEFAULT_MODE.getMode(); + } + }; + + public CrawlMode getMode() { + return this; + } + } + + @AboutConfig + @DefaultEnumValue("DEFAULT") + @Order(10) + @DefaultOnNull + CrawlMode getCrawlMode(); + + void setCrawlMode(final CrawlMode mode); + } } diff --git a/svn_trunk/src/jd/plugins/decrypter/VipergirlsToBoard.java b/svn_trunk/src/jd/plugins/decrypter/VipergirlsToBoard.java index 047f18e1..260dc214 100644 --- a/svn_trunk/src/jd/plugins/decrypter/VipergirlsToBoard.java +++ b/svn_trunk/src/jd/plugins/decrypter/VipergirlsToBoard.java @@ -3,6 +3,8 @@ import java.util.ArrayList; import java.util.HashSet; +import org.appwork.utils.Regex; + import jd.PluginWrapper; import jd.controlling.ProgressController; import jd.http.Browser; @@ -15,9 +17,7 @@ import jd.plugins.PluginException; import jd.plugins.PluginForDecrypt; -import org.appwork.utils.Regex; - -@DecrypterPlugin(revision = "$Revision: 50427 $", interfaceVersion = 3, names = { "vipergirls.to" }, urls = { "https?://(?:www\\.)?vipergirls\\.to/threads/(\\d+)([a-z0-9\\-]+).*" }) +@DecrypterPlugin(revision = "$Revision: 50430 $", interfaceVersion = 3, names = { "vipergirls.to" }, urls = { "https?://(?:www\\.)?vipergirls\\.to/threads/(\\d+)([a-z0-9\\-]+).*" }) public class VipergirlsToBoard extends PluginForDecrypt { public VipergirlsToBoard(PluginWrapper wrapper) { super(wrapper); @@ -57,14 +57,16 @@ public ArrayList<DownloadLink> decryptIt(final CryptedLink param, ProgressContro if (title == null) { title = new Regex(post, "<b>\\s*<div style\\s*=\\s*\"text-align: center;\">\\s*<font[^>]*>\\s*(.*?)\\s*</font>\\s*</div>\\s*</b>").getMatch(0); if (title == null) { - // The title is in the H2 tag spanning 3 lines - title = new Regex(post, "<h2[^>]*>[\\r\\n\\s]*(.*?)[\\r\\n\\s]*</h2>").getMatch(0); + title = new Regex(post, "<blockquote[^>]*>\\s*<b>\\s*(.*?)\\s*</b>\\s*<br").getMatch(0); if (title == null) { - title = threadID + "_" + postID; + // The title is in the H2 tag spanning 3 lines + title = new Regex(post, "<h2[^>]*>[\\r\\n\\s]*(.*?)[\\r\\n\\s]*</h2>").getMatch(0); + if (title == null) { + title = threadID + "_" + postID; + } } } } - FilePackage fp = null; if (title != null) { title = title.replaceAll("(<img.*>)", ""); diff --git a/svn_trunk/src/jd/plugins/download/raf/ChunkRange.java b/svn_trunk/src/jd/plugins/download/raf/ChunkRange.java index 764386fc..0f5950fd 100644 --- a/svn_trunk/src/jd/plugins/download/raf/ChunkRange.java +++ b/svn_trunk/src/jd/plugins/download/raf/ChunkRange.java @@ -72,18 +72,13 @@ public String getRangeHeaderContent(final boolean openEnd) { /* create a ChunkRange from index 'from' to index 'to' (included) */ public ChunkRange(final long from, final Long to) { - rangeRequested = true; if (from < 0) { - throw new IllegalArgumentException("from < 0"); + throw new IllegalArgumentException("from(" + from + ") < 0"); + } else if (to != null && to >= 0 && from > to) { + throw new IllegalArgumentException("from(" + from + ") > to(" + to + ")"); } + rangeRequested = true; this.from = from; - if (to != null && to >= 0) { - if (from > to) { - throw new IllegalArgumentException("from > to"); - } else if (to < from) { - throw new IllegalArgumentException("to < from"); - } - } this.to = to; } diff --git a/svn_trunk/src/jd/plugins/hoster/CivitaiCom.java b/svn_trunk/src/jd/plugins/hoster/CivitaiCom.java index 5062915d..fcbfd990 100644 --- a/svn_trunk/src/jd/plugins/hoster/CivitaiCom.java +++ b/svn_trunk/src/jd/plugins/hoster/CivitaiCom.java @@ -24,6 +24,8 @@ import org.appwork.net.protocol.http.HTTPConstants; import org.appwork.storage.TypeRef; import org.appwork.utils.StringUtils; +import org.jdownloader.plugins.components.config.CivitaiComConfig; +import org.jdownloader.plugins.config.PluginJsonConfig; import org.jdownloader.plugins.controller.LazyPlugin; import org.jdownloader.scripting.JavaScriptEngineFactory; @@ -43,7 +45,7 @@ import jd.plugins.PluginException; import jd.plugins.PluginForHost; -@HostPlugin(revision = "$Revision: 50389 $", interfaceVersion = 3, names = {}, urls = {}) +@HostPlugin(revision = "$Revision: 50439 $", interfaceVersion = 3, names = {}, urls = {}) public class CivitaiCom extends PluginForHost { public CivitaiCom(PluginWrapper wrapper) { super(wrapper); @@ -164,6 +166,7 @@ private AvailableStatus requestFileInformation(final DownloadLink link, final Ac this.login(account); } try { + final CivitaiComConfig cfg = PluginJsonConfig.get(CivitaiComConfig.class); if (regex_image.patternFind()) { br.getPage(link.getPluginPatternMatcher()); if (br.getHttpConnection().getResponseCode() == 404) { @@ -181,7 +184,9 @@ private AvailableStatus requestFileInformation(final DownloadLink link, final Ac final Map<String, Object> metadata = (Map<String, Object>) imagemap.get("metadata"); String filename = (String) imagemap.get("name"); final Number filesize = (Number) metadata.get("size"); - if (!StringUtils.isEmpty(filename)) { + if (cfg.isUseIndexIDForImageFilename()) { + filename = contentID; + } else if (!StringUtils.isEmpty(filename)) { // images/videos may include ?token=YZX in name filename = filename.replaceFirst("\\?token=.+", ""); filename = Encoding.htmlDecode(filename).trim(); @@ -225,7 +230,7 @@ private AvailableStatus requestFileInformation(final DownloadLink link, final Ac /* Do nothing - download handling will take care. */ return AvailableStatus.UNCHECKABLE; } - basicLinkCheck(br, br.createGetRequest(link.getPluginPatternMatcher()), link, null, extDefault, FILENAME_SOURCE.HEADER); + basicLinkCheck(br, br.createGetRequest(link.getPluginPatternMatcher()), link, null, extDefault, FILENAME_SOURCE.CUSTOM, FILENAME_SOURCE.HEADER); } } catch (final AccountRequiredException e) { if (isDownload) { diff --git a/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComBabestubeCom.java b/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComBabestubeCom.java index 4a8f4411..26c6f116 100644 --- a/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComBabestubeCom.java +++ b/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComBabestubeCom.java @@ -22,7 +22,7 @@ import jd.http.Browser; import jd.plugins.HostPlugin; -@HostPlugin(revision = "$Revision: 50411 $", interfaceVersion = 3, names = {}, urls = {}) +@HostPlugin(revision = "$Revision: 50429 $", interfaceVersion = 3, names = {}, urls = {}) public class KernelVideoSharingComBabestubeCom extends KernelVideoSharingComV2 { public KernelVideoSharingComBabestubeCom(final PluginWrapper wrapper) { super(wrapper); @@ -32,7 +32,7 @@ public KernelVideoSharingComBabestubeCom(final PluginWrapper wrapper) { public static List<String[]> getPluginDomains() { final List<String[]> ret = new ArrayList<String[]>(); // each entry in List<String[]> will result in one PluginForHost, Plugin.getHost() will return String[0]->main domain - ret.add(new String[] { "babestube.com", "foxytube.com", "moviesand.com" }); + ret.add(new String[] { "babestube.com", "foxytube.com", "moviesand.com", "submityourflicks.com" }); return ret; } diff --git a/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComThepornbangCom.java b/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComThepornbangCom.java index 3ffe5e98..15e81c32 100644 --- a/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComThepornbangCom.java +++ b/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComThepornbangCom.java @@ -27,6 +27,13 @@ import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; +import org.appwork.storage.TypeRef; +import org.appwork.utils.encoding.Base64; +import org.appwork.utils.formatter.HexFormatter; +import org.appwork.utils.parser.UrlQuery; +import org.jdownloader.plugins.components.config.KVSConfig; +import org.jdownloader.plugins.components.config.KVSConfigThepornbangCom; + import jd.PluginWrapper; import jd.http.Browser; import jd.nutils.encoding.Encoding; @@ -35,14 +42,7 @@ import jd.plugins.DownloadLink.AvailableStatus; import jd.plugins.HostPlugin; -import org.appwork.storage.TypeRef; -import org.appwork.utils.encoding.Base64; -import org.appwork.utils.formatter.HexFormatter; -import org.appwork.utils.parser.UrlQuery; -import org.jdownloader.plugins.components.config.KVSConfig; -import org.jdownloader.plugins.components.config.KVSConfigThepornbangCom; - -@HostPlugin(revision = "$Revision: 50427 $", interfaceVersion = 3, names = {}, urls = {}) +@HostPlugin(revision = "$Revision: 50429 $", interfaceVersion = 3, names = {}, urls = {}) public class KernelVideoSharingComThepornbangCom extends KernelVideoSharingComV2 { public KernelVideoSharingComThepornbangCom(final PluginWrapper wrapper) { super(wrapper); @@ -87,55 +87,57 @@ protected boolean hasFUIDInsideURL(final String url) { } @Override - protected String handleQualitySelection(Browser br, DownloadLink link, HashMap<Integer, String> qualityMap) { - if (qualityMap != null && !qualityMap.isEmpty()) { - try { - final String mp4varstext = br.getRegex("generate_mp4\\('([^\\)]+)").getMatch(0); - final String[] mp4vars = mp4varstext.replace("'", "").split(", "); - final String crypto0 = mp4vars[0]; - final String crypto1 = mp4vars[1]; - final String session_key = decrypt(crypto0, crypto1); - final String okDotRuPrivateVideoVideoID = mp4vars[2]; - final UrlQuery query = new UrlQuery(); - query.appendEncoded("application_key", "CBAFJIICABABABABA"); - query.appendEncoded("fields", "video.url_tiny,video.url_low,video.url_high,video.url_medium,video.url_quadhd,video.url_mobile,video.url_ultrahd,video.url_fullhd,"); - query.appendEncoded("method", "video.get"); - query.appendEncoded("session_key", session_key); - query.appendEncoded("vids", okDotRuPrivateVideoVideoID); - final Browser brc = br.cloneBrowser(); - brc.getPage("https://api.ok.ru/fb.do?" + query.toString()); - /* Small hack: Replace items in our map with the "okcdn.ru" links. */ - final Map<String, Integer> qualityHeightMapping = new HashMap<String, Integer>(); - // TODO: Check/add "url_ultrahd" - if (brc.containsHTML("url_ultrahd")) { - logger.info("Found unknown quality url_ultrahd DEV, ADD THIS!"); - } - qualityHeightMapping.put("url_quadhd", 2160); - qualityHeightMapping.put("url_fullhd", 1080); - qualityHeightMapping.put("url_high", 720); - qualityHeightMapping.put("url_medium", 480); - qualityHeightMapping.put("url_low", 360); - qualityHeightMapping.put("url_tiny", 240); - qualityHeightMapping.put("url_mobile", 144); - final HashMap<Integer, String> qualityMapNew = new HashMap<Integer, String>(); - for (final Entry<String, Integer> entry : qualityHeightMapping.entrySet()) { - final String qualityName = entry.getKey(); - String url = brc.getRegex("<" + qualityName + ">(https?://[^<]+)").getMatch(0); - if (url == null) { - logger.info("Failed to find quality: " + qualityName); - continue; - } - url = Encoding.htmlOnlyDecode(url); - qualityMapNew.put(entry.getValue(), url); - } - if (!qualityMapNew.isEmpty()) { - return super.handleQualitySelection(br, link, qualityMapNew); - } else { - logger.warning("Special handling failed"); + protected String handleQualitySelection(Browser br, DownloadLink link, Map<Integer, String> qualityMap) { + if (qualityMap == null || qualityMap.isEmpty()) { + return null; + } + try { + final String mp4varstext = br.getRegex("generate_mp4\\('([^\\)]+)").getMatch(0); + final String[] mp4vars = mp4varstext.replace("'", "").split(", "); + final String crypto0 = mp4vars[0]; + final String crypto1 = mp4vars[1]; + final String okDotRuPrivateVideoVideoID = mp4vars[2]; + final String session_key = decrypt(crypto0, crypto1); + final UrlQuery query = new UrlQuery(); + query.appendEncoded("application_key", "CBAFJIICABABABABA"); + query.appendEncoded("fields", "video.url_tiny,video.url_low,video.url_high,video.url_medium,video.url_quadhd,video.url_mobile,video.url_ultrahd,video.url_fullhd,"); + query.appendEncoded("method", "video.get"); + query.appendEncoded("session_key", session_key); + query.appendEncoded("vids", okDotRuPrivateVideoVideoID); + final Browser brc = br.cloneBrowser(); + brc.getPage("https://api.ok.ru/fb.do?" + query.toString()); + /* Small hack: Replace items in our map with the "okcdn.ru" links. */ + final Map<String, Integer> qualityHeightMapping = new HashMap<String, Integer>(); + // TODO: Check/add "url_ultrahd" + if (brc.containsHTML("url_ultrahd")) { + logger.info("Found unknown quality url_ultrahd DEV, ADD THIS!"); + } + qualityHeightMapping.put("url_quadhd", 2160); + qualityHeightMapping.put("url_fullhd", 1080); + qualityHeightMapping.put("url_high", 720); + qualityHeightMapping.put("url_medium", 480); + qualityHeightMapping.put("url_low", 360); + qualityHeightMapping.put("url_tiny", 240); + qualityHeightMapping.put("url_mobile", 144); + final Map<Integer, String> qualityMapNew = new HashMap<Integer, String>(); + for (final Entry<String, Integer> entry : qualityHeightMapping.entrySet()) { + final String qualityName = entry.getKey(); + String url = brc.getRegex("<" + qualityName + ">(https?://[^<]+)").getMatch(0); + if (url == null) { + logger.info("Failed to find quality: " + qualityName); + continue; } - } catch (final Throwable e) { - logger.log(e); + url = Encoding.htmlOnlyDecode(url); + qualityMapNew.put(entry.getValue(), url); } + if (!qualityMapNew.isEmpty()) { + /* Success! This is what we want :) */ + return super.handleQualitySelection(br, link, qualityMapNew); + } else { + logger.warning("Special handling failed"); + } + } catch (final Throwable e) { + logger.log(e); } return super.handleQualitySelection(br, link, qualityMap); } @@ -193,5 +195,4 @@ private static SecretKeySpec deriveKey(String password, byte[] salt, int iterati byte[] keyBytes = factory.generateSecret(spec).getEncoded(); return new SecretKeySpec(keyBytes, "AES"); } - } \ No newline at end of file diff --git a/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComV2.java b/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComV2.java index 52f2123d..1843390c 100644 --- a/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComV2.java +++ b/svn_trunk/src/jd/plugins/hoster/KernelVideoSharingComV2.java @@ -77,7 +77,7 @@ import jd.plugins.PluginException; import jd.plugins.components.SiteType.SiteTemplate; -@HostPlugin(revision = "$Revision: 50425 $", interfaceVersion = 3, names = {}, urls = {}) +@HostPlugin(revision = "$Revision: 50430 $", interfaceVersion = 3, names = {}, urls = {}) public abstract class KernelVideoSharingComV2 extends antiDDoSForHost { public KernelVideoSharingComV2(PluginWrapper wrapper) { super(wrapper); @@ -909,6 +909,9 @@ protected boolean isOfflineWebsite(final Browser br) { return true; } else if (responsecode == 410) { return true; + } else if (br._getURL().getPath() == null || "/".equals(br._getURL().getPath())) { + // redirect to main website + return true; } else if (br._getURL().getPath().matches("(?i)/4(04|10)\\.php.*")) { return true; } else if (br.containsHTML(">\\s*(Sorry, this video was deleted per copyright owner request|Video has been removed due to a violation of the Terms and Conditions|Deleted by the owner request|This video has been removed|Video removed due to DMCA|Video is not found)")) { @@ -1745,7 +1748,7 @@ private boolean addQualityURL(final DownloadLink link, final HashMap<Integer, St } /** Returns user preferred quality inside given quality map. Returns best, if user selection is not present in map. */ - protected String handleQualitySelection(final Browser br, final DownloadLink link, final HashMap<Integer, String> qualityMap) { + protected String handleQualitySelection(final Browser br, final DownloadLink link, final Map<Integer, String> qualityMap) { if (qualityMap.isEmpty()) { logger.info("Cannot perform quality selection: qualityMap is empty"); return null; diff --git a/svn_trunk/src/jd/plugins/hoster/KwikCx.java b/svn_trunk/src/jd/plugins/hoster/KwikCx.java index 00dc417e..4bfe1511 100644 --- a/svn_trunk/src/jd/plugins/hoster/KwikCx.java +++ b/svn_trunk/src/jd/plugins/hoster/KwikCx.java @@ -19,13 +19,18 @@ import java.util.ArrayList; import java.util.List; -import org.appwork.utils.DebugMode; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; + import org.appwork.utils.StringUtils; +import org.jdownloader.scripting.JavaScriptEngineFactory; import jd.PluginWrapper; import jd.http.Browser; +import jd.http.URLConnectionAdapter; import jd.nutils.encoding.Encoding; import jd.parser.Regex; +import jd.plugins.Account; import jd.plugins.DownloadLink; import jd.plugins.DownloadLink.AvailableStatus; import jd.plugins.HostPlugin; @@ -34,7 +39,7 @@ import jd.plugins.PluginForHost; import jd.plugins.download.HashInfo; -@HostPlugin(revision = "$Revision: 49072 $", interfaceVersion = 3, names = {}, urls = {}) +@HostPlugin(revision = "$Revision: 50434 $", interfaceVersion = 3, names = {}, urls = {}) public class KwikCx extends PluginForHost { public KwikCx(PluginWrapper wrapper) { super(wrapper); @@ -42,7 +47,7 @@ public KwikCx(PluginWrapper wrapper) { @Override public String getAGBLink() { - return "https://kwik.cx/"; + return "https://" + getHost() + "/"; } private static List<String[]> getPluginDomains() { @@ -64,15 +69,19 @@ public String[] siteSupportedNames() { public static String[] getAnnotationUrls() { final List<String> ret = new ArrayList<String>(); for (final String[] domains : getPluginDomains()) { - ret.add("https?://(?:www\\.)?" + buildHostsPatternPart(domains) + "/f/([A-Za-z0-9]+)"); + ret.add("https?://(?:www\\.)?" + buildHostsPatternPart(domains) + "/(?:f|e)/([A-Za-z0-9]+)"); } return ret.toArray(new String[0]); } - /* Connection stuff */ - private static final boolean FREE_RESUME = true; - private static final int FREE_MAXCHUNKS = 0; - private static final int FREE_MAXDOWNLOADS = 20; + @Override + public boolean isResumeable(final DownloadLink link, final Account account) { + return true; + } + + public int getMaxChunks(final DownloadLink link, final Account account) { + return -2; + } @Override public String getLinkID(final DownloadLink link) { @@ -92,33 +101,43 @@ private String getFID(final DownloadLink link) { public AvailableStatus requestFileInformation(final DownloadLink link) throws IOException, PluginException { if (!link.isNameSet()) { /* Fallback */ - link.setName(this.getFID(link)); + link.setName(this.getFID(link) + ".mp4"); } this.setBrowserExclusive(); br.setFollowRedirects(true); - br.getPage(link.getPluginPatternMatcher()); + br.getPage(link.getPluginPatternMatcher().replaceFirst("/e/", "/f/")); if (br.getHttpConnection().getResponseCode() == 404) { throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND); } - final String filename = br.getRegex("(?i)File name\\s*</strong>\\s*:\\s*([^<>\"]+)").getMatch(0); - String filesize = br.getRegex("(?i)Size\\s*</strong>\\s*:\\s*<abbr[^>]*title=\"(\\d+)\\s*Bytes").getMatch(0); + final String filename = br.getRegex("File name\\s*</strong>\\s*:\\s*([^<>\"]+)").getMatch(0); + String filesize = br.getRegex("Size\\s*</strong>\\s*:\\s*<abbr[^>]*title=\"(\\d+)\\s*Bytes").getMatch(0); if (filename != null) { link.setFinalFileName(Encoding.htmlDecode(filename).trim()); + } else { + logger.info("Failed to find filename"); } if (filesize != null) { link.setVerifiedFileSize(Long.parseLong(filesize)); + } else { + logger.info("Failed to find filesize"); } - final String sha1 = br.getRegex("(?i)strong>\\s*SHA1\\s*</strong>\\s*:\\s*<code>([a-f0-9]+)</code>").getMatch(0); - if (sha1 != null) { - link.setSha1Hash(sha1); - } - final String crc32 = br.getRegex("(?i)strong>\\s*CRC32\\s*</strong>\\s*:\\s*<code>([a-f0-9]+)</code>").getMatch(0); + final String crc32 = br.getRegex("strong>\\s*CRC32\\s*</strong>\\s*:\\s*<code>([a-f0-9]+)</code>").getMatch(0); if (crc32 != null) { link.setHashInfo(HashInfo.newInstanceSafe(crc32, HashInfo.TYPE.CRC32C)); + } else { + logger.info("Failed to find hash: crc32"); } - final String md5 = br.getRegex("(?i)strong>\\s*MD5\\s*</strong>\\s*:\\s*<code>([a-f0-9]+)</code>").getMatch(0); + final String md5 = br.getRegex("strong>\\s*MD5\\s*</strong>\\s*:\\s*<code>([a-f0-9]+)</code>").getMatch(0); if (md5 != null) { link.setMD5Hash(md5); + } else { + logger.info("Failed to find hash: md5"); + } + final String sha1 = br.getRegex("strong>\\s*SHA1\\s*</strong>\\s*:\\s*<code>([a-f0-9]+)</code>").getMatch(0); + if (sha1 != null) { + link.setSha1Hash(sha1); + } else { + logger.info("Failed to find hash: sha1"); } return AvailableStatus.TRUE; } @@ -126,48 +145,50 @@ public AvailableStatus requestFileInformation(final DownloadLink link) throws IO @Override public void handleFree(final DownloadLink link) throws Exception, PluginException { requestFileInformation(link); - doFree(link, FREE_RESUME, FREE_MAXCHUNKS, "free_directlink"); + doFree(link, "free_directlink"); } - private void doFree(final DownloadLink link, final boolean resumable, final int maxchunks, final String directlinkproperty) throws Exception, PluginException { - if (!attemptStoredDownloadurlDownload(link, directlinkproperty, resumable, maxchunks)) { - if (!DebugMode.TRUE_IN_IDE_ELSE_FALSE) { - /* - * 2021-08-03: Unfinished because js needs to be decrypted in order to be able to generate a valid token, see: - * https://svn.jdownloader.org/issues/85727 - */ + private void doFree(final DownloadLink link, final String directlinkproperty) throws Exception, PluginException { + if (!attemptStoredDownloadurlDownload(link, directlinkproperty)) { + br.setFollowRedirects(true); + String script = br.getRegex("<script>\\s*(var _0x[a-f0-9]+=\\[.*?)\\s*</script>").getMatch(0); + if (script == null) { throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); } - br.setFollowRedirects(true); - dl = jd.plugins.BrowserAdapter.openDownload(br, link, "/d/" + this.getFID(link), "_token=TODO", resumable, maxchunks); - if (!this.looksLikeDownloadableContent(dl.getConnection())) { - br.followConnection(true); - if (dl.getConnection().getResponseCode() == 403) { - throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, "Server error 403", 5 * 60 * 1000l); - } else if (dl.getConnection().getResponseCode() == 404) { - throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, "Server error 404", 5 * 60 * 1000l); - } else { - throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); - } + script = script.replace("eval(", "var result=("); + final ScriptEngineManager manager = JavaScriptEngineFactory.getScriptEngineManager(null); + final ScriptEngine engine = manager.getEngineByName("javascript"); + engine.eval(script); + script = engine.get("result").toString(); + final String token = new Regex(script, "name=\"_token\"\\s*value=\"(.*?)\"").getMatch(0); + if (token == null) { + throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); } - link.setProperty(directlinkproperty, dl.getConnection().getURL().toString()); + dl = jd.plugins.BrowserAdapter.openDownload(br, link, "/d/" + this.getFID(link), "_token=" + token, this.isResumeable(link, null), this.getMaxChunks(link, null)); + handleConnectionErrors(br, dl.getConnection()); + link.setProperty(directlinkproperty, dl.getConnection().getURL().toExternalForm()); } dl.startDownload(); } + @Override + protected void throwFinalConnectionException(Browser br, URLConnectionAdapter con) throws PluginException, IOException { + throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); + } + @Override public boolean hasCaptcha(DownloadLink link, jd.plugins.Account acc) { return false; } - private boolean attemptStoredDownloadurlDownload(final DownloadLink link, final String directlinkproperty, final boolean resumable, final int maxchunks) throws Exception { + private boolean attemptStoredDownloadurlDownload(final DownloadLink link, final String directlinkproperty) throws Exception { final String url = link.getStringProperty(directlinkproperty); if (StringUtils.isEmpty(url)) { return false; } try { final Browser brc = br.cloneBrowser(); - dl = new jd.plugins.BrowserAdapter().openDownload(brc, link, url, resumable, maxchunks); + dl = new jd.plugins.BrowserAdapter().openDownload(brc, link, url, this.isResumeable(link, null), this.getMaxChunks(link, null)); if (this.looksLikeDownloadableContent(dl.getConnection())) { return true; } else { @@ -186,7 +207,7 @@ private boolean attemptStoredDownloadurlDownload(final DownloadLink link, final @Override public int getMaxSimultanFreeDownloadNum() { - return FREE_MAXDOWNLOADS; + return Integer.MAX_VALUE; } @Override diff --git a/svn_trunk/src/jd/plugins/hoster/ModsfireCom.java b/svn_trunk/src/jd/plugins/hoster/ModsfireCom.java index 0be1c9bc..f1b523a9 100644 --- a/svn_trunk/src/jd/plugins/hoster/ModsfireCom.java +++ b/svn_trunk/src/jd/plugins/hoster/ModsfireCom.java @@ -18,16 +18,26 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.concurrent.atomic.AtomicInteger; +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.AbstractRecaptchaV2; +import org.jdownloader.captcha.v2.challenge.recaptcha.v2.CaptchaHelperHostPluginRecaptchaV2; import jd.PluginWrapper; import jd.http.Browser; +import jd.http.Cookies; import jd.nutils.encoding.Encoding; import jd.parser.Regex; +import jd.parser.html.Form; import jd.plugins.Account; +import jd.plugins.Account.AccountType; +import jd.plugins.AccountInfo; +import jd.plugins.AccountInvalidException; import jd.plugins.DownloadLink; import jd.plugins.DownloadLink.AvailableStatus; import jd.plugins.HostPlugin; @@ -35,15 +45,18 @@ import jd.plugins.PluginException; import jd.plugins.PluginForHost; -@HostPlugin(revision = "$Revision: 48387 $", interfaceVersion = 3, names = {}, urls = {}) +@HostPlugin(revision = "$Revision: 50432 $", interfaceVersion = 3, names = {}, urls = {}) public class ModsfireCom extends PluginForHost { public ModsfireCom(PluginWrapper wrapper) { super(wrapper); + if (DebugMode.TRUE_IN_IDE_ELSE_FALSE) { + this.enablePremium("https://" + getHost() + "/register"); + } } @Override public String getAGBLink() { - return "https://modsfire.com/"; + return "https://" + getHost() + "/tos"; } private static List<String[]> getPluginDomains() { @@ -70,12 +83,8 @@ public static String[] getAnnotationUrls() { return ret.toArray(new String[0]); } - /* Connection stuff */ - private static final boolean FREE_RESUME = true; - private static final int FREE_MAXCHUNKS = 1; - private static final int FREE_MAXDOWNLOADS = 20; /* Don't touch the following! */ - private static final AtomicInteger freeRunning = new AtomicInteger(0); + private static final AtomicInteger freeRunning = new AtomicInteger(0); @Override public String getLinkID(final DownloadLink link) { @@ -91,6 +100,15 @@ private String getFID(final DownloadLink link) { return new Regex(link.getPluginPatternMatcher(), this.getSupportedLinks()).getMatch(0); } + @Override + public boolean isResumeable(final DownloadLink link, final Account account) { + return true; + } + + public int getMaxChunks(final DownloadLink link, final Account account) { + return 1; + } + @Override public AvailableStatus requestFileInformation(final DownloadLink link) throws IOException, PluginException { if (!link.isNameSet()) { @@ -103,7 +121,7 @@ public AvailableStatus requestFileInformation(final DownloadLink link) throws IO if (br.getHttpConnection().getResponseCode() == 404) { throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND); } else if (!br.containsHTML("/download/" + this.getFID(link))) { - /* Not a downloadurl e.g. "https://modsfire.com/register" */ + /* Not a download url e.g. "https://modsfire.com/register" */ throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND); } final Regex fileNameSize = br.getRegex("class=\"name-file\">([^<>\"]+) - (\\d+(?:\\.\\d{1,2})? [A-Za-z]+)</div>"); @@ -115,27 +133,31 @@ public AvailableStatus requestFileInformation(final DownloadLink link) throws IO if (filename != null) { filename = Encoding.htmlDecode(filename).trim(); link.setName(filename); + } else { + logger.warning("Failed to find filename"); } if (filesize != null) { link.setDownloadSize(SizeFormatter.getSize(filesize)); + } else { + logger.warning("Failed to find filename"); } return AvailableStatus.TRUE; } @Override public void handleFree(final DownloadLink link) throws Exception, PluginException { - handleDownload(link, FREE_RESUME, FREE_MAXCHUNKS, "free_directlink"); + handleDownload(link, null); } - private void handleDownload(final DownloadLink link, final boolean resumable, final int maxchunks, final String directlinkproperty) throws Exception, PluginException { - if (!attemptStoredDownloadurlDownload(link, directlinkproperty)) { + private void handleDownload(final DownloadLink link, final Account account) throws Exception, PluginException { + final String directlinkproperty = this.getDirecturlProperty(account); + if (!attemptStoredDownloadurlDownload(link, account)) { requestFileInformation(link); - final String dllink = "/d/" + this.getFID(link); - if (StringUtils.isEmpty(dllink)) { - logger.warning("Failed to find final downloadurl"); - throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); + if (account != null) { + this.login(account, false); } - dl = jd.plugins.BrowserAdapter.openDownload(br, link, dllink, resumable, maxchunks); + final String dllink = "/d/" + this.getFID(link); + dl = jd.plugins.BrowserAdapter.openDownload(br, link, dllink, this.isResumeable(link, account), this.getMaxChunks(link, account)); if (!this.looksLikeDownloadableContent(dl.getConnection())) { br.followConnection(true); if (dl.getConnection().getResponseCode() == 403) { @@ -148,7 +170,7 @@ private void handleDownload(final DownloadLink link, final boolean resumable, fi throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); } } - link.setProperty(directlinkproperty, dl.getConnection().getURL().toString()); + link.setProperty(directlinkproperty, dl.getConnection().getURL().toExternalForm()); } /* Add a download slot */ controlMaxFreeDownloads(null, link, +1); @@ -162,29 +184,40 @@ private void handleDownload(final DownloadLink link, final boolean resumable, fi } protected void controlMaxFreeDownloads(final Account account, final DownloadLink link, final int num) { - if (account == null) { - synchronized (freeRunning) { - final int before = freeRunning.get(); - final int after = before + num; - freeRunning.set(after); - logger.info("freeRunning(" + link.getName() + ")|max:" + getMaxSimultanFreeDownloadNum() + "|before:" + before + "|after:" + after + "|num:" + num); - } + if (account != null) { + /* Do nothing */ + return; + } + synchronized (freeRunning) { + final int before = freeRunning.get(); + final int after = before + num; + freeRunning.set(after); + logger.info("freeRunning(" + link.getName() + ")|max:" + getMaxSimultanFreeDownloadNum() + "|before:" + before + "|after:" + after + "|num:" + num); } } @Override public boolean hasCaptcha(DownloadLink link, jd.plugins.Account acc) { + /* 2025-01-13: They use Cloudflare Turnstile captcha for free download but atm it is skippable. */ return false; } - private boolean attemptStoredDownloadurlDownload(final DownloadLink link, final String directlinkproperty) throws Exception { - final String url = link.getStringProperty(directlinkproperty); + private String getDirecturlProperty(final Account account) { + if (account == null) { + return "directlink"; + } else { + return "directlink_account_ " + account.getType().getLabel(); + } + } + + private boolean attemptStoredDownloadurlDownload(final DownloadLink link, final Account account) throws Exception { + final String url = link.getStringProperty(getDirecturlProperty(account)); if (StringUtils.isEmpty(url)) { return false; } try { final Browser brc = br.cloneBrowser(); - dl = new jd.plugins.BrowserAdapter().openDownload(brc, link, url, FREE_RESUME, FREE_MAXCHUNKS); + dl = new jd.plugins.BrowserAdapter().openDownload(brc, link, url, this.isResumeable(link, account), this.getMaxChunks(link, account)); if (this.looksLikeDownloadableContent(dl.getConnection())) { return true; } else { @@ -201,6 +234,83 @@ private boolean attemptStoredDownloadurlDownload(final DownloadLink link, final } } + private boolean login(final Account account, final boolean force) throws Exception { + synchronized (account) { + br.setFollowRedirects(true); + br.setCookiesExclusive(true); + final Cookies cookies = account.loadCookies(""); + final String url_relative_premium = "/premium"; + if (cookies != null) { + logger.info("Attempting cookie login"); + this.br.setCookies(this.getHost(), cookies); + if (!force) { + /* Don't validate cookies */ + return false; + } + br.getPage("https://" + this.getHost() + url_relative_premium); + if (this.isLoggedin(br)) { + logger.info("Cookie login successful"); + /* Refresh cookie timestamp */ + account.saveCookies(br.getCookies(br.getHost()), ""); + return true; + } else { + logger.info("Cookie login failed"); + br.clearCookies(null); + } + } + logger.info("Performing full login"); + br.getPage("https://" + this.getHost() + "/login"); + final Form loginform = br.getFormbyActionRegex(".*login"); + if (loginform == null) { + throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT, "Failed to find loginform"); + } + if (AbstractRecaptchaV2.containsRecaptchaV2Class(br)) { + final String recaptchaResponse = new CaptchaHelperHostPluginRecaptchaV2(this, br).getToken(); + loginform.put("g-recaptcha-response", Encoding.urlEncode(recaptchaResponse)); + } + /* Can be username or email(!) */ + loginform.put("email", Encoding.urlEncode(account.getUser())); + loginform.put("password", Encoding.urlEncode(account.getPass())); + loginform.put("remember", "on"); + br.submitForm(loginform); + if (!isLoggedin(br)) { + throw new AccountInvalidException(); + } + br.getPage(url_relative_premium); + account.saveCookies(br.getCookies(br.getHost()), ""); + return true; + } + } + + private boolean isLoggedin(final Browser br) { + return br.containsHTML("/logout\""); + } + + @Override + public AccountInfo fetchAccountInfo(final Account account) throws Exception { + final AccountInfo ai = new AccountInfo(); + login(account, true); + ai.setUnlimitedTraffic(); + final String expire = br.getRegex("(\\d{4}-\\d{2}-\\d{2})").getMatch(0); + if (expire == null) { + throw new AccountInvalidException("Free accounts are not supported"); + } + ai.setValidUntil(TimeFormatter.getMilliSeconds(expire, "dd MMMM yyyy", Locale.ENGLISH)); + account.setType(AccountType.PREMIUM); + account.setConcurrentUsePossible(true); + return ai; + } + + @Override + public void handlePremium(final DownloadLink link, final Account account) throws Exception { + // this.handleDownload(link, account); + } + + @Override + public int getMaxSimultanPremiumDownloadNum() { + return Integer.MAX_VALUE; + } + @Override public int getMaxSimultanFreeDownloadNum() { /* 2023-01-17: Allow max 5 simultaneous downloads and let them start sequentially to try to avoid running into Cloudflare. */ diff --git a/svn_trunk/src/jd/plugins/hoster/MydaddyCc.java b/svn_trunk/src/jd/plugins/hoster/MydaddyCc.java index da48157a..7894c58b 100644 --- a/svn_trunk/src/jd/plugins/hoster/MydaddyCc.java +++ b/svn_trunk/src/jd/plugins/hoster/MydaddyCc.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import org.appwork.utils.DebugMode; @@ -40,7 +41,7 @@ import jd.plugins.PluginForHost; import jd.plugins.components.PluginJSonUtils; -@HostPlugin(revision = "$Revision: 49462 $", interfaceVersion = 3, names = {}, urls = {}) +@HostPlugin(revision = "$Revision: 50429 $", interfaceVersion = 3, names = {}, urls = {}) public class MydaddyCc extends PluginForHost { public MydaddyCc(PluginWrapper wrapper) { super(wrapper); @@ -139,7 +140,7 @@ public AvailableStatus requestFileInformation(final DownloadLink link) throws IO serverReal = br.getRegex(catMouseVars.getMatch(0) + "=\"(//[^\"]+)\"").getMatch(0); internalVideoidReal = br.getRegex(catMouseVars.getMatch(1) + "=\"([^\"]+)\"").getMatch(0); } - final HashMap<Integer, String> qualityMap = new HashMap<Integer, String>(); + final Map<Integer, String> qualityMap = new HashMap<Integer, String>(); final String[] sources = br.getRegex("<source src.*?/>").getColumn(-1); int qualityMax = -1; for (final String source : sources) { @@ -183,7 +184,7 @@ public AvailableStatus requestFileInformation(final DownloadLink link) throws IO } /** Returns user preferred quality inside given quality map. Returns best, if user selection is not present in map. */ - protected final String handleQualitySelection(final Browser br, final DownloadLink link, final HashMap<Integer, String> qualityMap) { + protected final String handleQualitySelection(final Browser br, final DownloadLink link, final Map<Integer, String> qualityMap) { if (qualityMap.isEmpty()) { return null; } diff --git a/svn_trunk/src/jd/plugins/hoster/SeedrCc.java b/svn_trunk/src/jd/plugins/hoster/SeedrCc.java index 45e1edb1..a5cac676 100644 --- a/svn_trunk/src/jd/plugins/hoster/SeedrCc.java +++ b/svn_trunk/src/jd/plugins/hoster/SeedrCc.java @@ -44,11 +44,11 @@ import jd.plugins.PluginException; import jd.plugins.PluginForHost; -@HostPlugin(revision = "$Revision: 50224 $", interfaceVersion = 3, names = { "seedr.cc" }, urls = { "https://(?:www\\.)?seedr\\.cc/download/(file/\\d+|archive/[a-fA-F0-9]+\\?token=[a-fA-F0-9]+&exp=\\d+)" }) +@HostPlugin(revision = "$Revision: 50432 $", interfaceVersion = 3, names = { "seedr.cc" }, urls = { "https://(?:www\\.)?seedr\\.cc/download/(file/\\d+|archive/[a-fA-F0-9]+\\?token=[a-fA-F0-9]+&exp=\\d+)" }) public class SeedrCc extends PluginForHost { public SeedrCc(PluginWrapper wrapper) { super(wrapper); - this.enablePremium("https://www.seedr.cc/premium"); + this.enablePremium("https://www." + getHost() + "/premium"); } @Override @@ -62,7 +62,7 @@ public LazyPlugin.FEATURE[] getFeatures() { @Override public String getAGBLink() { - return "https://www.seedr.cc/dynamic/terms"; + return "https://www." + getHost() + "/dynamic/terms"; } /* Connection stuff */ diff --git a/svn_trunk/src/jd/plugins/hoster/StreamrecorderIo.java b/svn_trunk/src/jd/plugins/hoster/StreamrecorderIo.java new file mode 100644 index 00000000..7d50ce41 --- /dev/null +++ b/svn_trunk/src/jd/plugins/hoster/StreamrecorderIo.java @@ -0,0 +1,311 @@ +//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.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.appwork.utils.StringUtils; +import org.appwork.utils.formatter.TimeFormatter; +import org.jdownloader.gui.translate._GUI; +import org.jdownloader.plugins.controller.LazyPlugin; + +import jd.PluginWrapper; +import jd.http.Browser; +import jd.http.Cookies; +import jd.http.URLConnectionAdapter; +import jd.nutils.encoding.Encoding; +import jd.parser.html.Form; +import jd.plugins.Account; +import jd.plugins.Account.AccountType; +import jd.plugins.AccountInfo; +import jd.plugins.AccountInvalidException; +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; + +@HostPlugin(revision = "$Revision: 50439 $", interfaceVersion = 3, names = {}, urls = {}) +public class StreamrecorderIo extends PluginForHost { + public StreamrecorderIo(PluginWrapper wrapper) { + super(wrapper); + this.enablePremium("https://" + getHost() + "/purchase/plan"); + } + + public static final String PROPERTY_record_id = "record_id"; + public static final String PROPERTY_clip_id = "clip_id"; + public static final String PROPERTY_title = "title"; + public static final String PROPERTY_streamcategory = "streamcategory"; + public static final String PROPERTY_recorded_at = "recorded_at"; + public static final String PROPERTY_user_id = "user_id"; + public static final String PROPERTY_username = "username"; + public static final String PROPERTY_video_resolution_height = "video_resolution_height"; + public static final String PROPERTY_downloadable_via_account_id = "downloadable_via_account_id"; + public static final String PROPERTY_directurl = "directurl"; + public static final String PROPERTY_type = "type"; + public static final String PROPERTY_TYPE_RECORDING = "recording"; + public static final String PROPERTY_TYPE_CLIP = "clip"; + + @Override + public LazyPlugin.FEATURE[] getFeatures() { + return new LazyPlugin.FEATURE[] { LazyPlugin.FEATURE.COOKIE_LOGIN_OPTIONAL }; + } + + @Override + public Browser createNewBrowserInstance() { + final Browser br = super.createNewBrowserInstance(); + br.setFollowRedirects(true); + return br; + } + + @Override + public String getAGBLink() { + return "https://" + getHost() + "/"; + } + + public static List<String[]> getPluginDomains() { + final List<String[]> ret = new ArrayList<String[]>(); + // each entry in List<String[]> will result in one PluginForHost, Plugin.getHost() will return String[0]->main domain + ret.add(new String[] { "streamrecorder.io" }); + return ret; + } + + public static String[] getAnnotationNames() { + return buildAnnotationNames(getPluginDomains()); + } + + @Override + public String[] siteSupportedNames() { + return buildSupportedNames(getPluginDomains()); + } + + public static String[] getAnnotationUrls() { + final List<String> ret = new ArrayList<String>(); + for (final String[] domains : getPluginDomains()) { + /* No regex as items get added via crawler plugin plus there are no individual links to items available. */ + ret.add(""); + } + return ret.toArray(new String[0]); + } + + @Override + public String getPluginContentURL(DownloadLink link) { + final String type = link.getStringProperty(PROPERTY_type, null); + if (PROPERTY_TYPE_CLIP.equals(type)) { + return "https://streamrecorder.io/clip/" + getClipID(link); + } + if (PROPERTY_TYPE_RECORDING.equals(type)) { + return "https://streamrecorder.io/userrecordings/recording/" + getRecordID(link); + } + return super.getPluginContentURL(link); + } + + @Override + public String getLinkID(final DownloadLink link) { + final String type = link.getStringProperty(PROPERTY_type, null); + if (PROPERTY_TYPE_CLIP.equals(type)) { + return this.getHost() + "://clip/" + getClipID(link); + } + if (PROPERTY_TYPE_RECORDING.equals(type)) { + return this.getHost() + "://recording/" + getRecordID(link) + "/" + link.getStringProperty(PROPERTY_video_resolution_height); + } + return super.getLinkID(link); + } + + @Override + public String getMirrorID(final DownloadLink link) { + return getLinkID(link); + } + + private String getRecordID(final DownloadLink link) { + return link.getStringProperty(PROPERTY_record_id); + } + + private String getClipID(final DownloadLink link) { + return link.getStringProperty(PROPERTY_clip_id); + } + + @Override + public boolean isResumeable(final DownloadLink link, final Account account) { + return true; + } + + public int getMaxChunks(final DownloadLink link, final Account account) { + return 0; + } + + @Override + public AvailableStatus requestFileInformation(final DownloadLink link) throws IOException, PluginException { + return AvailableStatus.UNCHECKABLE; + } + + @Override + public void handleFree(final DownloadLink link) throws Exception, PluginException { + throw new AccountRequiredException(); + } + + public void handleDownload(final DownloadLink link, final Account account) throws Exception, PluginException { + final String dllink = link.getStringProperty(PROPERTY_directurl); + dl = jd.plugins.BrowserAdapter.openDownload(br, link, dllink, this.isResumeable(link, null), this.getMaxChunks(link, null)); + handleConnectionErrors(br, dl.getConnection()); + dl.startDownload(); + } + + @Override + protected void throwFinalConnectionException(Browser br, URLConnectionAdapter con) throws PluginException, IOException { + throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT); + } + + @Override + public int getMaxSimultanFreeDownloadNum() { + return Integer.MAX_VALUE; + } + + public boolean login(final Account account, final boolean force) throws Exception { + synchronized (account) { + br.setFollowRedirects(true); + br.setCookiesExclusive(true); + final Cookies cookies = account.loadCookies(""); + final Cookies userCookies = account.loadUserCookies(); + final String url_relative_profilesettings = "/profilesettings"; + if (cookies != null || userCookies != null) { + logger.info("Attempting cookie login"); + if (userCookies != null) { + br.setCookies(userCookies); + } else { + br.setCookies(cookies); + } + if (!force) { + /* Don't validate cookies */ + return false; + } + br.getPage("https://" + this.getHost() + url_relative_profilesettings); + if (get2FAForm(br) == null && this.isLoggedin(br)) { + logger.info("Cookie login successful"); + /* Refresh cookie timestamp */ + account.saveCookies(br.getCookies(br.getHost()), ""); + return true; + } else { + logger.info("Cookie login failed"); + br.clearCookies(null); + if (userCookies != null) { + /* Dead-end */ + if (account.hasEverBeenValid()) { + throw new AccountInvalidException(_GUI.T.accountdialog_check_cookies_expired()); + } else { + throw new AccountInvalidException(_GUI.T.accountdialog_check_cookies_invalid()); + } + } + } + } + logger.info("Performing full login"); + br.getPage("https://" + this.getHost() + "/login"); + final Form loginform = br.getFormbyActionRegex(".*login"); + if (loginform == null) { + throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT, "Failed to find loginform"); + } + loginform.put("username", Encoding.urlEncode(account.getUser())); + loginform.put("password", Encoding.urlEncode(account.getPass())); + br.submitForm(loginform); + final Form twoFAForm = br.getFormbyActionRegex(".*check-totp"); + if (twoFAForm != null) { + logger.info("2FA code required"); + final String twoFACode = this.getTwoFACode(account, "\\d{6}"); + logger.info("Submitting 2FA code"); + twoFAForm.put("code", twoFACode); + br.submitForm(twoFAForm); + if (get2FAForm(br) != null || !isLoggedin(br)) { + throw new AccountInvalidException("Invalid TOTP code"); + } + } else if (!isLoggedin(br)) { + throw new AccountInvalidException(); + } + br.getPage(url_relative_profilesettings); + account.saveCookies(br.getCookies(br.getHost()), ""); + return true; + } + } + + private Form get2FAForm(final Browser br) { + return br.getFormbyActionRegex(".*check-totp"); + } + + private boolean isLoggedin(final Browser br) { + return br.containsHTML("/logout\""); + } + + @Override + public AccountInfo fetchAccountInfo(final Account account) throws Exception { + final AccountInfo ai = new AccountInfo(); + login(account, true); + final String expire = br.getRegex("Premium until (\\d{4}-\\d{2}-\\d{2})").getMatch(0); + if (expire == null) { + throw new AccountInvalidException("Free accounts are not supported"); + } + ai.setValidUntil(TimeFormatter.getMilliSeconds(expire, "yyyy-MM-dd", Locale.ENGLISH)); + ai.setUnlimitedTraffic(); + account.setType(AccountType.PREMIUM); + account.setConcurrentUsePossible(true); + return ai; + } + + @Override + public void handlePremium(final DownloadLink link, final Account account) throws Exception { + this.handleDownload(link, account); + } + + @Override + public int getMaxSimultanPremiumDownloadNum() { + return Integer.MAX_VALUE; + } + + @Override + public boolean hasCaptcha(final DownloadLink link, final Account acc) { + return false; + } + + private String getDownloadableVia(final DownloadLink dl) { + return dl.getStringProperty(PROPERTY_downloadable_via_account_id, null); + } + + @Override + public boolean canHandle(final DownloadLink link, final Account account) throws Exception { + if (account == null) { + /* Without account its not possible to download any link from this host. */ + return false; + } + final String account_username = account.getUser(); + final String account_username_from_which_url_was_added = getDownloadableVia(link); + if (!StringUtils.equals(account_username_from_which_url_was_added, account_username)) { + /* Link is from another account -> Users can only download the items they "recorded" with their account. */ + return false; + } + return super.canHandle(link, account); + } + + @Override + public void reset() { + } + + @Override + public void resetDownloadlink(DownloadLink link) { + } +} \ No newline at end of file diff --git a/svn_trunk/src/jd/plugins/hoster/TeraboxCom.java b/svn_trunk/src/jd/plugins/hoster/TeraboxCom.java index fb6ee0e3..8134d698 100644 --- a/svn_trunk/src/jd/plugins/hoster/TeraboxCom.java +++ b/svn_trunk/src/jd/plugins/hoster/TeraboxCom.java @@ -54,7 +54,7 @@ import jd.plugins.download.HashInfo; import jd.plugins.download.HashResult; -@HostPlugin(revision = "$Revision: 50173 $", interfaceVersion = 3, names = {}, urls = {}) +@HostPlugin(revision = "$Revision: 50429 $", interfaceVersion = 3, names = {}, urls = {}) @PluginDependencies(dependencies = { TeraboxComFolder.class }) public class TeraboxCom extends PluginForHost { public TeraboxCom(PluginWrapper wrapper) { @@ -216,7 +216,7 @@ public static AvailableStatus parseFileInformation(final DownloadLink link, fina @Override public void handleFree(final DownloadLink link) throws Exception, PluginException { requestFileInformation(link, null); - throw new AccountRequiredException(); + throw new AccountRequiredException("[Free] account required to download files from this host"); } private String checkDirectLink(final DownloadLink link, final String property) { diff --git a/svn_trunk/src/jd/plugins/hoster/XbabeCom.java b/svn_trunk/src/jd/plugins/hoster/XbabeCom.java index bf46fbda..fa4a4c5d 100644 --- a/svn_trunk/src/jd/plugins/hoster/XbabeCom.java +++ b/svn_trunk/src/jd/plugins/hoster/XbabeCom.java @@ -19,9 +19,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; - -import org.appwork.utils.Regex; -import org.appwork.utils.StringUtils; +import java.util.Map; import jd.PluginWrapper; import jd.http.Browser; @@ -29,7 +27,10 @@ import jd.plugins.HostPlugin; import jd.plugins.PluginException; -@HostPlugin(revision = "$Revision: 49462 $", interfaceVersion = 3, names = {}, urls = {}) +import org.appwork.utils.Regex; +import org.appwork.utils.StringUtils; + +@HostPlugin(revision = "$Revision: 50436 $", interfaceVersion = 3, names = {}, urls = {}) public class XbabeCom extends KernelVideoSharingComV2 { public XbabeCom(final PluginWrapper wrapper) { super(wrapper); @@ -71,7 +72,7 @@ protected String generateContentURL(final String host, final String fuid, final @Override protected String getDllink(final DownloadLink link, final Browser br) throws PluginException, IOException { /* 2021-09-01: Workaround as upper handling picks up preview-clips instead of the full videos. */ - final HashMap<Integer, String> qualityMap = new HashMap<Integer, String>(); + final Map<Integer, String> qualityMap = new HashMap<Integer, String>(); final String[] htmls = br.getRegex("(<source[^>]*src=.*?[^>]*type=\"video/mp4\"[^>]*>)").getColumn(0); for (final String html : htmls) { final String url = new Regex(html, "src=\"(http[^\"]+)").getMatch(0); diff --git a/svn_trunk/src/org/jdownloader/container/InternetShortcut.java b/svn_trunk/src/org/jdownloader/container/InternetShortcut.java index 2d09aa46..b009dd05 100644 --- a/svn_trunk/src/org/jdownloader/container/InternetShortcut.java +++ b/svn_trunk/src/org/jdownloader/container/InternetShortcut.java @@ -20,17 +20,18 @@ import java.io.IOException; import java.util.ArrayList; -import jd.controlling.linkcrawler.CrawledLink; -import jd.plugins.ContainerStatus; -import jd.plugins.PluginsC; - import org.appwork.utils.IO; import org.appwork.utils.Regex; import org.appwork.utils.StringUtils; +import jd.controlling.linkcollector.LinkOrigin; +import jd.controlling.linkcrawler.CrawledLink; +import jd.plugins.ContainerStatus; +import jd.plugins.PluginsC; + public class InternetShortcut extends PluginsC { public InternetShortcut() { - super("InternetShortcut", "file:/.+\\.url$", "$Revision: 49815 $"); + super("InternetShortcut", "file:/.+\\.url$", "$Revision: 50430 $"); } public InternetShortcut newPluginInstance() { @@ -41,6 +42,16 @@ public InternetShortcut newPluginInstance() { protected void deleteContainer(CrawledLink source, File file) { } + @Override + public ArrayList<CrawledLink> decryptContainer(final CrawledLink source) { + if (source != null && source.getOrigin() != null && LinkOrigin.DOWNLOADED_CONTAINER.equals(source.getOrigin().getOrigin())) { + // do not open downloaded/extracted InternetShortcut files, they are often used for affiliate + return null; + } + return super.decryptContainer(source); + } + + @Override public ContainerStatus callDecryption(File lc) { final ContainerStatus cs = new ContainerStatus(lc); try { diff --git a/svn_trunk/src/org/jdownloader/controlling/hosterrule/HosterRuleController.java b/svn_trunk/src/org/jdownloader/controlling/hosterrule/HosterRuleController.java index c3ff76ec..81784d51 100644 --- a/svn_trunk/src/org/jdownloader/controlling/hosterrule/HosterRuleController.java +++ b/svn_trunk/src/org/jdownloader/controlling/hosterrule/HosterRuleController.java @@ -27,8 +27,7 @@ import org.appwork.utils.event.queue.QueueAction; import org.appwork.utils.logging2.LogSource; import org.appwork.utils.swing.dialog.Dialog; -import org.appwork.utils.swing.dialog.DialogCanceledException; -import org.appwork.utils.swing.dialog.DialogClosedException; +import org.appwork.utils.swing.dialog.DialogNoAnswerException; import org.jdownloader.gui.translate._GUI; import org.jdownloader.logging.LogController; import org.jdownloader.plugins.controller.host.LazyHostPlugin; @@ -236,7 +235,9 @@ private void validateRules(final List<AccountUsageRule> loadedRules) { protected Void run() throws RuntimeException { if (loadedRules != null) { for (final AccountUsageRule hr : loadedRules) { - validateRule(hr); + if (!validateRule(hr)) { + remove(hr); + } } } return null; @@ -320,7 +321,7 @@ public boolean isCustomizedCache() { }); } - protected void validateRule(final AccountUsageRule hr) { + public boolean validateRule(final AccountUsageRule hr) { final String host = hr.getHoster(); final Set<Account> accounts = new HashSet<Account>(); AccountGroup defaultAccountGroup = null; @@ -422,9 +423,9 @@ protected void validateRule(final AccountUsageRule hr) { if (Boolean.FALSE.equals(isHosterpluginAllowsUsageRuleCreation)) { logger.info("Disable and removed rule for host " + host + " because: plugin does not allow usage rule creation"); hr.setEnabled(false); - this.remove(hr); - return; + return false; } + return true; } /** Returns true if new rule creation is allowed according to some factors given inside given LazyHostPlugin instance. */ @@ -483,7 +484,10 @@ public void add(final AccountUsageRule rule) { queue.add(new QueueAction<Void, RuntimeException>() { @Override protected Void run() throws RuntimeException { - validateRule(rule); + if (!validateRule(rule)) { + remove(rule); + return null; + } rule.setOwner(HosterRuleController.this); loadedRules.add(rule); delayedSaver.delayedrun(); @@ -506,10 +510,16 @@ protected boolean allowAsync() { @Override protected Void run() throws RuntimeException { delayedSaver.delayedrun(); + boolean valid = true; try { - validateRule(rule); + valid = validateRule(rule); + if (!valid) { + remove(rule); + } } finally { - eventSender.fireEvent(new HosterRuleControllerEvent(this, HosterRuleControllerEvent.Type.DATA_UPDATE, rule)); + if (valid) { + eventSender.fireEvent(new HosterRuleControllerEvent(this, HosterRuleControllerEvent.Type.DATA_UPDATE, rule)); + } } return null; } @@ -531,16 +541,14 @@ public boolean showEditPanel(final AccountUsageRule editing) { queue.add(new QueueAction<Void, RuntimeException>() { @Override protected Void run() throws RuntimeException { - validateRule(newRule); - editing.set(newRule.isEnabled(), newRule.getAccounts()); + if (validateRule(newRule)) { + editing.set(newRule.isEnabled(), newRule.getAccounts()); + } return null; } }); return true; - } catch (DialogClosedException e) { - e.printStackTrace(); - return false; - } catch (DialogCanceledException e) { + } catch (DialogNoAnswerException e) { e.printStackTrace(); return false; } diff --git a/svn_trunk/src/org/jdownloader/plugins/components/config/CivitaiComConfig.java b/svn_trunk/src/org/jdownloader/plugins/components/config/CivitaiComConfig.java index 31df5828..3e5166a8 100644 --- a/svn_trunk/src/org/jdownloader/plugins/components/config/CivitaiComConfig.java +++ b/svn_trunk/src/org/jdownloader/plugins/components/config/CivitaiComConfig.java @@ -1,6 +1,7 @@ package org.jdownloader.plugins.components.config; import org.appwork.storage.config.annotations.AboutConfig; +import org.appwork.storage.config.annotations.DefaultBooleanValue; import org.appwork.storage.config.annotations.DefaultIntValue; import org.appwork.storage.config.annotations.DefaultOnNull; import org.appwork.storage.config.annotations.DescriptionForConfigEntry; @@ -43,4 +44,12 @@ public String getProfileCrawlerPaginationSleepMillis_label() { int getProfileCrawlerPaginationSleepMillis(); void setProfileCrawlerPaginationSleepMillis(int millis); + + @AboutConfig + @DefaultBooleanValue(false) + @DescriptionForConfigEntry("Use IndexID (/images/XXXXX) for image filename?") + @Order(30) + boolean isUseIndexIDForImageFilename(); + + void setUseIndexIDForImageFilename(boolean b); } \ No newline at end of file diff --git a/svn_trunk/src/org/jdownloader/plugins/components/config/MissavComConfig.java b/svn_trunk/src/org/jdownloader/plugins/components/config/MissavComConfig.java index df494e92..3ebda408 100644 --- a/svn_trunk/src/org/jdownloader/plugins/components/config/MissavComConfig.java +++ b/svn_trunk/src/org/jdownloader/plugins/components/config/MissavComConfig.java @@ -10,7 +10,7 @@ import org.jdownloader.plugins.config.PluginHost; import org.jdownloader.plugins.config.Type; -@PluginHost(host = "missav.com", type = Type.HOSTER) +@PluginHost(host = "missav.ws", type = Type.HOSTER) public interface MissavComConfig extends PluginConfigInterface { public static final MissavComConfig.TRANSLATION TRANSLATION = new TRANSLATION(); public static final MissavComConfig.VideoQuality DEFAULT_MODE = VideoQuality.BEST; diff --git a/svn_trunk/src/org/jdownloader/plugins/controller/host/HostPluginController.java b/svn_trunk/src/org/jdownloader/plugins/controller/host/HostPluginController.java index 02572493..0c5386e9 100644 --- a/svn_trunk/src/org/jdownloader/plugins/controller/host/HostPluginController.java +++ b/svn_trunk/src/org/jdownloader/plugins/controller/host/HostPluginController.java @@ -14,15 +14,6 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -import jd.SecondLevelLaunch; -import jd.controlling.AccountController; -import jd.controlling.TaskQueue; -import jd.controlling.downloadcontroller.DownloadController; -import jd.controlling.linkcollector.LinkCollector; -import jd.nutils.Formatter; -import jd.plugins.HostPlugin; -import jd.plugins.PluginForHost; - import org.appwork.exceptions.WTFException; import org.appwork.shutdown.ShutdownController; import org.appwork.shutdown.ShutdownEvent; @@ -41,6 +32,15 @@ import org.jdownloader.plugins.controller.PluginInfo; import org.jdownloader.plugins.controller.UpdateRequiredClassNotFoundException; +import jd.SecondLevelLaunch; +import jd.controlling.AccountController; +import jd.controlling.TaskQueue; +import jd.controlling.downloadcontroller.DownloadController; +import jd.controlling.linkcollector.LinkCollector; +import jd.nutils.Formatter; +import jd.plugins.HostPlugin; +import jd.plugins.PluginForHost; + public class HostPluginController extends PluginController<PluginForHost> { private static final HostPluginController INSTANCE = new HostPluginController(); @@ -345,8 +345,10 @@ private List<LazyHostPlugin> update(LogSource logger, final List<LazyHostPlugin> if (purl != null) { lazyHostPlugin.setPremiumUrl(new String(purl)); } + lazyHostPlugin.setHasPremiumConfig(plg.getAccountConfigInterface(null) != null); } else { lazyHostPlugin.setPremium(false); + lazyHostPlugin.setHasPremiumConfig(false); } /* set hasConfig */ lazyHostPlugin.setHasConfig(plg.hasConfig()); diff --git a/svn_trunk/src/org/jdownloader/plugins/controller/host/LazyHostPlugin.java b/svn_trunk/src/org/jdownloader/plugins/controller/host/LazyHostPlugin.java index 084e0a4d..1d8fd095 100644 --- a/svn_trunk/src/org/jdownloader/plugins/controller/host/LazyHostPlugin.java +++ b/svn_trunk/src/org/jdownloader/plugins/controller/host/LazyHostPlugin.java @@ -1,17 +1,18 @@ package org.jdownloader.plugins.controller.host; -import jd.plugins.PluginForHost; - import org.jdownloader.DomainInfo; import org.jdownloader.plugins.controller.LazyPlugin; import org.jdownloader.plugins.controller.LazyPluginClass; import org.jdownloader.plugins.controller.PluginClassLoader.PluginClassLoaderChild; import org.jdownloader.plugins.controller.UpdateRequiredClassNotFoundException; +import jd.plugins.PluginForHost; + public class LazyHostPlugin extends LazyPlugin<PluginForHost> { private static enum PROPERTY { CONFIG, PREMIUM, + PREMIUM_CONFIG, REWRITE, ALLOW } @@ -123,6 +124,14 @@ protected void setPremium(boolean premium) { setProperty(premium, PROPERTY.PREMIUM); } + public boolean isHasPremiumConfig() { + return getProperty(PROPERTY.PREMIUM_CONFIG); + } + + protected void setHasPremiumConfig(boolean premium) { + setProperty(premium, PROPERTY.PREMIUM_CONFIG); + } + public DomainInfo getDomainInfo() { return DomainInfo.getInstance(getHost()); } diff --git a/svn_trunk/src/org/jdownloader/plugins/controller/host/LazyHostPluginCache.java b/svn_trunk/src/org/jdownloader/plugins/controller/host/LazyHostPluginCache.java index ea3a53de..0c675edd 100644 --- a/svn_trunk/src/org/jdownloader/plugins/controller/host/LazyHostPluginCache.java +++ b/svn_trunk/src/org/jdownloader/plugins/controller/host/LazyHostPluginCache.java @@ -22,7 +22,7 @@ import org.jdownloader.plugins.controller.LazyPluginClass; public class LazyHostPluginCache { - private static final long CACHEVERSION = 29042024001l + LazyPlugin.FEATURE.CACHEVERSION; + private static final long CACHEVERSION = 13012025001l + LazyPlugin.FEATURE.CACHEVERSION; public static ByteArrayOutputStream readFile(File file) throws IOException { final FileInputStream fis = new FileInputStream(file); @@ -83,17 +83,20 @@ public static List<LazyHostPlugin> read(File file, final AtomicLong lastModifica lazyHostPlugin.setPluginUsage(is.readLongOptimized()); final int flags = is.ensureRead(); lazyHostPlugin.setPremium((flags & (1 << 0)) != 0); - lazyHostPlugin.setHasConfig((flags & (1 << 1)) != 0); - if ((flags & (1 << 4)) != 0) { - lazyHostPlugin.setPremiumUrl(is.readString(stringBuffer)); + if (lazyHostPlugin.isPremium()) { + lazyHostPlugin.setHasPremiumConfig((flags & (1 << 1)) != 0); } + lazyHostPlugin.setHasConfig((flags & (1 << 2)) != 0); if ((flags & (1 << 5)) != 0) { - lazyHostPlugin.setHasRewrite(true); + lazyHostPlugin.setPremiumUrl(is.readString(stringBuffer)); } if ((flags & (1 << 6)) != 0) { + lazyHostPlugin.setHasRewrite(true); + } + if ((flags & (1 << 7)) != 0) { lazyHostPlugin.setHasAllowHandle(true); } - if ((flags & (1 << 3)) != 0) { + if ((flags & (1 << 4)) != 0) { lazyHostPlugin.setConfigInterface(is.readString(stringBuffer)); } final int sitesSupportedNumber = is.readShort(); @@ -106,7 +109,7 @@ public static List<LazyHostPlugin> read(File file, final AtomicLong lastModifica } lazyHostPlugin.setSitesSupported(sitesSupportedNames.toArray(new String[0])); } - if ((flags & (1 << 2)) != 0) { + if ((flags & (1 << 3)) != 0) { final ArrayList<LazyPlugin.FEATURE> features = new ArrayList<LazyPlugin.FEATURE>(LazyPlugin.FEATURE.values().length); for (final LazyPlugin.FEATURE feature : LazyPlugin.FEATURE.values()) { if (is.readBoolean()) { @@ -184,25 +187,28 @@ public static void write(List<LazyHostPlugin> lazyPlugins, File file, final Atom byte flags = 0; if (plugin.isPremium()) { flags |= (1 << 0); + if (plugin.isHasPremiumConfig()) { + flags |= (1 << 1); + } } if (plugin.isHasConfig()) { - flags |= (1 << 1); + flags |= (1 << 2); } final LazyPlugin.FEATURE[] features = plugin.getFeatures(); if (features != null && features.length > 0) { - flags |= (1 << 2); + flags |= (1 << 3); } if (plugin.isHasConfig() && plugin.getConfigInterface() != null) { - flags |= (1 << 3); + flags |= (1 << 4); } if (plugin.isPremium() && plugin.getPremiumUrl() != null) { - flags |= (1 << 4); + flags |= (1 << 5); } if (plugin.isHasRewrite()) { - flags |= (1 << 5); + flags |= (1 << 6); } if (plugin.isHasAllowHandle()) { - flags |= (1 << 6); + flags |= (1 << 7); } bos.write(flags); if (plugin.isPremium() && plugin.getPremiumUrl() != null) { diff --git a/svn_utils/libs/publicsuffix-list.dep.json b/svn_utils/libs/publicsuffix-list.dep.json index a389bebd..21d48725 100644 --- a/svn_utils/libs/publicsuffix-list.dep.json +++ b/svn_utils/libs/publicsuffix-list.dep.json @@ -488,11 +488,101 @@ "minJRE":null, "name":"\"Public Suffix List Library\"", "version":"2024.351.1 bc9a4ea7bea6062240b3b6161125931925283dc1" + }, + { + "changes":"2024.355.0 9e89e8b8a64027217dc22dda2e7c9dacd3d6ee6c\t: chore: update website URL (#2344)\r\n2024.358.0 a12a4d2dd9c8d27a4b187a42588f90577858ab5a\t: util: gTLD data autopull updates for 2024-12-23T15:16:32 UTC (#2357)\n\nCo-authored-by: GitHub <noreply@github.com>\r\n2024.359.0 60bb8d87995b9423bf55742da5360c68ec33ce84\t: remove `platter-app.com` (#2346)\r\n2024.359.1 f6f89086eb4c1e8d0c654ce5ba4cf425fb62bb96\t: remove `drud.io` and `drud.us` (#2347)\r\n2024.359.2 d2dd5f273d594b1a335fd3aadfc8c182df3ed787\t: remove `spacekit.io` (#2348)\r\n2024.359.3 eaebbab737795c84c6ab6159f8273fb2dfc84d9e\t: update email address (#2354)\r\n2024.359.4 304c0680cdcbc97c93a09a1b2dc387a7c411700a\t: add botdash domains (#2342)\r\n2024.359.5 b29032616d31b532d04092781b9aa61cf54c6fdc\t: remove Diher Solutions section (#2319)\r\n2024.359.6 9001793946007094caf862748aaeb7e5773541a9\t: remove `curv.dev` (#2317)\r\n2024.359.7 f229d7f87051bb6197b315f42adae05cb68e33b5\t: chore: formatting + fixes (#2329)", + "date":"2024-12-28T11:56:45.646+01:00", + "dependencies":null, + "description":"The publicsuffix/list is a Java library that provides an updated version of Mozilla's Public Suffix List. This is an essential resource for web developers, as it allows users to parse domain names, extract their effective top-level domains (TLDs), or check whether a domain is a public suffix. It can be used to avoid 'supercookie' vulnerabilities, ensure correct cookie scope, and uphold the same-origin policy. (Library description by ChatGPT)", + "files":null, + "hashes":{"../src/org/appwork/utils/net/effective_tld_names.dat":"998c28a066398a1e05864242e95327b905ce33c564c0e392ea8f4f0db4a5c0fb"}, + "licenses":[{ + "name":"Mozilla Public License 2.0", + "spdx_id":"MPL-2.0", + "key":"mpl-2.0", + "url":"https://api.github.com/licenses/mpl-2.0", + "node_id":"MDc6TGljZW5zZTE0" + }], + "minJRE":null, + "name":"\"Public Suffix List Library\"", + "version":"2024.359.7 f229d7f87051bb6197b315f42adae05cb68e33b5" + }, + { + "changes":"2025.5.0 397a13cba5672b1b4eb847995fc91e03fc3893e1\t: remove Hakaran domains (#2361)", + "date":"2025-01-05T16:20:58.456+01:00", + "dependencies":null, + "description":"The publicsuffix/list is a Java library that provides an updated version of Mozilla's Public Suffix List. This is an essential resource for web developers, as it allows users to parse domain names, extract their effective top-level domains (TLDs), or check whether a domain is a public suffix. It can be used to avoid 'supercookie' vulnerabilities, ensure correct cookie scope, and uphold the same-origin policy. (Library description by ChatGPT)", + "files":null, + "hashes":{"../src/org/appwork/utils/net/effective_tld_names.dat":"f76a284242bafc683eac6d1ba239cb6661144c3c5565a2e29a1f9de9081c06cf"}, + "licenses":[{ + "name":"Mozilla Public License 2.0", + "spdx_id":"MPL-2.0", + "key":"mpl-2.0", + "url":"https://api.github.com/licenses/mpl-2.0", + "node_id":"MDc6TGljZW5zZTE0" + }], + "minJRE":null, + "name":"\"Public Suffix List Library\"", + "version":"2025.5.0 397a13cba5672b1b4eb847995fc91e03fc3893e1" + }, + { + "changes":"2025.7.0 fde49104ed0d33a0ff10762386bb4a36801b2121\t: Add Code of Conduct (#2364)\r\n2025.7.1 cc970cad8ae7694bd7c080f1f9f5cc7ae0d6a43f\t: Replace broken links (#2360)\r\n2025.7.2 0f5ad14268854e6bff2d2e53a6861e46cdb63dab\t: add PSL Sandbox (#2358)\r\n2025.7.3 17440f51f53e1fb0e53f1d843dceb235a25893cf\t: Add `cloudbeesusercontent.io` (#2298)", + "date":"2025-01-08T10:39:18.908+01:00", + "dependencies":null, + "description":"The publicsuffix/list is a Java library that provides an updated version of Mozilla's Public Suffix List. This is an essential resource for web developers, as it allows users to parse domain names, extract their effective top-level domains (TLDs), or check whether a domain is a public suffix. It can be used to avoid 'supercookie' vulnerabilities, ensure correct cookie scope, and uphold the same-origin policy. (Library description by ChatGPT)", + "files":null, + "hashes":{"../src/org/appwork/utils/net/effective_tld_names.dat":"f4e10aab4acadc5af9214ba711e2a9d737d9de696e1e9441a82b72809b274693"}, + "licenses":[{ + "name":"Mozilla Public License 2.0", + "spdx_id":"MPL-2.0", + "key":"mpl-2.0", + "url":"https://api.github.com/licenses/mpl-2.0", + "node_id":"MDc6TGljZW5zZTE0" + }], + "minJRE":null, + "name":"\"Public Suffix List Library\"", + "version":"2025.7.3 17440f51f53e1fb0e53f1d843dceb235a25893cf" + }, + { + "changes":"2025.8.0 d1420f641cf8523ae758342e8b5661287718d33f\t: Add Liara (#2365)", + "date":"2025-01-09T17:02:05.677+01:00", + "dependencies":null, + "description":"The publicsuffix/list is a Java library that provides an updated version of Mozilla's Public Suffix List. This is an essential resource for web developers, as it allows users to parse domain names, extract their effective top-level domains (TLDs), or check whether a domain is a public suffix. It can be used to avoid 'supercookie' vulnerabilities, ensure correct cookie scope, and uphold the same-origin policy. (Library description by ChatGPT)", + "files":null, + "hashes":{"../src/org/appwork/utils/net/effective_tld_names.dat":"7c33ac889553eec4fd845214fafc373446995dbc6b4e8f8288fef77be833760f"}, + "licenses":[{ + "name":"Mozilla Public License 2.0", + "spdx_id":"MPL-2.0", + "key":"mpl-2.0", + "url":"https://api.github.com/licenses/mpl-2.0", + "node_id":"MDc6TGljZW5zZTE0" + }], + "minJRE":null, + "name":"\"Public Suffix List Library\"", + "version":"2025.8.0 d1420f641cf8523ae758342e8b5661287718d33f" + }, + { + "changes":"2025.9.0 d283cf7b0d097b0ac17b59e984e25827b91d4e69\t: AWS Submissions to the Public Suffix List - Q4 2024 (#2212)\n\n* Add rules for AWS Transfer Family web apps\r\n\r\n* Add rules for Amazon SageMaker Studio", + "date":"2025-01-10T12:11:47.825+01:00", + "dependencies":null, + "description":"The publicsuffix/list is a Java library that provides an updated version of Mozilla's Public Suffix List. This is an essential resource for web developers, as it allows users to parse domain names, extract their effective top-level domains (TLDs), or check whether a domain is a public suffix. It can be used to avoid 'supercookie' vulnerabilities, ensure correct cookie scope, and uphold the same-origin policy. (Library description by ChatGPT)", + "files":null, + "hashes":{"../src/org/appwork/utils/net/effective_tld_names.dat":"bd0982bdbf52e282c05da4685362d4db813ac4091216a4e5bc03477b6b283195"}, + "licenses":[{ + "name":"Mozilla Public License 2.0", + "spdx_id":"MPL-2.0", + "key":"mpl-2.0", + "url":"https://api.github.com/licenses/mpl-2.0", + "node_id":"MDc6TGljZW5zZTE0" + }], + "minJRE":null, + "name":"\"Public Suffix List Library\"", + "version":"2025.9.0 d283cf7b0d097b0ac17b59e984e25827b91d4e69" } ], "installed":{ - "changes":"2024.355.0 9e89e8b8a64027217dc22dda2e7c9dacd3d6ee6c\t: chore: update website URL (#2344)\r\n2024.358.0 a12a4d2dd9c8d27a4b187a42588f90577858ab5a\t: util: gTLD data autopull updates for 2024-12-23T15:16:32 UTC (#2357)\n\nCo-authored-by: GitHub <noreply@github.com>\r\n2024.359.0 60bb8d87995b9423bf55742da5360c68ec33ce84\t: remove `platter-app.com` (#2346)\r\n2024.359.1 f6f89086eb4c1e8d0c654ce5ba4cf425fb62bb96\t: remove `drud.io` and `drud.us` (#2347)\r\n2024.359.2 d2dd5f273d594b1a335fd3aadfc8c182df3ed787\t: remove `spacekit.io` (#2348)\r\n2024.359.3 eaebbab737795c84c6ab6159f8273fb2dfc84d9e\t: update email address (#2354)\r\n2024.359.4 304c0680cdcbc97c93a09a1b2dc387a7c411700a\t: add botdash domains (#2342)\r\n2024.359.5 b29032616d31b532d04092781b9aa61cf54c6fdc\t: remove Diher Solutions section (#2319)\r\n2024.359.6 9001793946007094caf862748aaeb7e5773541a9\t: remove `curv.dev` (#2317)\r\n2024.359.7 f229d7f87051bb6197b315f42adae05cb68e33b5\t: chore: formatting + fixes (#2329)", - "date":"2024-12-28T11:56:45.646+01:00", + "changes":"2025.10.0 b067df3f267dc1233e27e2d4d37c470886861370\t: add `edu.vg` (#2367)", + "date":"2025-01-13T11:46:30.732+01:00", "dependencies":null, "description":"The publicsuffix/list is a Java library that provides an updated version of Mozilla's Public Suffix List. This is an essential resource for web developers, as it allows users to parse domain names, extract their effective top-level domains (TLDs), or check whether a domain is a public suffix. It can be used to avoid 'supercookie' vulnerabilities, ensure correct cookie scope, and uphold the same-origin policy. (Library description by ChatGPT)", "files":[ @@ -508,6 +598,7 @@ ".github/workflows/validate.yml", ".gitignore", ".travis.yml", + "CODE_OF_CONDUCT.md", "CONTRIBUTING.md", "LICENSE", "linter", @@ -596,7 +687,7 @@ "tools/psltool", "tools/psltool/psltool.go" ], - "hashes":{"../src/org/appwork/utils/net/effective_tld_names.dat":"998c28a066398a1e05864242e95327b905ce33c564c0e392ea8f4f0db4a5c0fb"}, + "hashes":{"../src/org/appwork/utils/net/effective_tld_names.dat":"0271ce0c4bc237f906be5854430f04caa27c93accb54af80e36ca52480c628ab"}, "licenses":[{ "name":"Mozilla Public License 2.0", "spdx_id":"MPL-2.0", @@ -606,7 +697,7 @@ }], "minJRE":null, "name":"\"Public Suffix List Library\"", - "version":"2024.359.7 f229d7f87051bb6197b315f42adae05cb68e33b5" + "version":"2025.10.0 b067df3f267dc1233e27e2d4d37c470886861370" }, "minJRE":null, "provider":"github-clone", diff --git a/svn_utils/src/org/appwork/jna/windows/wmi/tests/WMITests.java b/svn_utils/src/org/appwork/jna/windows/wmi/tests/WMITests.java index 71253ab7..8eee05f8 100644 --- a/svn_utils/src/org/appwork/jna/windows/wmi/tests/WMITests.java +++ b/svn_utils/src/org/appwork/jna/windows/wmi/tests/WMITests.java @@ -40,6 +40,7 @@ import org.appwork.jna.windows.wmi.JNAWMIUtils; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; import org.appwork.utils.os.CrossSystem; /** @@ -47,6 +48,7 @@ * @date 20.11.2024 * */ +@TestDependency({ "org.appwork.jna.windows.wmi.JNAWMIUtils" }) public class WMITests extends AWTest { /** * @param args diff --git a/svn_utils/src/org/appwork/remoteapi/test/RemoteAPITest.java b/svn_utils/src/org/appwork/remoteapi/test/RemoteAPITest.java index 7c545cb3..57b95168 100644 --- a/svn_utils/src/org/appwork/remoteapi/test/RemoteAPITest.java +++ b/svn_utils/src/org/appwork/remoteapi/test/RemoteAPITest.java @@ -38,14 +38,15 @@ import org.appwork.remoteapi.RemoteAPI; import org.appwork.storage.TypeRef; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; /** * @author daniel * @date Apr 18, 2023 * */ +@TestDependency({ "org.appwork.remoteapi.RemoteAPI" }) public class RemoteAPITest extends AWTest { - public static enum TEST_ENUM { TEST1, TEST2; @@ -70,20 +71,16 @@ public void runTest() throws Exception { assertEquals(Boolean.FALSE, RemoteAPI.convert("\"false\"", Boolean.class)); assertEquals(Boolean.FALSE, RemoteAPI.convert("false", Object.class)); assertEquals("false", RemoteAPI.convert("\"false\"", Object.class)); - assertEquals(null, RemoteAPI.convert("null", Object.class)); assertEquals("null", RemoteAPI.convert("\"null\"", Object.class)); assertEquals(null, RemoteAPI.convert("null", String.class)); assertEquals("null", RemoteAPI.convert("\"null\"", String.class)); - assertEquals("test", RemoteAPI.convert("test", Object.class)); assertEquals("test", RemoteAPI.convert("\"test\"", Object.class)); assertEquals("test", RemoteAPI.convert("test", String.class)); assertEquals("test", RemoteAPI.convert("\"test\"", String.class)); - assertEquals("test\"", RemoteAPI.convert("test\"", Object.class)); assertEquals("test\"", RemoteAPI.convert("test\"", String.class)); - assertEquals("{test", RemoteAPI.convert("{test", String.class)); assertEquals("{test", RemoteAPI.convert("{test", Object.class)); assertEquals("{test}", RemoteAPI.convert("{test}", String.class)); @@ -96,7 +93,6 @@ public void runTest() throws Exception { assertEquals("{test}", RemoteAPI.convert("\"{test}\"", Object.class)); assertEquals("test}", RemoteAPI.convert("\"test}\"", String.class)); assertEquals("test}", RemoteAPI.convert("\"test}\"", Object.class)); - assertEquals("[test", RemoteAPI.convert("[test", String.class)); assertEquals("[test", RemoteAPI.convert("[test", Object.class)); assertEquals("[test]", RemoteAPI.convert("[test]", String.class)); @@ -109,15 +105,12 @@ public void runTest() throws Exception { assertEquals("[test]", RemoteAPI.convert("\"[test]\"", Object.class)); assertEquals("test]", RemoteAPI.convert("\"test]\"", String.class)); assertEquals("test]", RemoteAPI.convert("\"test]\"", Object.class)); - assertEquals("\"test", RemoteAPI.convert("\"test", Object.class)); assertEquals("\"test", RemoteAPI.convert("\"test", String.class)); - assertEquals(10, RemoteAPI.convert("10", Object.class)); assertEquals("10", RemoteAPI.convert("\"10\"", Object.class)); assertEquals(10, RemoteAPI.convert("10", Integer.class)); assertEquals(10, RemoteAPI.convert("\"10\"", Integer.class)); - assertEquals(TEST_ENUM.TEST1, RemoteAPI.convert("TEST1", new TypeRef<TEST_ENUM>() { }.getType())); assertEquals(TEST_ENUM.TEST2, RemoteAPI.convert("TEST2", new TypeRef<TEST_ENUM>() { @@ -126,17 +119,13 @@ public void runTest() throws Exception { }.getType())); assertEquals(TEST_ENUM.TEST2, RemoteAPI.convert("\"TEST2\"", new TypeRef<TEST_ENUM>() { }.getType())); - assertEquals(Long.MAX_VALUE, RemoteAPI.convert("" + Long.MAX_VALUE, Object.class)); assertEquals(Long.MIN_VALUE, RemoteAPI.convert("" + Long.MIN_VALUE, Object.class)); assertEquals(Long.MAX_VALUE, RemoteAPI.convert("" + Long.MAX_VALUE, Long.class)); assertEquals(Long.MIN_VALUE, RemoteAPI.convert("" + Long.MIN_VALUE, Long.class)); - assertEquals(Integer.MAX_VALUE, RemoteAPI.convert("" + Integer.MAX_VALUE, Object.class)); assertEquals(Integer.MIN_VALUE, RemoteAPI.convert("" + Integer.MIN_VALUE, Object.class)); - assertEquals(Integer.MAX_VALUE, RemoteAPI.convert("" + Integer.MAX_VALUE, Integer.class)); assertEquals(Integer.MIN_VALUE, RemoteAPI.convert("" + Integer.MIN_VALUE, Integer.class)); } - } diff --git a/svn_utils/src/org/appwork/storage/config/test/Test.java b/svn_utils/src/org/appwork/storage/config/test/Test.java index e9f22a02..06ebbdbc 100644 --- a/svn_utils/src/org/appwork/storage/config/test/Test.java +++ b/svn_utils/src/org/appwork/storage/config/test/Test.java @@ -46,11 +46,13 @@ import org.appwork.storage.config.handler.KeyHandler; import org.appwork.storage.config.handler.StorageHandler; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; /** * @author thomas * */ +@TestDependency({ "org.appwork.storage.config.JsonConfig" }) public class Test extends AWTest { public static void main(final String[] args) throws InterruptedException { run(); @@ -63,7 +65,6 @@ public static void main(final String[] args) throws InterruptedException { */ @Override public void runTest() throws Exception { - // new PerformanceObserver().start(); JsonConfig.create(MyInterface.class); /* @@ -73,9 +74,7 @@ public void runTest() throws Exception { * 2. Create your storage. The Factory will check your interface and throw Exceptions if it is malformed. This helps to find Errors * immediately. The Check not only checks directly used Datatypes, but runs through the whole TypeStructure of the interface. */ - final MyInterface jc = JsonConfig.create(MyInterface.class); - HashSet<String> storedSet = jc.getSet(); if (storedSet == null) { storedSet = new HashSet<String>(); @@ -84,29 +83,24 @@ public void runTest() throws Exception { jc.setSet(storedSet); // jc._getStorageHandler().getEventSender().addListener(new ConfigEventListener() { - @Override public void onConfigValidatorError(final KeyHandler<Object> keyHandler, final Object invalidValue, final ValidationException validateException) { - } + } @Override public void onConfigValueModified(final KeyHandler<Object> keyHandler, final Object newValue) { LogV3.info("New value: " + keyHandler); } - }); MyInterface.INT.getEventSender().addListener(new GenericConfigEventListener<Integer>() { - @Override public void onConfigValidatorError(final KeyHandler<Integer> keyHandler, final Integer invalidValue, final ValidationException validateException) { - } + } @Override public void onConfigValueModified(final KeyHandler<Integer> keyHandler, final Integer newValue) { - } - + } }); - double[] ar = jc.getDoubleArray(); jc.setDoubleArray(new double[] { 1.2, 3.4, 5.6 }); LogV3.info(JSonStorage.serializeToJson(jc.getObject())); @@ -118,7 +112,6 @@ public void onConfigValueModified(final KeyHandler<Integer> keyHandler, final In o.setA(36287); jc.setObject(o); jc.setIntArray(new int[] { 1, 2, 3, 4, 5 }); - final ArrayList<TestObject> list = new ArrayList<TestObject>(); list.add(o); list.add(new TestObject()); @@ -127,13 +120,10 @@ public void onConfigValueModified(final KeyHandler<Integer> keyHandler, final In LogV3.info(JSonStorage.serializeToJson(jc.getIntArray())); LogV3.info(JSonStorage.serializeToJson(jc.getObject())); LogV3.info(JSonStorage.serializeToJson(jc.getGenericList())); - LogV3.info(JSonStorage.serializeToJson(jc.getStringArray())); - /* * 4. get values by key */ - final StorageHandler<?> storageHandler = MyInterface.CFG._getStorageHandler(); LogV3.info("" + storageHandler.getValue("Float")); LogV3.info("" + MyInterface.CFG.getInt()); @@ -154,6 +144,5 @@ public void onConfigValueModified(final KeyHandler<Integer> keyHandler, final In * */ LogV3.info("" + MyInterface.CFG.getDefault()); - } } diff --git a/svn_utils/src/org/appwork/storage/config/test/WeakValueProviderBridgeTest.java b/svn_utils/src/org/appwork/storage/config/test/WeakValueProviderBridgeTest.java index 045a92b8..50dab2a4 100644 --- a/svn_utils/src/org/appwork/storage/config/test/WeakValueProviderBridgeTest.java +++ b/svn_utils/src/org/appwork/storage/config/test/WeakValueProviderBridgeTest.java @@ -49,6 +49,7 @@ import org.appwork.storage.flexijson.mapper.interfacestorage.PropertyHandlerImpl; import org.appwork.storage.flexijson.mapper.interfacestorage.PropertyHandlerListener; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; import org.appwork.utils.Application; /** @@ -56,6 +57,7 @@ * @date 22.08.2022 * */ +@TestDependency({ "org.appwork.storage.config.swing.ValueProviderListener" }) public class WeakValueProviderBridgeTest extends AWTest { public static void main(String[] args) { run(); @@ -126,7 +128,7 @@ public void onValueModified(ValueProvider<Boolean> owner, Boolean newValue) { @Override public void onValueValidationError(ValueProvider<Boolean> owner, Boolean invalidValue, Exception exception) { - } + } }, false); ValueProviderListener<Boolean> listener; bridge.register(listener = new ValueProviderListener<Boolean>() { @@ -137,7 +139,7 @@ public void onValueModified(ValueProvider<Boolean> owner, Boolean newValue) { @Override public void onValueValidationError(ValueProvider<Boolean> owner, Boolean invalidValue, Exception exception) { - } + } }, true); bridge.register(listener, false); bridge = null; @@ -215,7 +217,7 @@ public void onConfigValueModified(KeyHandler<Boolean> keyHandler, Boolean newVal @Override public void onConfigValidatorError(KeyHandler<Boolean> keyHandler, Boolean invalidValue, ValidationException validateException) { - } + } }, false); // KeyHandlerProviderBridge bridge = new KeyHandlerProviderBridge(keyHandler); @@ -227,7 +229,7 @@ public void onValueModified(ValueProvider<Boolean> owner, Boolean newValue) { @Override public void onValueValidationError(ValueProvider<Boolean> owner, Boolean invalidValue, Exception exception) { - } + } }, false); ValueProviderListener<Boolean> listener; bridge.register(listener = new ValueProviderListener<Boolean>() { diff --git a/svn_utils/src/org/appwork/storage/simplejson/mapper/test/SpecialMappers.java b/svn_utils/src/org/appwork/storage/simplejson/mapper/test/SpecialMappers.java index 87df8c85..85813936 100644 --- a/svn_utils/src/org/appwork/storage/simplejson/mapper/test/SpecialMappers.java +++ b/svn_utils/src/org/appwork/storage/simplejson/mapper/test/SpecialMappers.java @@ -45,6 +45,7 @@ import org.appwork.storage.simplejson.mapper.FileMapper; import org.appwork.storage.simplejson.mapper.URLMapper; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; import org.appwork.utils.Application; import org.appwork.utils.duration.TimeSpan; @@ -52,6 +53,7 @@ * @author thomas * */ +@TestDependency({ "org.appwork.storage.simplejson.mapper.ColorMapper", "org.appwork.storage.simplejson.mapper.FileMapper", "org.appwork.storage.simplejson.mapper.URLMapper" }) public class SpecialMappers extends AWTest { public static void main(final String[] args) { run(); diff --git a/svn_utils/src/org/appwork/storage/tests/RemoteAPI1InterfaceValidator.java b/svn_utils/src/org/appwork/storage/tests/RemoteAPI1InterfaceValidator.java index 5af08f98..c2b6d707 100644 --- a/svn_utils/src/org/appwork/storage/tests/RemoteAPI1InterfaceValidator.java +++ b/svn_utils/src/org/appwork/storage/tests/RemoteAPI1InterfaceValidator.java @@ -20,11 +20,13 @@ import org.appwork.storage.simplejson.mapper.ClassCache; import org.appwork.testframework.AWTest; import org.appwork.testframework.IgnoreInAWTest; +import org.appwork.testframework.TestDependency; import org.appwork.utils.ClassPathScanner; import org.appwork.utils.ReflectionUtils; import org.appwork.utils.reflection.Clazz; import org.appwork.utils.reflection.CompiledType; +@TestDependency({ "org.appwork.remoteapi.RemoteAPIInterface" }) public class RemoteAPI1InterfaceValidator extends AWTest { public static void main(String[] args) { run(); diff --git a/svn_utils/src/org/appwork/testframework/PostBuildRunner.java b/svn_utils/src/org/appwork/testframework/PostBuildRunner.java index 3a6010f5..e9a92ea5 100644 --- a/svn_utils/src/org/appwork/testframework/PostBuildRunner.java +++ b/svn_utils/src/org/appwork/testframework/PostBuildRunner.java @@ -48,6 +48,7 @@ import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Map.Entry; import org.appwork.builddecision.BuildDecisions; import org.appwork.exceptions.WTFException; @@ -117,11 +118,12 @@ public void publish(LogRecord2 record) { } } - static File BASE; - private static HashSet<String> MUST_RUN_WITHOUT_CLASSLOADER_ERRORS; - private static HashSet<String> DO_NOT_TRY_TO_RUN; - private static boolean PRINT_CLASSLOADER_ERRORS; - private static ArrayList<String> TESTS_OK; + static File BASE; + private static HashSet<String> MUST_RUN_WITHOUT_CLASSLOADER_ERRORS; + private static HashSet<String> DO_NOT_TRY_TO_RUN; + private static boolean PRINT_CLASSLOADER_ERRORS; + private static ArrayList<String> TESTS_OK; + private static HashMap<String, String> TESTS_FAILED = new HashMap<String, String>(); public static void main(final String[] args) throws Exception { BuildDecisions.setEnabled(false); @@ -142,6 +144,7 @@ protected String createPre(LogRecord2 record, String sourceString) { protected static void runAllTestsInClasspath(final String[] args) throws Exception { BASE = new File(args[0]); TESTS_OK = new ArrayList<String>(); + TESTS_FAILED = new HashMap<String, String>(); MUST_RUN_WITHOUT_CLASSLOADER_ERRORS = new HashSet<String>(); DO_NOT_TRY_TO_RUN = new HashSet<String>(); String sourceFolder = null; @@ -213,6 +216,9 @@ protected static void runAllTestsInClasspath(final String[] args) throws Excepti if (!anyTest) { throw new Exception("No Tests found. This is probably a build error. Check folder " + new File(BASE, "tests") + " for tests classes"); } + for (Entry<String, String> es : TESTS_FAILED.entrySet()) { + LogV3.info(header("FAILED") + es.getKey() + ": " + es.getValue()); + } int i = 0; main: for (String p : MUST_RUN_WITHOUT_CLASSLOADER_ERRORS) { for (String test : TESTS_OK) { @@ -223,7 +229,7 @@ protected static void runAllTestsInClasspath(final String[] args) throws Excepti LogV3.info(header("error") + "-force Test not found: " + p); i++; } - if (i > 0) { + if (i > 0 || TESTS_FAILED.size() > 0) { throw new Exception("Could not find tests for at least 1 -force pattern"); } LogV3.info(header("SUCCESS") + "Finished Post Build Tests"); @@ -295,10 +301,13 @@ protected static void runSingleTest(final String[] args) { if (Exceptions.getInstanceof(e, NoClassDefFoundError.class) != null) { logInfoAnyway("Add @TestDependency({\"" + Exceptions.getInstanceof(e, NoClassDefFoundError.class).getMessage().replace("/", ".") + "\"}) to " + testClass); System.err.println("Add @TestDependency({\"" + Exceptions.getInstanceof(e, NoClassDefFoundError.class).getMessage().replace("/", ".") + "\"}) to " + testClass); - } - if (Exceptions.getInstanceof(e, ClassNotFoundException.class) != null) { + LogV3.disableSysout(); + System.exit(3); + } else if (Exceptions.getInstanceof(e, ClassNotFoundException.class) != null) { logInfoAnyway("Add @TestDependency({\"" + Exceptions.getInstanceof(e, ClassNotFoundException.class).getMessage().replace("/", ".") + "\"}) to " + testClass); System.err.println("Add @TestDependency({\"" + Exceptions.getInstanceof(e, ClassNotFoundException.class).getMessage().replace("/", ".") + "\"}) to " + testClass); + LogV3.disableSysout(); + System.exit(3); } LogV3.disableSysout(); System.exit(1); @@ -421,7 +430,17 @@ public boolean accept(File pathname) { } int exit = result.getExitCode(); AWTest.setLoggerSilent(false, false); - if (exit == 2) { + if (exit == 3) { + // error, but do not stop tests - just log + LogV3.info(" >>" + header("failed") + "Exit with ExitCode " + exit); + if (result.getStdOutString().length() > 0) { + LogV3.info(" " + result.getStdOutString().replaceAll("[\r\n]{1,2}", "\r\n ")); + } + if (result.getErrOutString().length() > 0) { + LogV3.info(" " + result.getErrOutString().replaceAll("[\r\n]{1,2}", "\r\n ")); + } + TESTS_FAILED.put(cls.getName(), "Exit Code " + exit); + } else if (exit == 2) { if (mustRunWithoutClassloaderErrors(cls.getName())) { if (result.getStdOutString().length() > 0) { LogV3.info(" " + result.getStdOutString().replaceAll("[\r\n]{1,2}", "\r\n ")); @@ -447,8 +466,7 @@ public boolean accept(File pathname) { } TESTS_OK.add(cls.getName()); return; - } - if (exit == 1) { + } else if (exit == 1) { LogV3.info(" >>" + header("failed") + "Exit with ExitCode " + exit); if (result.getStdOutString().length() > 0) { LogV3.info(" " + result.getStdOutString().replaceAll("[\r\n]{1,2}", "\r\n ")); diff --git a/svn_utils/src/org/appwork/utils/awfc/test/AWFCTest.java b/svn_utils/src/org/appwork/utils/awfc/test/AWFCTest.java index 1b2ac223..aec1a163 100644 --- a/svn_utils/src/org/appwork/utils/awfc/test/AWFCTest.java +++ b/svn_utils/src/org/appwork/utils/awfc/test/AWFCTest.java @@ -40,6 +40,7 @@ import java.util.Random; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; import org.appwork.utils.Hash; import org.appwork.utils.awfc.AWFCEntry; import org.appwork.utils.awfc.AWFCInputStream; @@ -51,6 +52,7 @@ * @date Oct 13, 2022 * */ +@TestDependency({ "org.appwork.utils.awfc.AWFCInputStream" }) public class AWFCTest extends AWTest { public static void main(String[] args) { run(); diff --git a/svn_utils/src/org/appwork/utils/crypto/tests/AWSignTest.java b/svn_utils/src/org/appwork/utils/crypto/tests/AWSignTest.java index 2747e4a0..a65d05b4 100644 --- a/svn_utils/src/org/appwork/utils/crypto/tests/AWSignTest.java +++ b/svn_utils/src/org/appwork/utils/crypto/tests/AWSignTest.java @@ -43,6 +43,7 @@ import org.appwork.exceptions.WTFException; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; import org.appwork.utils.crypto.AWSign; import org.appwork.utils.crypto.SignatureViolationException; import org.appwork.utils.encoding.Base64; @@ -52,6 +53,7 @@ * @date 15.01.2022 * */ +@TestDependency({ "org.appwork.utils.crypto.SignatureViolationException" }) public class AWSignTest extends AWTest { public static void main(String[] args) { run(); @@ -60,11 +62,8 @@ public static void main(String[] args) { @Override public void runTest() throws Exception { final PublicKey pub = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.decode("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg+EQ1wHD62QGjzJalAkl1WjExeS345ZkCMtuyvqP3NLVpUbfZjc/IeHVi9qKBUPtV8ca8QfOZo8ACNIBvUxEiVy4YFE7vqZfBNV0uEz/kHSXxDlFeiv0+BFMgcXow0NYBjGDT02/1ddmjEMtnAXnjqUwlVPorzOmJoeuNSLCyCcOe0pKuF1yDha9TkEsaUcJ8kho+09kQvhMl5mKnuTUc81nIHHVb4GClRmFp1kfB9BbqPc9sL5jg1BrmjHMCD84HZk4OehxJ8AeA+veVRH2Gn6gcslPcrgNw1zK6VcXzCqsuZCAejAyDHnX+jay1SaxmHDgk5jc+agee+M2+QPiwQIDAQAB"))); - final PrivateKey pk = KeyFactory - .getInstance("RSA") - .generatePrivate( - new PKCS8EncodedKeySpec( - Base64.decode("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCD4RDXAcPrZAaPMlqUCSXVaMTF5LfjlmQIy27K+o/c0tWlRt9mNz8h4dWL2ooFQ+1XxxrxB85mjwAI0gG9TESJXLhgUTu+pl8E1XS4TP+QdJfEOUV6K/T4EUyBxejDQ1gGMYNPTb/V12aMQy2cBeeOpTCVU+ivM6Ymh641IsLIJw57Skq4XXIOFr1OQSxpRwnySGj7T2RC+EyXmYqe5NRzzWcgcdVvgYKVGYWnWR8H0Fuo9z2wvmODUGuaMcwIPzgdmTg56HEnwB4D695VEfYafqByyU9yuA3DXMrpVxfMKqy5kIB6MDIMedf6NrLVJrGYcOCTmNz5qB574zb5A+LBAgMBAAECggEAWLi/lYZQgjoG16tumI0W8N3NE71toST6I5iI7vFme48zwD9P5/pe9LJz8eSSWjx6nkUK8QDpcMHfqg9usCVxLmA8gj/kS7ytzBi2r47NmCd4OsC05x5PbdxldiDpGQRjYbdJub56wqhpCw/ezUqDn8muR6ftsIC01NMO9hxuoiv1tE1GXZwBo36YSPb5NsB0Og5p0w8gwogXo0/TLIOJVy5ysZGACrXMaSN7DX/XP5hp4rXEfbY9vQdegVShejIKOIc9r5+0btRPjGP7YkMRWvTQQt43jWgI8cBIFUcZ4fYmwegzGnl1OONVzXjum10B2E3R2vmDEZqrLVB22I5Y4QKBgQDq0W0/g9H7hyd0NroZP8yP0/bOZO6ZYzUNMRQgZ/BO76yMUId6+wi0RREzqya+r/ur+kDXCs+liTlbJ+KyjRv29ls40eDW5OpCG9ccFguzg1CUpyIRu2obKC5i59x3I4KGiUplumKcSE8QILD09DslvoSf2pHBIQKZNEdVMROObQKBgQCPxoGORYshbsptqZ5batMTWAeb5xeBn6rxBNDWAzeD+qXazOsTWYgU4310nq/Vqyc7UU18VPoRTTflUyhJFoFxJRjTEHxa/hKjIOGPYayCK2EHrMXHoSxZsUvSbSH1Y84zFAbDcRPylXg1pGnn5CyDB5jijS6mQxnT94TRgX1hJQKBgFwzcUcgNmIiFn7OQlJJt8O9wcoW3Y0C5EDSxYlX5obIGyNZN2k1ipxmBjQYfvUe2p4TfEQzrYbdE9VUGvJq79EPuI/d8P/QEJ92mQchLOUGqaxE197IjQguxc/2JJ3vJoA3Bixde/zLc6fsfi8getz+Ksstok+H66JGYb/0ri4dAoGAFnZeAVtOHGAR0kZAzmmHJquHLM1S99Z5P4SQGA+SmdUMGn4PcAt53kGYdSLht9EwpOzT3UvtccyNog926MxSVtoD4d3ef9zYDpJxixQofoHGfAt7LvA4XJ79iJeySYNZUNOdJuXAxxKhIEhan3cfmS0Trrl+A03SeDJgltbTPt0CgYEA1uPP5gpL029gtx3shiQFblpVl3AhUE1dmDITJYrGqD+06Z+nPHu73kOnVdPKgy9wYIIxcyx/DrQfcT5e1+IZy9bZ5OOIUVi9qNsQ1RhvFzEwo8tiE/1LX7XUIC2gIjyY0Q+VXLk03UgjV7qAgOg4X/foetGZn2NHmc4NUUaCoNE="))); + final PrivateKey pk = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.decode( + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCD4RDXAcPrZAaPMlqUCSXVaMTF5LfjlmQIy27K+o/c0tWlRt9mNz8h4dWL2ooFQ+1XxxrxB85mjwAI0gG9TESJXLhgUTu+pl8E1XS4TP+QdJfEOUV6K/T4EUyBxejDQ1gGMYNPTb/V12aMQy2cBeeOpTCVU+ivM6Ymh641IsLIJw57Skq4XXIOFr1OQSxpRwnySGj7T2RC+EyXmYqe5NRzzWcgcdVvgYKVGYWnWR8H0Fuo9z2wvmODUGuaMcwIPzgdmTg56HEnwB4D695VEfYafqByyU9yuA3DXMrpVxfMKqy5kIB6MDIMedf6NrLVJrGYcOCTmNz5qB574zb5A+LBAgMBAAECggEAWLi/lYZQgjoG16tumI0W8N3NE71toST6I5iI7vFme48zwD9P5/pe9LJz8eSSWjx6nkUK8QDpcMHfqg9usCVxLmA8gj/kS7ytzBi2r47NmCd4OsC05x5PbdxldiDpGQRjYbdJub56wqhpCw/ezUqDn8muR6ftsIC01NMO9hxuoiv1tE1GXZwBo36YSPb5NsB0Og5p0w8gwogXo0/TLIOJVy5ysZGACrXMaSN7DX/XP5hp4rXEfbY9vQdegVShejIKOIc9r5+0btRPjGP7YkMRWvTQQt43jWgI8cBIFUcZ4fYmwegzGnl1OONVzXjum10B2E3R2vmDEZqrLVB22I5Y4QKBgQDq0W0/g9H7hyd0NroZP8yP0/bOZO6ZYzUNMRQgZ/BO76yMUId6+wi0RREzqya+r/ur+kDXCs+liTlbJ+KyjRv29ls40eDW5OpCG9ccFguzg1CUpyIRu2obKC5i59x3I4KGiUplumKcSE8QILD09DslvoSf2pHBIQKZNEdVMROObQKBgQCPxoGORYshbsptqZ5batMTWAeb5xeBn6rxBNDWAzeD+qXazOsTWYgU4310nq/Vqyc7UU18VPoRTTflUyhJFoFxJRjTEHxa/hKjIOGPYayCK2EHrMXHoSxZsUvSbSH1Y84zFAbDcRPylXg1pGnn5CyDB5jijS6mQxnT94TRgX1hJQKBgFwzcUcgNmIiFn7OQlJJt8O9wcoW3Y0C5EDSxYlX5obIGyNZN2k1ipxmBjQYfvUe2p4TfEQzrYbdE9VUGvJq79EPuI/d8P/QEJ92mQchLOUGqaxE197IjQguxc/2JJ3vJoA3Bixde/zLc6fsfi8getz+Ksstok+H66JGYb/0ri4dAoGAFnZeAVtOHGAR0kZAzmmHJquHLM1S99Z5P4SQGA+SmdUMGn4PcAt53kGYdSLht9EwpOzT3UvtccyNog926MxSVtoD4d3ef9zYDpJxixQofoHGfAt7LvA4XJ79iJeySYNZUNOdJuXAxxKhIEhan3cfmS0Trrl+A03SeDJgltbTPt0CgYEA1uPP5gpL029gtx3shiQFblpVl3AhUE1dmDITJYrGqD+06Z+nPHu73kOnVdPKgy9wYIIxcyx/DrQfcT5e1+IZy9bZ5OOIUVi9qNsQ1RhvFzEwo8tiE/1LX7XUIC2gIjyY0Q+VXLk03UgjV7qAgOg4X/foetGZn2NHmc4NUUaCoNE="))); byte[] sign = AWSign.createSign("Apfelbaum".getBytes(), pk, true); AWSign.verify("Apfelbaum".getBytes(), pub, sign, true); try { diff --git a/svn_utils/src/org/appwork/utils/net/effective_tld_names.dat b/svn_utils/src/org/appwork/utils/net/effective_tld_names.dat index 295ad3ef..a7c9eab5 100644 --- a/svn_utils/src/org/appwork/utils/net/effective_tld_names.dat +++ b/svn_utils/src/org/appwork/utils/net/effective_tld_names.dat @@ -22,7 +22,7 @@ org.ac // Confirmed by Amadeu Abril i Abril (CORE) <amadeu.abril@corenic.org> 2024-11-17 ad -// ae : https://tdra.gov.ae/en/aeda/ae-policies +// ae : https://www.iana.org/domains/root/db/ae.html ae ac.ae co.ae @@ -839,7 +839,6 @@ yn.cn zj.cn // co : https://www.iana.org/domains/root/db/co.html -// https://www.cointernet.com.co/registra // https://www.cointernet.com.co/como-funciona-un-dominio-restringido // Confirmed by registry <gonzalo@cointernet.com.co> 2024-11-18 co @@ -1186,7 +1185,7 @@ org.gp // gq : https://www.iana.org/domains/root/db/gq.html gq -// gr : https://grweb.ics.forth.gr/english/1617-B-2005.html +// gr : https://www.iana.org/domains/root/db/gr.html // Submitted by registry <segred@ics.forth.gr> gr com.gr @@ -1263,7 +1262,7 @@ org.hk // hm : https://www.iana.org/domains/root/db/hm.html hm -// hn : http://www.nic.hn/politicas/ps02,,05.html +// hn : https://www.iana.org/domains/root/db/hn.html hn com.hn edu.hn @@ -1299,7 +1298,7 @@ pro.ht rel.ht shop.ht -// hu : http://www.domain.hu/domain/English/sld.html +// hu : https://www.iana.org/domains/root/db/hu.html // Confirmed by registry <pasztor@iszt.hu> 2008-06-12 hu 2000.hu @@ -1334,7 +1333,7 @@ tozsde.hu utazas.hu video.hu -// id : https://pandi.id/en/domain/registration-requirements/ +// id : https://www.iana.org/domains/root/db/id.html id ac.id biz.id @@ -1897,7 +1896,7 @@ vs.it vt.it vv.it -// je : http://www.channelisles.net/register-domains/ +// je : https://www.iana.org/domains/root/db/je.html // Confirmed by registry <nigel@channelisles.net> 2013-11-28 je co.je @@ -3755,7 +3754,7 @@ org.kg // kh : http://www.mptc.gov.kh/dns_registration.htm *.kh -// ki : http://www.ki/dns/index.html +// ki : https://www.iana.org/domains/root/db/ki.html ki biz.ki com.ki @@ -3902,7 +3901,7 @@ org.lc // li : https://www.iana.org/domains/root/db/li.html li -// lk : https://www.nic.lk/index.php/domain-registration/lk-domain-naming-structure +// lk : https://www.iana.org/domains/root/db/lk.html lk ac.lk assn.lk @@ -3950,7 +3949,7 @@ gov.lt // lu : http://www.dns.lu/en/ lu -// lv : http://www.nic.lv/DNS/En/generic.php +// lv : https://www.iana.org/domains/root/db/lv.html lv asn.lv com.lv @@ -4031,8 +4030,7 @@ name.mk net.mk org.mk -// ml : http://www.gobin.info/domainname/ml-template.doc -// see also: https://www.iana.org/domains/root/db/ml.html +// ml : https://www.iana.org/domains/root/db/ml.html ml com.ml edu.ml @@ -4073,7 +4071,7 @@ mq mr gov.mr -// ms : http://www.nic.ms/pdf/MS_Domain_Name_Rules.pdf +// ms : https://www.iana.org/domains/root/db/ms.html ms com.ms edu.ms @@ -5094,7 +5092,7 @@ org.pf // pg : https://www.iana.org/domains/root/db/pg.html *.pg -// ph : http://www.domains.ph/FAQ2.asp +// ph : https://www.iana.org/domains/root/db/ph.html // Submitted by registry <jed@email.com.ph> ph com.ph @@ -5344,7 +5342,7 @@ zgorzelec.pl // pm : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf pm -// pn : http://www.government.pn/PnRegistry/policies.htm +// pn : https://www.iana.org/domains/root/db/pn.html pn co.pn edu.pn @@ -5413,7 +5411,7 @@ publ.pt pw gov.pw -// py : http://www.nic.py/pautas.html#seccion_9 +// py : https://www.iana.org/domains/root/db/py.html // Submitted by registry py com.py @@ -5469,7 +5467,7 @@ org.rs // Submitted by George Georgievsky <gug@cctld.ru> ru -// rw : https://www.ricta.org.rw/sites/default/files/resources/registry_registrar_contract_0.pdf +// rw : https://www.iana.org/domains/root/db/rw.html rw ac.rw co.rw @@ -5507,7 +5505,7 @@ gov.sc net.sc org.sc -// sd : http://www.isoc.sd/sudanic.isoc.sd/billing_pricing.htm +// sd : https://www.iana.org/domains/root/db/sd.html // Submitted by registry <admin@isoc.sd> sd com.sd @@ -5654,7 +5652,7 @@ store.st // su : https://www.iana.org/domains/root/db/su.html su -// sv : http://www.svnet.org.sv/niveldos.pdf +// sv : https://www.iana.org/domains/root/db/sv.html sv com.sv edu.sv @@ -5668,7 +5666,6 @@ sx gov.sx // sy : https://www.iana.org/domains/root/db/sy.html -// see also: http://www.gobin.info/domainname/sy.doc sy com.sy edu.sy @@ -6274,12 +6271,11 @@ tec.ve web.ve // vg : https://www.iana.org/domains/root/db/vg.html +// Confirmed by registry <tld.ops@centralnic.com> 2025-01-10 vg +edu.vg -// vi : http://www.nic.vi/newdomainform.htm -// http://www.nic.vi/Domain_Rules/body_domain_rules.html indicates some other -// TLDs are "reserved", such as edu.vi and gov.vi, but doesn't actually say they -// are available for registration (which they do not seem to be). +// vi : https://www.iana.org/domains/root/db/vi.html vi co.vi com.vi @@ -6686,7 +6682,7 @@ mil.ye net.ye org.ye -// za : https://www.zadna.org.za/content/page/domain-information/ +// za : https://www.iana.org/domains/root/db/za.html ac.za agric.za alt.za @@ -11935,7 +11931,7 @@ notebook.cn-northwest-1.sagemaker.com.cn // Amazon SageMaker Studio // Submitted by AWS Security <psl-maintainers@amazon.com> -// Reference: 69c723d9-6e1a-4bff-a203-48eecd203183 +// Reference: 475f237e-ab88-4041-9f41-7cfccdf66aeb studio.af-south-1.sagemaker.aws studio.ap-east-1.sagemaker.aws studio.ap-northeast-1.sagemaker.aws @@ -11947,6 +11943,7 @@ studio.ap-southeast-2.sagemaker.aws studio.ap-southeast-3.sagemaker.aws studio.ca-central-1.sagemaker.aws studio.eu-central-1.sagemaker.aws +studio.eu-central-2.sagemaker.aws studio.eu-north-1.sagemaker.aws studio.eu-south-1.sagemaker.aws studio.eu-south-2.sagemaker.aws @@ -12119,6 +12116,19 @@ awsglobalaccelerator.com // Reference: 83385945-225f-416e-9aa0-ad0632bfdcee *.private.repost.aws +// AWS Transfer Family web apps +// Submitted by AWS Security <psl-maintainers@amazon.com> +// Reference: 67e9cfe6-ac57-49c7-b197-6652711c8e8d +transfer-webapp.ap-northeast-1.on.aws +transfer-webapp.ap-southeast-1.on.aws +transfer-webapp.ap-southeast-2.on.aws +transfer-webapp.eu-central-1.on.aws +transfer-webapp.eu-north-1.on.aws +transfer-webapp.eu-west-1.on.aws +transfer-webapp.us-east-1.on.aws +transfer-webapp.us-east-2.on.aws +transfer-webapp.us-west-2.on.aws + // eero // Submitted by Yue Kang <eero-dynamic-dns@amazon.com> // Reference: 264afe70-f62c-4c02-8ab9-b5281ed24461 @@ -12431,6 +12441,10 @@ cloudaccess.host freesite.host cloudaccess.net +// Cloudbees, Inc. : https://www.cloudbees.com/ +// Submitted by Mohideen Shajith <jaas-sre-infra@cloudbees.com> +cloudbeesusercontent.io + // Cloudera, Inc. : https://www.cloudera.com/ // Submitted by Kedarnath Waikar <security@cloudera.com> *.cloudera.site @@ -13578,14 +13592,6 @@ grayjayleagues.com günstigbestellen.de günstigliefern.de -// Hakaran group : http://hakaran.cz -// Submitted by Arseniy Sokolov <security@hakaran.cz> -fin.ci -free.hr -caa.li -ua.rs -conf.se - // Häkkinen.fi : https://www.häkkinen.fi/ // Submitted by Eero Häkkinen <Eero+psl@Häkkinen.fi> häkkinen.fi @@ -13987,6 +13993,11 @@ leadpages.co lpages.co lpusercontent.com +// Liara : https://liara.ir +// Submitted by Amirhossein Badinloo <info@liara.ir> +liara.run +iran.liara.run + // libp2p project : https://libp2p.io // Submitted by Interplanetary Shipyard <domains@ipshipyard.com> libp2p.direct @@ -14683,6 +14694,14 @@ priv.at // Submitted by Martin Meier <admin@protonet.io> protonet.io +// PSL Sandbox : https://psl.hrsn.dev +// Submitted by William Harrison <psl@hrsn.net> +sub.psl.hrsn.dev +*.wc.psl.hrsn.dev +!ignored.wc.psl.hrsn.dev +*.sub.wc.psl.hrsn.dev +!ignored.sub.wc.psl.hrsn.dev + // Publication Presse Communication SARL : https://ppcom.fr // Submitted by Yaacov Akiba Slama <admin@chirurgiens-dentistes-en-france.fr> chirurgiens-dentistes-en-france.fr diff --git a/svn_utils/src/org/appwork/utils/reflection/tests/CompiledTypeTests.java b/svn_utils/src/org/appwork/utils/reflection/tests/CompiledTypeTests.java index 9cceed70..28374579 100644 --- a/svn_utils/src/org/appwork/utils/reflection/tests/CompiledTypeTests.java +++ b/svn_utils/src/org/appwork/utils/reflection/tests/CompiledTypeTests.java @@ -46,6 +46,7 @@ import org.appwork.storage.simplejson.MinimalMemoryMap; import org.appwork.storage.simplejson.mapper.ClassCache; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; import org.appwork.txtresource.LocaleMap; import org.appwork.utils.KeyValueEntry; import org.appwork.utils.KeyValueStringEntry; @@ -61,6 +62,7 @@ * @date 17.10.2022 * */ +@TestDependency({ "org.appwork.storage.simplejson.MinimalMemoryMap" }) public class CompiledTypeTests<T extends Object> extends AWTest { public static enum MyEnum { A, diff --git a/svn_utils/src/org/appwork/utils/swing/tests/CheckGraphicsProxy.java b/svn_utils/src/org/appwork/utils/swing/tests/CheckGraphicsProxy.java index 5842b9ae..76b0c03f 100644 --- a/svn_utils/src/org/appwork/utils/swing/tests/CheckGraphicsProxy.java +++ b/svn_utils/src/org/appwork/utils/swing/tests/CheckGraphicsProxy.java @@ -37,6 +37,7 @@ import java.lang.reflect.Modifier; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; import org.appwork.utils.JVMVersion; import org.appwork.utils.swing.Graphics2DProxy; @@ -45,6 +46,7 @@ * @date 29.01.2024 * */ +@TestDependency({ "org.appwork.utils.swing.Graphics2DProxy" }) public class CheckGraphicsProxy extends AWTest { /** * @see org.appwork.testframework.TestInterface#runTest() diff --git a/svn_utils/src/org/appwork/utils/swing/tests/EDTTest.java b/svn_utils/src/org/appwork/utils/swing/tests/EDTTest.java index ad3a95d7..5f777649 100644 --- a/svn_utils/src/org/appwork/utils/swing/tests/EDTTest.java +++ b/svn_utils/src/org/appwork/utils/swing/tests/EDTTest.java @@ -40,6 +40,7 @@ import org.appwork.exceptions.WTFException; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; import org.appwork.utils.Application; import org.appwork.utils.swing.EDT; @@ -48,6 +49,7 @@ * @date Mar 1, 2024 * */ +@TestDependency({ "org.appwork.utils.swing.EDT" }) public class EDTTest extends AWTest { /** * @param args diff --git a/svn_utils/src/org/appwork/utils/test/LEB128Test.java b/svn_utils/src/org/appwork/utils/test/LEB128Test.java index 23faa3fb..bcebe7a4 100644 --- a/svn_utils/src/org/appwork/utils/test/LEB128Test.java +++ b/svn_utils/src/org/appwork/utils/test/LEB128Test.java @@ -37,6 +37,7 @@ import java.io.ByteArrayOutputStream; import org.appwork.testframework.AWTest; +import org.appwork.testframework.TestDependency; import org.appwork.utils.LEB128; /** @@ -44,6 +45,7 @@ * @date Aug 24, 2023 * */ +@TestDependency({ "org.appwork.utils.LEB128" }) public class LEB128Test extends AWTest { public static void main(String[] args) { run(); diff --git a/svn_utils/src/org/appwork/utils/zip/tests/CompressedEntriesIndexTest.java b/svn_utils/src/org/appwork/utils/zip/tests/CompressedEntriesIndexTest.java index aae0f38d..f9cecd69 100644 --- a/svn_utils/src/org/appwork/utils/zip/tests/CompressedEntriesIndexTest.java +++ b/svn_utils/src/org/appwork/utils/zip/tests/CompressedEntriesIndexTest.java @@ -48,6 +48,7 @@ import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; +import org.appwork.testframework.TestDependency; import org.appwork.utils.StringUtils; import org.appwork.utils.zip.CompressedEntriesIndex; @@ -56,6 +57,7 @@ * @date Aug 24, 2023 * */ +@TestDependency({ "org.appwork.utils.zip.CompressedEntriesIndex" }) public class CompressedEntriesIndexTest extends OnClassPathZipJarTests { public static void main(String[] args) { run(); diff --git a/svn_utils/src/org/appwork/utils/zip/tests/SignedZipsTest.java b/svn_utils/src/org/appwork/utils/zip/tests/SignedZipsTest.java index 1bd2adb3..d900719c 100644 --- a/svn_utils/src/org/appwork/utils/zip/tests/SignedZipsTest.java +++ b/svn_utils/src/org/appwork/utils/zip/tests/SignedZipsTest.java @@ -49,6 +49,7 @@ import java.util.zip.ZipException; import org.appwork.loggingv3.LogV3; +import org.appwork.testframework.TestDependency; import org.appwork.utils.Application; import org.appwork.utils.Exceptions; import org.appwork.utils.Files; @@ -67,6 +68,7 @@ * @date Aug 24, 2023 * */ +@TestDependency({ "org.appwork.utils.zip.ZipIOWriter" }) public class SignedZipsTest extends OnClassPathZipJarTests { public static void main(String[] args) { run();