mirror of
https://github.com/mirror/jdownloader.git
synced 2024-11-26 21:40:38 +00:00
*General*
- PluginForHost: enoughTrafficFor: added IDE only code for special multihost traffic calculation - ZeveraCore: setVerifiedFilesize - AccountTooltip: getDomainInfos early return and set domains with subdomain - DomainInfo: added ability to allow/set domain with subdomain for e.g. drive.google.com and mh.takefile.link (at this moment such domains would just be displayed twice in list of supported multihosts which is just wrong) - NewRuleAction: refactored to early return, allow subdomains refs #90321 *Plugins: Fixes/Changes/Maintenance* - BooruOrgCrawler: added safebooruorg and updated pattern RE forum 90201 - BitchuteComChannel: fixed and added GEO-blocked errorhandling RE forum 88455 - MixCloudComCrawler: set estimated filesize - MixCloudCom: minor changes git-svn-id: svn://svn.jdownloader.org/jdownloader/trunk@49846 ebf7c1c2-ba36-0410-9fe8-c592906822b4 Former-commit-id: efa796b87da86d868314e7eeb861b5c7ee3c6feb
This commit is contained in:
parent
eca4d1b14f
commit
509baa63a4
@ -56,7 +56,7 @@ public class AccountCache implements Iterable<CachedAccount> {
|
||||
}
|
||||
this.plugin = plugin;
|
||||
this.host = host;
|
||||
pluginDomainInfo = plugin != null ? DomainInfo.getInstance(plugin.getHost()) : null;
|
||||
pluginDomainInfo = plugin != null ? DomainInfo.getInstance(plugin.getHost(), true) : null;
|
||||
}
|
||||
|
||||
public final Account getAccount() {
|
||||
|
@ -138,26 +138,29 @@ public class AccountTooltip extends PanelToolTip {
|
||||
return super.getPreferredSize();
|
||||
}
|
||||
|
||||
private List<DomainInfo> getDomainInfos(AccountServiceCollection accountCollection) {
|
||||
HashSet<DomainInfo> domains = new HashSet<DomainInfo>();
|
||||
for (Account acc : accountCollection) {
|
||||
AccountInfo ai = acc.getAccountInfo();
|
||||
if (ai != null) {
|
||||
final List<String> supported = ai.getMultiHostSupport();
|
||||
if (supported != null) {
|
||||
/*
|
||||
* synchronized on list because plugins can change the list in runtime
|
||||
*/
|
||||
for (String sup : supported) {
|
||||
LazyHostPlugin plg = HostPluginController.getInstance().get(sup);
|
||||
if (plg != null) {
|
||||
domains.add(DomainInfo.getInstance(plg.getHost()));
|
||||
}
|
||||
}
|
||||
private List<DomainInfo> getDomainInfos(final AccountServiceCollection accountCollection) {
|
||||
final HashSet<DomainInfo> domains = new HashSet<DomainInfo>();
|
||||
for (final Account acc : accountCollection) {
|
||||
final AccountInfo ai = acc.getAccountInfo();
|
||||
if (ai == null) {
|
||||
continue;
|
||||
}
|
||||
final List<String> supported = ai.getMultiHostSupport();
|
||||
if (supported == null) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* synchronized on list because plugins can change the list in runtime
|
||||
*/
|
||||
for (final String sup : supported) {
|
||||
final LazyHostPlugin plg = HostPluginController.getInstance().get(sup);
|
||||
if (plg == null) {
|
||||
continue;
|
||||
}
|
||||
domains.add(DomainInfo.getInstance(plg.getHost(), true));
|
||||
}
|
||||
}
|
||||
ArrayList<DomainInfo> ret = new ArrayList<DomainInfo>(domains);
|
||||
final ArrayList<DomainInfo> ret = new ArrayList<DomainInfo>(domains);
|
||||
Collections.sort(ret, new Comparator<DomainInfo>() {
|
||||
@Override
|
||||
public int compare(DomainInfo o1, DomainInfo o2) {
|
||||
|
@ -13,7 +13,6 @@
|
||||
//
|
||||
// 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.gui.swing.jdgui.components.premiumbar;
|
||||
|
||||
import java.awt.HeadlessException;
|
||||
@ -34,19 +33,6 @@ import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import jd.SecondLevelLaunch;
|
||||
import jd.controlling.AccountController;
|
||||
import jd.controlling.AccountControllerEvent;
|
||||
import jd.controlling.AccountControllerListener;
|
||||
import jd.gui.swing.dialog.AddAccountDialog;
|
||||
import jd.gui.swing.jdgui.JDGui;
|
||||
import jd.gui.swing.jdgui.views.settings.ConfigurationView;
|
||||
import jd.gui.swing.jdgui.views.settings.panels.accountmanager.AccountManagerSettings;
|
||||
import jd.plugins.Account;
|
||||
import jd.plugins.AccountInfo;
|
||||
import jd.plugins.PluginForHost;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.appwork.scheduler.DelayedRunnable;
|
||||
import org.appwork.storage.config.JsonConfig;
|
||||
import org.appwork.storage.config.ValidationException;
|
||||
@ -69,12 +55,22 @@ import org.jdownloader.settings.GraphicalUserInterfaceSettings;
|
||||
import org.jdownloader.settings.GraphicalUserInterfaceSettings.PremiumStatusBarDisplay;
|
||||
import org.jdownloader.settings.staticreferences.CFG_GUI;
|
||||
|
||||
import jd.SecondLevelLaunch;
|
||||
import jd.controlling.AccountController;
|
||||
import jd.controlling.AccountControllerEvent;
|
||||
import jd.controlling.AccountControllerListener;
|
||||
import jd.gui.swing.dialog.AddAccountDialog;
|
||||
import jd.gui.swing.jdgui.JDGui;
|
||||
import jd.gui.swing.jdgui.views.settings.ConfigurationView;
|
||||
import jd.gui.swing.jdgui.views.settings.panels.accountmanager.AccountManagerSettings;
|
||||
import jd.plugins.Account;
|
||||
import jd.plugins.AccountInfo;
|
||||
import jd.plugins.PluginForHost;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
public class ServicePanel extends JPanel implements MouseListener, AccountTooltipOwner {
|
||||
|
||||
private static final long serialVersionUID = 7290466989514173719L;
|
||||
|
||||
private DelayedRunnable redrawTimer;
|
||||
|
||||
private final CopyOnWriteArrayList<ServicePanelExtender> extender;
|
||||
private static ServicePanel INSTANCE = new ServicePanel();
|
||||
static {
|
||||
@ -82,7 +78,7 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
throw new HeadlessException();
|
||||
}
|
||||
}
|
||||
private AtomicBoolean redrawing = new AtomicBoolean(false);
|
||||
private AtomicBoolean redrawing = new AtomicBoolean(false);
|
||||
|
||||
public static ServicePanel getInstance() {
|
||||
return INSTANCE;
|
||||
@ -110,13 +106,10 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
|
||||
private ServicePanel() {
|
||||
super(new MigLayout("ins 0 2 0", "0[]0[]0[]0[]0", "0[]0"));
|
||||
|
||||
extender = new CopyOnWriteArrayList<ServicePanelExtender>();
|
||||
this.setOpaque(false);
|
||||
final ScheduledExecutorService scheduler = DelayedRunnable.getNewScheduledExecutorService();
|
||||
|
||||
redrawTimer = new DelayedRunnable(scheduler, 1000, 5000) {
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return "PremiumStatusRedraw";
|
||||
@ -124,15 +117,11 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
|
||||
@Override
|
||||
public void delayedrun() {
|
||||
|
||||
redraw();
|
||||
}
|
||||
|
||||
};
|
||||
redraw();
|
||||
|
||||
CFG_GUI.PREMIUM_STATUS_BAR_DISPLAY.getEventSender().addListener(new GenericConfigEventListener<Enum>() {
|
||||
|
||||
@Override
|
||||
public void onConfigValidatorError(KeyHandler<Enum> keyHandler, Enum invalidValue, ValidationException validateException) {
|
||||
}
|
||||
@ -143,7 +132,6 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
}
|
||||
});
|
||||
org.jdownloader.settings.staticreferences.CFG_GENERAL.USE_AVAILABLE_ACCOUNTS.getEventSender().addListener(new GenericConfigEventListener<Boolean>() {
|
||||
|
||||
public void onConfigValueModified(KeyHandler<Boolean> keyHandler, Boolean newValue) {
|
||||
redraw();
|
||||
}
|
||||
@ -152,15 +140,12 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
}
|
||||
});
|
||||
SecondLevelLaunch.ACCOUNTLIST_LOADED.executeWhenReached(new Runnable() {
|
||||
|
||||
public void run() {
|
||||
new Thread() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
redrawTimer.run();
|
||||
AccountController.getInstance().getEventSender().addListener(new AccountControllerListener() {
|
||||
|
||||
public void onAccountControllerEvent(AccountControllerEvent event) {
|
||||
if (org.jdownloader.settings.staticreferences.CFG_GENERAL.USE_AVAILABLE_ACCOUNTS.isEnabled()) {
|
||||
redrawTimer.run();
|
||||
@ -198,18 +183,15 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasValidAccount) {
|
||||
sb.append("[]0");
|
||||
}
|
||||
setLayout(new MigLayout("ins 0 2 0 0", sb.toString(), "[22!]"));
|
||||
for (ServiceCollection<?> s : services) {
|
||||
|
||||
final JComponent c = s.createIconComponent(ServicePanel.this);
|
||||
if (c != null) {
|
||||
add(c, "gapleft 0,gapright 0");
|
||||
}
|
||||
|
||||
}
|
||||
if (!hasValidAccount && CFG_GUI.CFG.isStatusBarAddPremiumButtonVisible()) {
|
||||
ExtButton addPremium = new ExtButton(new AppAction() {
|
||||
@ -223,13 +205,11 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
JDGui.getInstance().setContent(ConfigurationView.getInstance(), true);
|
||||
ConfigurationView.getInstance().setSelectedSubPanel(AccountManagerSettings.class);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AddAccountDialog.showDialog(null, null);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
addPremium.setRolloverEffectEnabled(true);
|
||||
@ -237,7 +217,6 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
addPremium.setIcon(new AbstractIcon(IconKey.ICON_ADD, 18));
|
||||
// addPremium.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
add(addPremium, "height 20!,gapright 10!");
|
||||
|
||||
}
|
||||
revalidate();
|
||||
repaint();
|
||||
@ -272,7 +251,6 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
public int compare(Account o1, Account o2) {
|
||||
return compare(o1.isMultiHost(), o2.isMultiHost());
|
||||
}
|
||||
|
||||
});
|
||||
} catch (final Throwable e) {
|
||||
LogController.CL(true).log(e);
|
||||
@ -298,10 +276,9 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
if (acc.getLastValidTimestamp() == -1 || (!acc.isEnabled() && timeSinceValidLogin > expireTimeMS)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final PluginForHost plugin = acc.getPlugin();
|
||||
if (plugin != null) {
|
||||
final DomainInfo domainInfo = DomainInfo.getInstance(plugin.getHost());
|
||||
final DomainInfo domainInfo = DomainInfo.getInstance(plugin.getHost(), true);
|
||||
final String domainTld = domainInfo.getTld();
|
||||
domainInfo.getFavIcon();
|
||||
switch (premiumStatusBarDisplay) {
|
||||
@ -361,7 +338,6 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (PremiumStatusBarDisplay.GROUP_BY_SUPPORTED_ACCOUNTS.equals(premiumStatusBarDisplay)) {
|
||||
for (ServiceCollection<?> serviceCollection : services) {
|
||||
@ -391,5 +367,4 @@ public class ServicePanel extends JPanel implements MouseListener, AccountToolti
|
||||
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
}
|
||||
|
||||
}
|
@ -38,8 +38,8 @@ public class NewRuleAction extends AbstractAddAction {
|
||||
final ArrayList<DomainInfo> list = getAvailableDomainInfoList();
|
||||
/* Allow only one rule per hoster -> Remove items from list which a rule already exists for. */
|
||||
final HosterRuleController hrc = HosterRuleController.getInstance();
|
||||
for (AccountUsageRule aur : hrc.list()) {
|
||||
list.remove(DomainInfo.getInstance(aur.getHoster()));
|
||||
for (final AccountUsageRule aur : hrc.list()) {
|
||||
list.remove(DomainInfo.getInstance(aur.getHoster(), true));
|
||||
}
|
||||
final ChooseHosterDialog d = new ChooseHosterDialog(_GUI.T.NewRuleAction_actionPerformed_choose_hoster_message(), list.toArray(new DomainInfo[] {}));
|
||||
try {
|
||||
@ -64,27 +64,30 @@ public class NewRuleAction extends AbstractAddAction {
|
||||
final HashSet<String> multihosterDomains = new HashSet<String>();
|
||||
/* Collect domains of all multihoster accounts which the user currently has. */
|
||||
for (final Account acc : AccountController.getInstance().list()) {
|
||||
if (acc.getPlugin().hasFeature(FEATURE.MULTIHOST)) {
|
||||
final String thisMultihosterDomain = acc.getHoster();
|
||||
multihosterDomains.add(thisMultihosterDomain);
|
||||
final AccountInfo ai = acc.getAccountInfo();
|
||||
if (ai != null) {
|
||||
final List<String> supportedHosts = ai.getMultiHostSupport();
|
||||
if (supportedHosts != null) {
|
||||
for (final String supportedHost : supportedHosts) {
|
||||
if (multihosterDomains.contains(supportedHost)) {
|
||||
/*
|
||||
* Multihoster supports its own domain or domains of other multihosters -> Exclude those domains from usage
|
||||
* rule selection
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
final LazyHostPlugin plg = HostPluginController.getInstance().get(supportedHost);
|
||||
if (plg != null) {
|
||||
domains.add(DomainInfo.getInstance(plg.getHost()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!acc.getPlugin().hasFeature(FEATURE.MULTIHOST)) {
|
||||
continue;
|
||||
}
|
||||
final String thisMultihosterDomain = acc.getHoster();
|
||||
multihosterDomains.add(thisMultihosterDomain);
|
||||
final AccountInfo ai = acc.getAccountInfo();
|
||||
if (ai == null) {
|
||||
continue;
|
||||
}
|
||||
final List<String> supportedHosts = ai.getMultiHostSupport();
|
||||
if (supportedHosts == null) {
|
||||
continue;
|
||||
}
|
||||
for (final String supportedHost : supportedHosts) {
|
||||
if (multihosterDomains.contains(supportedHost)) {
|
||||
/*
|
||||
* Multihoster supports its own domain or domains of other multihosters -> Exclude those domains from usage rule
|
||||
* selection
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
final LazyHostPlugin plg = HostPluginController.getInstance().get(supportedHost);
|
||||
if (plg != null) {
|
||||
domains.add(DomainInfo.getInstance(plg.getHost(), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -92,7 +95,7 @@ public class NewRuleAction extends AbstractAddAction {
|
||||
/* Collect all domains which the user is allowed to create usage rules for. */
|
||||
for (final LazyHostPlugin plugin : plugins) {
|
||||
if (allowAccountUsageRuleCreation(plugin)) {
|
||||
domains.add(DomainInfo.getInstance(plugin.getHost()));
|
||||
domains.add(DomainInfo.getInstance(plugin.getHost(), true));
|
||||
}
|
||||
}
|
||||
/* Sort results. */
|
||||
|
@ -625,7 +625,7 @@ public class AccountInfo extends Property implements AccountTrafficView {
|
||||
return mhosts;
|
||||
}
|
||||
|
||||
/** Returns information about host if it is supported. */
|
||||
/** Returns information about specific host if it is supported. */
|
||||
public MultiHostHost getMultihostSupportedHost(final String domain) {
|
||||
final List<MultiHostHost> mhosts = getMultiHostSupport2();
|
||||
if (mhosts == null || mhosts.size() == 0) {
|
||||
|
@ -46,51 +46,6 @@ import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import jd.PluginWrapper;
|
||||
import jd.captcha.JACMethod;
|
||||
import jd.config.SubConfiguration;
|
||||
import jd.controlling.accountchecker.AccountChecker.AccountCheckJob;
|
||||
import jd.controlling.accountchecker.AccountCheckerThread;
|
||||
import jd.controlling.captcha.CaptchaSettings;
|
||||
import jd.controlling.captcha.SkipException;
|
||||
import jd.controlling.captcha.SkipRequest;
|
||||
import jd.controlling.downloadcontroller.AccountCache.ACCOUNTTYPE;
|
||||
import jd.controlling.downloadcontroller.DiskSpaceManager.DISKSPACERESERVATIONRESULT;
|
||||
import jd.controlling.downloadcontroller.DiskSpaceReservation;
|
||||
import jd.controlling.downloadcontroller.DownloadSession;
|
||||
import jd.controlling.downloadcontroller.DownloadWatchDog;
|
||||
import jd.controlling.downloadcontroller.DownloadWatchDogJob;
|
||||
import jd.controlling.downloadcontroller.ExceptionRunnable;
|
||||
import jd.controlling.downloadcontroller.SingleDownloadController;
|
||||
import jd.controlling.downloadcontroller.SingleDownloadController.WaitingQueueItem;
|
||||
import jd.controlling.linkchecker.LinkChecker;
|
||||
import jd.controlling.linkcollector.LinkCollector;
|
||||
import jd.controlling.linkcrawler.CheckableLink;
|
||||
import jd.controlling.linkcrawler.CrawledLink;
|
||||
import jd.controlling.linkcrawler.LinkCrawler;
|
||||
import jd.controlling.linkcrawler.LinkCrawlerThread;
|
||||
import jd.controlling.packagecontroller.AbstractNode;
|
||||
import jd.controlling.proxy.AbstractProxySelectorImpl;
|
||||
import jd.controlling.reconnect.ipcheck.BalancedWebIPCheck;
|
||||
import jd.controlling.reconnect.ipcheck.IPCheckException;
|
||||
import jd.controlling.reconnect.ipcheck.OfflineException;
|
||||
import jd.gui.swing.jdgui.views.settings.panels.pluginsettings.PluginConfigPanel;
|
||||
import jd.http.Browser;
|
||||
import jd.http.Browser.BrowserException;
|
||||
import jd.http.NoGateWayException;
|
||||
import jd.http.ProxySelectorInterface;
|
||||
import jd.http.Request;
|
||||
import jd.http.StaticProxySelector;
|
||||
import jd.http.URLConnectionAdapter;
|
||||
import jd.nutils.Formatter;
|
||||
import jd.nutils.JDHash;
|
||||
import jd.plugins.Account.AccountError;
|
||||
import jd.plugins.DownloadLink.AvailableStatus;
|
||||
import jd.plugins.download.DownloadInterface;
|
||||
import jd.plugins.download.DownloadInterfaceFactory;
|
||||
import jd.plugins.download.DownloadLinkDownloadable;
|
||||
import jd.plugins.download.Downloadable;
|
||||
|
||||
import org.appwork.exceptions.WTFException;
|
||||
import org.appwork.net.protocol.http.HTTPConstants;
|
||||
import org.appwork.storage.JSonStorage;
|
||||
@ -104,6 +59,7 @@ import org.appwork.uio.ConfirmDialogInterface;
|
||||
import org.appwork.uio.InputDialogInterface;
|
||||
import org.appwork.uio.UIOManager;
|
||||
import org.appwork.utils.Application;
|
||||
import org.appwork.utils.DebugMode;
|
||||
import org.appwork.utils.Exceptions;
|
||||
import org.appwork.utils.Files;
|
||||
import org.appwork.utils.Hash;
|
||||
@ -190,6 +146,51 @@ import org.jdownloader.translate._JDT;
|
||||
import org.jdownloader.updatev2.UpdateController;
|
||||
import org.jdownloader.updatev2.UpdateHandler;
|
||||
|
||||
import jd.PluginWrapper;
|
||||
import jd.captcha.JACMethod;
|
||||
import jd.config.SubConfiguration;
|
||||
import jd.controlling.accountchecker.AccountChecker.AccountCheckJob;
|
||||
import jd.controlling.accountchecker.AccountCheckerThread;
|
||||
import jd.controlling.captcha.CaptchaSettings;
|
||||
import jd.controlling.captcha.SkipException;
|
||||
import jd.controlling.captcha.SkipRequest;
|
||||
import jd.controlling.downloadcontroller.AccountCache.ACCOUNTTYPE;
|
||||
import jd.controlling.downloadcontroller.DiskSpaceManager.DISKSPACERESERVATIONRESULT;
|
||||
import jd.controlling.downloadcontroller.DiskSpaceReservation;
|
||||
import jd.controlling.downloadcontroller.DownloadSession;
|
||||
import jd.controlling.downloadcontroller.DownloadWatchDog;
|
||||
import jd.controlling.downloadcontroller.DownloadWatchDogJob;
|
||||
import jd.controlling.downloadcontroller.ExceptionRunnable;
|
||||
import jd.controlling.downloadcontroller.SingleDownloadController;
|
||||
import jd.controlling.downloadcontroller.SingleDownloadController.WaitingQueueItem;
|
||||
import jd.controlling.linkchecker.LinkChecker;
|
||||
import jd.controlling.linkcollector.LinkCollector;
|
||||
import jd.controlling.linkcrawler.CheckableLink;
|
||||
import jd.controlling.linkcrawler.CrawledLink;
|
||||
import jd.controlling.linkcrawler.LinkCrawler;
|
||||
import jd.controlling.linkcrawler.LinkCrawlerThread;
|
||||
import jd.controlling.packagecontroller.AbstractNode;
|
||||
import jd.controlling.proxy.AbstractProxySelectorImpl;
|
||||
import jd.controlling.reconnect.ipcheck.BalancedWebIPCheck;
|
||||
import jd.controlling.reconnect.ipcheck.IPCheckException;
|
||||
import jd.controlling.reconnect.ipcheck.OfflineException;
|
||||
import jd.gui.swing.jdgui.views.settings.panels.pluginsettings.PluginConfigPanel;
|
||||
import jd.http.Browser;
|
||||
import jd.http.Browser.BrowserException;
|
||||
import jd.http.NoGateWayException;
|
||||
import jd.http.ProxySelectorInterface;
|
||||
import jd.http.Request;
|
||||
import jd.http.StaticProxySelector;
|
||||
import jd.http.URLConnectionAdapter;
|
||||
import jd.nutils.Formatter;
|
||||
import jd.nutils.JDHash;
|
||||
import jd.plugins.Account.AccountError;
|
||||
import jd.plugins.DownloadLink.AvailableStatus;
|
||||
import jd.plugins.download.DownloadInterface;
|
||||
import jd.plugins.download.DownloadInterfaceFactory;
|
||||
import jd.plugins.download.DownloadLinkDownloadable;
|
||||
import jd.plugins.download.Downloadable;
|
||||
|
||||
/**
|
||||
* Dies ist die Oberklasse fuer alle Plugins, die von einem Anbieter Dateien herunterladen koennen
|
||||
*
|
||||
@ -198,11 +199,10 @@ import org.jdownloader.updatev2.UpdateHandler;
|
||||
public abstract class PluginForHost extends Plugin {
|
||||
private static final String COPY_MOVE_FILE = "CopyMoveFile";
|
||||
private static final Pattern[] PATTERNS = new Pattern[] {
|
||||
/**
|
||||
* these patterns should split filename and fileextension (extension must include the
|
||||
* point)
|
||||
*/
|
||||
// multipart rar archives
|
||||
/**
|
||||
* these patterns should split filename and fileextension (extension must include the point)
|
||||
*/
|
||||
// multipart rar archives
|
||||
Pattern.compile("(.*)(\\.pa?r?t?\\.?[0-9]+.*?\\.rar$)", Pattern.CASE_INSENSITIVE),
|
||||
// normal files with extension
|
||||
Pattern.compile("(.*)(\\..*?$)", Pattern.CASE_INSENSITIVE) };
|
||||
@ -1136,14 +1136,41 @@ public abstract class PluginForHost extends Plugin {
|
||||
if (accountTrafficView == null) {
|
||||
return true;
|
||||
}
|
||||
final long trafficLeft = accountTrafficView.getTrafficLeft();
|
||||
final long minimum = 1024;
|
||||
final long downloadSize = link.getView().getBytesTotalEstimated();
|
||||
if (DebugMode.TRUE_IN_IDE_ELSE_FALSE && ACCOUNTTYPE.MULTI.equals(account.getType()) && downloadSize != -1) {
|
||||
final AccountInfo ai = account.getAccountInfo();
|
||||
if (ai == null) {
|
||||
/* Multihoster account without accountInfo -> That should never happen */
|
||||
return false;
|
||||
}
|
||||
/* Verify again because plugins can modify list on runtime */
|
||||
/* Check for domain specific limits of multihost items. */
|
||||
final MultiHostHost hostinfo = ai.getMultihostSupportedHost(link.getHost());
|
||||
if (hostinfo == null) {
|
||||
/* Not supported */
|
||||
return false;
|
||||
}
|
||||
final long trafficCalcFactor = hostinfo.getTrafficCalculationFactorPercent();
|
||||
long neededTraffic = downloadSize;
|
||||
if (trafficCalcFactor != 100) {
|
||||
neededTraffic = (downloadSize * trafficCalcFactor) / 100;
|
||||
if (neededTraffic > trafficLeft) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* Account itself has enough traffic but does it have enough traffic for the host we are trying to download from? */
|
||||
if (!hostinfo.isUnlimitedTraffic() && neededTraffic > hostinfo.getTrafficLeft()) {
|
||||
/* Not enough traffic to download this file */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (accountTrafficView.isUnlimitedTraffic() || accountTrafficView.isSpecialTraffic()) {
|
||||
return true;
|
||||
}
|
||||
final long trafficLeft = accountTrafficView.getTrafficLeft();
|
||||
final long minimum = 1024;
|
||||
if (trafficLeft == 0) {
|
||||
if (accountTrafficView.isTrafficRefill()) {
|
||||
final long downloadSize = link.getView().getBytesTotalEstimated();
|
||||
final long downloadLeft;
|
||||
if (downloadSize >= 0) {
|
||||
downloadLeft = Math.max(minimum, downloadSize - link.getView().getBytesLoaded());
|
||||
@ -1155,7 +1182,6 @@ public abstract class PluginForHost extends Plugin {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
final long downloadSize = link.getView().getBytesTotalEstimated();
|
||||
if (downloadSize <= 0) {
|
||||
/* File size is unknown */
|
||||
return true;
|
||||
@ -1292,12 +1318,9 @@ public abstract class PluginForHost extends Plugin {
|
||||
protected void handleException(final DownloadLink downloadLink, final ACCOUNTTYPE accountType, final Account account, final Exception e) throws Exception {
|
||||
if (ACCOUNTTYPE.MULTI.equals(accountType) && e instanceof PluginException) {
|
||||
if (((PluginException) e).getLinkStatus() == LinkStatus.ERROR_FILE_NOT_FOUND && AvailableStatus.TRUE.equals(link.getAvailableStatus())) {
|
||||
|
||||
/* File is online according to original filehoster -> Do not trust offline status from multihoster. */
|
||||
|
||||
throw new PluginException(LinkStatus.ERROR_TEMPORARILY_UNAVAILABLE, "Multihoster " + getHost() + " claims that this file is offline", e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1367,16 +1390,16 @@ public abstract class PluginForHost extends Plugin {
|
||||
public void handleMultiHost(DownloadLink downloadLink, Account account) throws Exception {
|
||||
/*
|
||||
* fetchAccountInfo must fill ai.setMultiHostSupport to signal all supported multiHosts
|
||||
*
|
||||
*
|
||||
* please synchronized on accountinfo and the ArrayList<String> when you change something in the handleMultiHost function
|
||||
*
|
||||
*
|
||||
* in fetchAccountInfo we don't have to synchronize because we create a new instance of AccountInfo and fill it
|
||||
*
|
||||
*
|
||||
* if you need customizable maxDownloads, please use getMaxSimultanDownload to handle this you are in multihost when account host
|
||||
* does not equal link host!
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* will update this doc about error handling
|
||||
*/
|
||||
logger.severe("invalid call to handleMultiHost: " + downloadLink.getName() + ":" + downloadLink.getHost() + " to " + getHost() + ":" + this.getVersion() + " with " + account);
|
||||
|
@ -16,16 +16,18 @@
|
||||
package jd.plugins.decrypter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
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.jdownloader.controlling.filter.CompiledFiletypeFilter;
|
||||
import org.jdownloader.plugins.controller.LazyPlugin;
|
||||
|
||||
import jd.PluginWrapper;
|
||||
import jd.controlling.ProgressController;
|
||||
import jd.http.Cookies;
|
||||
import jd.nutils.encoding.Encoding;
|
||||
import jd.parser.Regex;
|
||||
import jd.plugins.CryptedLink;
|
||||
@ -63,54 +65,68 @@ public class BitchuteComChannel extends PluginForDecrypt {
|
||||
} else if (br.containsHTML("(?i)>\\s*This channel is blocked under the following Community Guideline")) {
|
||||
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
final String csrftoken = this.br.getCookie(br.getHost(), "csrftoken", Cookies.NOTDELETEDPATTERN);
|
||||
final String channelUID = br.getRegex("channelRefreshCounts\\('([A-Za-z0-9]+)'").getMatch(0);
|
||||
if (StringUtils.isEmpty(csrftoken) || channelUID == null) {
|
||||
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
|
||||
}
|
||||
final String channelID = new Regex(parameter, this.getSupportedLinks()).getMatch(0);
|
||||
/*
|
||||
* Prefer to use channelname from html - channelname inside URL is always lowercase and sometimes a cryptic string while html
|
||||
* contains the "nicer" channelname.
|
||||
*/
|
||||
String channelname = br.getRegex("id=\"channel-title\"[^>]*>([^>]+)<").getMatch(0);
|
||||
String channelname = br.getRegex("itemprop=\"name\" content=\"([^\"]+)").getMatch(0);
|
||||
if (StringUtils.isEmpty(channelname)) {
|
||||
/* Fallback */
|
||||
channelname = new Regex(parameter, this.getSupportedLinks()).getMatch(0);
|
||||
channelname = channelID;
|
||||
}
|
||||
final FilePackage fp = FilePackage.getInstance();
|
||||
fp.setName(Encoding.htmlDecode(channelname.trim()));
|
||||
int index = 0;
|
||||
fp.setPackageKey("bitchute://channel/" + channelID);
|
||||
int offset = 0;
|
||||
int page = 0;
|
||||
final int itemsPerRequest = 25;
|
||||
br.getHeaders().put("x-requested-with", "XMLHttpRequest");
|
||||
final int itemsPerRequest = 10;
|
||||
br.getHeaders().put("Accept", "application/json, text/plain, */*");
|
||||
br.getHeaders().put("X-Requested-With", "XMLHttpRequest");
|
||||
br.getHeaders().put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
|
||||
do {
|
||||
logger.info("Crawling page: " + page);
|
||||
br.postPage("https://www.bitchute.com/channel/" + channelUID + "/extend/", "csrfmiddlewaretoken=" + Encoding.urlEncode(csrftoken) + "&name=&offset=" + index);
|
||||
final String[] videoIDs = br.getRegex("/video/([A-Za-z0-9]+)/").getColumn(0);
|
||||
int addedItems = 0;
|
||||
for (final String videoID : videoIDs) {
|
||||
if (isAbort()) {
|
||||
break;
|
||||
} else if (dupes.add(videoID)) {
|
||||
dupes.add(videoID);
|
||||
final DownloadLink dl = createDownloadlink("https://www." + this.getHost() + "/video/" + videoID);
|
||||
dl.setMimeHint(CompiledFiletypeFilter.VideoExtensions.MP4);
|
||||
dl.setAvailable(true);
|
||||
/* Property for packagizer */
|
||||
dl.setProperty("username", channelname);
|
||||
dl._setFilePackage(fp);
|
||||
ret.add(dl);
|
||||
distribute(dl);
|
||||
addedItems++;
|
||||
final Map<String, Object> postdata = new HashMap<String, Object>();
|
||||
postdata.put("channel_id", channelID);
|
||||
postdata.put("limit", itemsPerRequest);
|
||||
pagination: do {
|
||||
postdata.put("offset", offset);
|
||||
br.getPage(br.createJSonPostRequest("https://api.bitchute.com/api/beta/channel/videos", postdata));
|
||||
if (br.getHttpConnection().getResponseCode() == 403) {
|
||||
/**
|
||||
* E.g. GEO-blocked: <br>
|
||||
* {"errors":[{"context":"AUTH","message":"Forbidden - Cannot perform this action"},{"context":"reason","message":"Content
|
||||
* access is restricted based on the users location"}]}
|
||||
*/
|
||||
throw new DecrypterRetryException(RetryReason.GEO);
|
||||
} else if (br.getHttpConnection().getResponseCode() == 404) {
|
||||
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
final Map<String, Object> entries = restoreFromString(br.getRequest().getHtmlCode(), TypeRef.MAP);
|
||||
final List<Map<String, Object>> videos = (List<Map<String, Object>>) entries.get("videos");
|
||||
int numberofNewItemsThisPage = 0;
|
||||
for (final Map<String, Object> videomap : videos) {
|
||||
final String videoID = videomap.get("video_id").toString();
|
||||
if (!dupes.add(videoID)) {
|
||||
continue;
|
||||
}
|
||||
final DownloadLink dl = createDownloadlink("https://www." + this.getHost() + "/video/" + videoID);
|
||||
dl.setName(videomap.get("video_name") + ".mp4");
|
||||
dl.setAvailable(true);
|
||||
/* Property for Packagizer */
|
||||
dl.setProperty("username", channelname);
|
||||
dl._setFilePackage(fp);
|
||||
ret.add(dl);
|
||||
distribute(dl);
|
||||
numberofNewItemsThisPage++;
|
||||
}
|
||||
logger.info("Crawling page: " + page + " | Found items so far: " + index);
|
||||
if (addedItems < itemsPerRequest) {
|
||||
logger.info("Crawled page: " + page + " | offset: " + offset + " | Found items so far: " + ret.size());
|
||||
if (this.isAbort()) {
|
||||
break pagination;
|
||||
} else if (numberofNewItemsThisPage < itemsPerRequest) {
|
||||
logger.info("Stopping because number of items found doesn't match number of items per request");
|
||||
break;
|
||||
break pagination;
|
||||
}
|
||||
index += itemsPerRequest;
|
||||
/* Continue to next page */
|
||||
offset += itemsPerRequest;
|
||||
page += 1;
|
||||
} while (!this.isAbort());
|
||||
return ret;
|
||||
|
@ -16,12 +16,15 @@
|
||||
package jd.plugins.decrypter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.appwork.utils.parser.UrlQuery;
|
||||
|
||||
import jd.PluginWrapper;
|
||||
import jd.controlling.ProgressController;
|
||||
import jd.nutils.encoding.Encoding;
|
||||
import jd.parser.Regex;
|
||||
import jd.plugins.CryptedLink;
|
||||
import jd.plugins.DecrypterPlugin;
|
||||
import jd.plugins.DownloadLink;
|
||||
@ -40,7 +43,9 @@ public class BooruOrgCrawler extends PluginForDecrypt {
|
||||
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[] { "tbib.org", "booru.org" });
|
||||
ret.add(new String[] { "tbib.org" });
|
||||
ret.add(new String[] { "booru.org" });
|
||||
ret.add(new String[] { "safebooru.org" });
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -56,7 +61,7 @@ public class BooruOrgCrawler extends PluginForDecrypt {
|
||||
public static String[] getAnnotationUrls() {
|
||||
final List<String> ret = new ArrayList<String>();
|
||||
for (final String[] domains : getPluginDomains()) {
|
||||
ret.add("https?://(?:\\w+\\.)?" + buildHostsPatternPart(domains) + "/index\\.php\\?page=post\\&s=list\\&tags=[A-Za-z0-9_\\-]+");
|
||||
ret.add("https?://(?:\\w+\\.)?" + buildHostsPatternPart(domains) + "/.*?index\\.php\\?page=post\\&s=list\\&tags=[A-Za-z0-9_\\-]+");
|
||||
}
|
||||
return ret.toArray(new String[0]);
|
||||
}
|
||||
@ -68,8 +73,8 @@ public class BooruOrgCrawler extends PluginForDecrypt {
|
||||
if (br.getHttpConnection().getResponseCode() == 404) {
|
||||
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
|
||||
}
|
||||
final String full_host = new Regex(contenturl, "https?://([^/]+)/").getMatch(0);
|
||||
final String fpName = new Regex(contenturl, "tags=(.+)").getMatch(0);
|
||||
final UrlQuery query = UrlQuery.parse(contenturl);
|
||||
final String fpName = query.get("tags");
|
||||
final FilePackage fp = FilePackage.getInstance();
|
||||
fp.setName(Encoding.htmlDecode(fpName).trim());
|
||||
final String url_part = contenturl;
|
||||
@ -77,11 +82,8 @@ public class BooruOrgCrawler extends PluginForDecrypt {
|
||||
int offset = 0;
|
||||
final int max_entries_per_page = 20;
|
||||
int entries_per_page_current = 0;
|
||||
do {
|
||||
if (this.isAbort()) {
|
||||
logger.info("Decryption aborted by user");
|
||||
return ret;
|
||||
}
|
||||
final Set<String> dupes = new HashSet<String>();
|
||||
pagination: do {
|
||||
if (page_counter > 1) {
|
||||
this.br.getPage(url_part + "&pid=" + offset);
|
||||
if (this.br.containsHTML("You are viewing an advertisement")) {
|
||||
@ -95,8 +97,12 @@ public class BooruOrgCrawler extends PluginForDecrypt {
|
||||
break;
|
||||
}
|
||||
entries_per_page_current = linkids.length;
|
||||
int numberofNewItemsThisPage = 0;
|
||||
for (final String linkid : linkids) {
|
||||
final String link = "http://" + full_host + "/index.php?page=post&s=view&id=" + linkid;
|
||||
if (!dupes.add(linkid)) {
|
||||
continue;
|
||||
}
|
||||
final String link = br.getURL("index.php?page=post&s=view&id=" + linkid).toExternalForm();
|
||||
final DownloadLink dl = createDownloadlink(link);
|
||||
dl.setLinkID(linkid);
|
||||
dl.setAvailable(true);
|
||||
@ -105,9 +111,22 @@ public class BooruOrgCrawler extends PluginForDecrypt {
|
||||
ret.add(dl);
|
||||
distribute(dl);
|
||||
offset++;
|
||||
numberofNewItemsThisPage++;
|
||||
}
|
||||
if (this.isAbort()) {
|
||||
logger.info("Decryption aborted by user");
|
||||
break pagination;
|
||||
} else if (numberofNewItemsThisPage == 0) {
|
||||
logger.info("Stopping because: Failed to find any new items on current page");
|
||||
break pagination;
|
||||
} else {
|
||||
/* Continue to next page */
|
||||
page_counter++;
|
||||
}
|
||||
page_counter++;
|
||||
} while (entries_per_page_current >= max_entries_per_page);
|
||||
if (ret.isEmpty()) {
|
||||
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,13 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.appwork.storage.TypeRef;
|
||||
import org.appwork.utils.StringUtils;
|
||||
import org.appwork.utils.parser.UrlQuery;
|
||||
import org.jdownloader.plugins.components.antiDDoSForDecrypt;
|
||||
import org.jdownloader.plugins.controller.LazyPlugin;
|
||||
import org.jdownloader.scripting.JavaScriptEngineFactory;
|
||||
|
||||
import jd.PluginWrapper;
|
||||
import jd.controlling.AccountController;
|
||||
import jd.controlling.ProgressController;
|
||||
@ -42,13 +49,6 @@ import jd.plugins.PluginException;
|
||||
import jd.plugins.PluginForHost;
|
||||
import jd.utils.JDHexUtils;
|
||||
|
||||
import org.appwork.storage.TypeRef;
|
||||
import org.appwork.utils.StringUtils;
|
||||
import org.appwork.utils.parser.UrlQuery;
|
||||
import org.jdownloader.plugins.components.antiDDoSForDecrypt;
|
||||
import org.jdownloader.plugins.controller.LazyPlugin;
|
||||
import org.jdownloader.scripting.JavaScriptEngineFactory;
|
||||
|
||||
@DecrypterPlugin(revision = "$Revision$", interfaceVersion = 3, names = { "mixcloud.com" }, urls = { "https?://(?:www\\.)?mixcloud\\.com/(widget/iframe/\\?.+|[^/]+/?([^/]+/)?)" })
|
||||
public class MixCloudComCrawler extends antiDDoSForDecrypt {
|
||||
public MixCloudComCrawler(final PluginWrapper wrapper) {
|
||||
@ -126,11 +126,9 @@ public class MixCloudComCrawler extends antiDDoSForDecrypt {
|
||||
if (csrftoken == null) {
|
||||
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
|
||||
}
|
||||
PostRequest request = br
|
||||
.createJSonPostRequest(
|
||||
"https://app.mixcloud.com/graphql",
|
||||
"{\"query\":\"query UserProfileHeaderQuery( $lookup: UserLookup!) { user: userLookup(lookup: $lookup) { id displayName username isBranded isStaff isFollowing isViewer followers { totalCount } hasCoverPicture hasPremiumFeatures hasProFeatures picture { primaryColor ...UGCImage_picture } coverPicture { urlRoot } ...UserBadge_user ...ProfileNavigation_user ...ShareUserButton_user ...ProfileRegisterUpsellComponent_user ...FollowButton_user ...SelectUpsellButton_user } viewer { ...ProfileRegisterUpsellComponent_viewer ...FollowButton_viewer id }}fragment FollowButton_user on User { id isFollowed isFollowing isViewer followers { totalCount } username displayName}fragment FollowButton_viewer on Viewer { me { id }}fragment ProfileNavigation_user on User { id username stream { totalCount } favorites { totalCount } listeningHistory { totalCount } uploads { totalCount } posts { totalCount } profileNavigation { menuItems { __typename ... on NavigationItemInterface { __isNavigationItemInterface: __typename inDropdown } ... on HideableNavigationItemInterface { __isHideableNavigationItemInterface: __typename hidden } ... on PlaylistNavigationItem { count playlist { id name slug } } } }}fragment ProfileRegisterUpsellComponent_user on User { id displayName followers { totalCount }}fragment ProfileRegisterUpsellComponent_viewer on Viewer { me { id }}fragment SelectUpsellButton_user on User { username isSelect isSubscribedTo selectUpsell { planInfo { displayAmount } }}fragment ShareUserButton_user on User { biog username displayName id isUploader picture { urlRoot }}fragment UGCImage_picture on Picture { urlRoot primaryColor}fragment UserBadge_user on User { username hasProFeatures hasPremiumFeatures isStaff isSelect}\",\"variables\":{\"lookup\":{\"username\":\""
|
||||
+ username + "\"}}}");
|
||||
PostRequest request = br.createJSonPostRequest("https://app.mixcloud.com/graphql",
|
||||
"{\"query\":\"query UserProfileHeaderQuery( $lookup: UserLookup!) { user: userLookup(lookup: $lookup) { id displayName username isBranded isStaff isFollowing isViewer followers { totalCount } hasCoverPicture hasPremiumFeatures hasProFeatures picture { primaryColor ...UGCImage_picture } coverPicture { urlRoot } ...UserBadge_user ...ProfileNavigation_user ...ShareUserButton_user ...ProfileRegisterUpsellComponent_user ...FollowButton_user ...SelectUpsellButton_user } viewer { ...ProfileRegisterUpsellComponent_viewer ...FollowButton_viewer id }}fragment FollowButton_user on User { id isFollowed isFollowing isViewer followers { totalCount } username displayName}fragment FollowButton_viewer on Viewer { me { id }}fragment ProfileNavigation_user on User { id username stream { totalCount } favorites { totalCount } listeningHistory { totalCount } uploads { totalCount } posts { totalCount } profileNavigation { menuItems { __typename ... on NavigationItemInterface { __isNavigationItemInterface: __typename inDropdown } ... on HideableNavigationItemInterface { __isHideableNavigationItemInterface: __typename hidden } ... on PlaylistNavigationItem { count playlist { id name slug } } } }}fragment ProfileRegisterUpsellComponent_user on User { id displayName followers { totalCount }}fragment ProfileRegisterUpsellComponent_viewer on Viewer { me { id }}fragment SelectUpsellButton_user on User { username isSelect isSubscribedTo selectUpsell { planInfo { displayAmount } }}fragment ShareUserButton_user on User { biog username displayName id isUploader picture { urlRoot }}fragment UGCImage_picture on Picture { urlRoot primaryColor}fragment UserBadge_user on User { username hasProFeatures hasPremiumFeatures isStaff isSelect}\",\"variables\":{\"lookup\":{\"username\":\""
|
||||
+ username + "\"}}}");
|
||||
br.getPage(request);
|
||||
Map<String, Object> entries = restoreFromString(br.toString(), TypeRef.MAP);
|
||||
entries = (Map<String, Object>) JavaScriptEngineFactory.walkJson(entries, "data/user");
|
||||
@ -213,13 +211,9 @@ public class MixCloudComCrawler extends antiDDoSForDecrypt {
|
||||
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
|
||||
}
|
||||
br.setFollowRedirects(true);
|
||||
|
||||
final PostRequest request = br
|
||||
.createJSonPostRequest(
|
||||
"https://app.mixcloud.com/graphql",
|
||||
String.format(
|
||||
"{\"id\":\"q13\",\"query\":\"query HeaderQuery($lookup_0:CloudcastLookup!,$lighten_1:Int!,$alpha_2:Float!) {cloudcastLookup(lookup:$lookup_0) {id,...Fn}} fragment F0 on Cloudcast {picture {urlRoot,primaryColor},id} fragment F1 on Cloudcast {id,name,slug,owner {username,id}} fragment F2 on Cloudcast {owner {id,displayName,followers {totalCount}},id} fragment F3 on Cloudcast {restrictedReason,owner {displayName,country,username,isSubscribedTo,isViewer,id},slug,id,isAwaitingAudio,isDraft,isPlayable,streamInfo {hlsUrl,dashUrl,url,uuid},audioLength,currentPosition,proportionListened,repeatPlayAmount,hasPlayCompleted,seekRestriction,previewUrl,isExclusivePreviewOnly,isExclusive,picture {primaryColor,isLight,_primaryColor2pfPSM:primaryColor(lighten:$lighten_1),_primaryColor3Yfcks:primaryColor(alpha:$alpha_2)}} fragment F4 on Node {id,__typename} fragment F5 on Cloudcast {id,isFavorited,isPublic,hiddenStats,favorites {totalCount},slug,owner {id,isFollowing,username,isSelect,displayName,isViewer}} fragment F6 on Cloudcast {id,isUnlisted,isPublic} fragment F7 on Cloudcast {id,isReposted,isPublic,hiddenStats,reposts {totalCount},owner {isViewer,id}} fragment F8 on Cloudcast {id,isUnlisted,isPublic,slug,description,picture {urlRoot},owner {displayName,isViewer,username,id}} fragment F9 on Cloudcast {id,slug,isSpam,owner {username,isViewer,id}} fragment Fa on Cloudcast {owner {isViewer,isSubscribedTo,username,hasProFeatures,isBranded,id},sections {__typename,...F4},id,slug,isExclusive,isUnlisted,isShortLength,...F5,...F6,...F7,...F8,...F9} fragment Fb on Cloudcast {qualityScore,listenerMinutes,id} fragment Fc on Cloudcast {slug,plays,publishDate,hiddenStats,owner {username,id},id,...Fb} fragment Fd on User {id} fragment Fe on User {username,hasProFeatures,hasPremiumFeatures,isStaff,isSelect,id} fragment Ff on User {id,isFollowed,isFollowing,isViewer,followers {totalCount},username,displayName} fragment Fg on Cloudcast {isExclusive,isExclusivePreviewOnly,slug,id,owner {username,id}} fragment Fh on Cloudcast {isExclusive,owner {id,username,displayName,...Fd,...Fe,...Ff},id,...Fg} fragment Fi on Cloudcast {id,streamInfo {uuid,url,hlsUrl,dashUrl},audioLength,seekRestriction,currentPosition} fragment Fj on Cloudcast {owner {displayName,isSelect,username,id},seekRestriction,id} fragment Fk on Cloudcast {id,waveformUrl,previewUrl,audioLength,isPlayable,streamInfo {hlsUrl,dashUrl,url,uuid},restrictedReason,seekRestriction,currentPosition,...Fj} fragment Fl on Cloudcast {__typename,isExclusivePreviewOnly,isExclusive,owner {isSelect,isSubscribedTo,username,displayName,isViewer,id},id} fragment Fm on Cloudcast {owner {username,displayName,isSelect,id},id} fragment Fn on Cloudcast {id,name,picture {isLight,primaryColor,urlRoot,primaryColor},owner {displayName,isViewer,isBranded,selectUpsell {text},id},repeatPlayAmount,restrictedReason,seekRestriction,...F0,...F1,...F2,...F3,...Fa,...Fc,...Fh,...Fi,...Fk,...Fl,...Fm}\",\"variables\":{\"lookup_0\":{\"username\":\"%s\",\"slug\":\"%s\"},\"lighten_1\":15,\"alpha_2\":0.3}}",
|
||||
username, slug));
|
||||
final PostRequest request = br.createJSonPostRequest("https://app.mixcloud.com/graphql", String.format(
|
||||
"{\"id\":\"q13\",\"query\":\"query HeaderQuery($lookup_0:CloudcastLookup!,$lighten_1:Int!,$alpha_2:Float!) {cloudcastLookup(lookup:$lookup_0) {id,...Fn}} fragment F0 on Cloudcast {picture {urlRoot,primaryColor},id} fragment F1 on Cloudcast {id,name,slug,owner {username,id}} fragment F2 on Cloudcast {owner {id,displayName,followers {totalCount}},id} fragment F3 on Cloudcast {restrictedReason,owner {displayName,country,username,isSubscribedTo,isViewer,id},slug,id,isAwaitingAudio,isDraft,isPlayable,streamInfo {hlsUrl,dashUrl,url,uuid},audioLength,currentPosition,proportionListened,repeatPlayAmount,hasPlayCompleted,seekRestriction,previewUrl,isExclusivePreviewOnly,isExclusive,picture {primaryColor,isLight,_primaryColor2pfPSM:primaryColor(lighten:$lighten_1),_primaryColor3Yfcks:primaryColor(alpha:$alpha_2)}} fragment F4 on Node {id,__typename} fragment F5 on Cloudcast {id,isFavorited,isPublic,hiddenStats,favorites {totalCount},slug,owner {id,isFollowing,username,isSelect,displayName,isViewer}} fragment F6 on Cloudcast {id,isUnlisted,isPublic} fragment F7 on Cloudcast {id,isReposted,isPublic,hiddenStats,reposts {totalCount},owner {isViewer,id}} fragment F8 on Cloudcast {id,isUnlisted,isPublic,slug,description,picture {urlRoot},owner {displayName,isViewer,username,id}} fragment F9 on Cloudcast {id,slug,isSpam,owner {username,isViewer,id}} fragment Fa on Cloudcast {owner {isViewer,isSubscribedTo,username,hasProFeatures,isBranded,id},sections {__typename,...F4},id,slug,isExclusive,isUnlisted,isShortLength,...F5,...F6,...F7,...F8,...F9} fragment Fb on Cloudcast {qualityScore,listenerMinutes,id} fragment Fc on Cloudcast {slug,plays,publishDate,hiddenStats,owner {username,id},id,...Fb} fragment Fd on User {id} fragment Fe on User {username,hasProFeatures,hasPremiumFeatures,isStaff,isSelect,id} fragment Ff on User {id,isFollowed,isFollowing,isViewer,followers {totalCount},username,displayName} fragment Fg on Cloudcast {isExclusive,isExclusivePreviewOnly,slug,id,owner {username,id}} fragment Fh on Cloudcast {isExclusive,owner {id,username,displayName,...Fd,...Fe,...Ff},id,...Fg} fragment Fi on Cloudcast {id,streamInfo {uuid,url,hlsUrl,dashUrl},audioLength,seekRestriction,currentPosition} fragment Fj on Cloudcast {owner {displayName,isSelect,username,id},seekRestriction,id} fragment Fk on Cloudcast {id,waveformUrl,previewUrl,audioLength,isPlayable,streamInfo {hlsUrl,dashUrl,url,uuid},restrictedReason,seekRestriction,currentPosition,...Fj} fragment Fl on Cloudcast {__typename,isExclusivePreviewOnly,isExclusive,owner {isSelect,isSubscribedTo,username,displayName,isViewer,id},id} fragment Fm on Cloudcast {owner {username,displayName,isSelect,id},id} fragment Fn on Cloudcast {id,name,picture {isLight,primaryColor,urlRoot,primaryColor},owner {displayName,isViewer,isBranded,selectUpsell {text},id},repeatPlayAmount,restrictedReason,seekRestriction,...F0,...F1,...F2,...F3,...Fa,...Fc,...Fh,...Fi,...Fk,...Fl,...Fm}\",\"variables\":{\"lookup_0\":{\"username\":\"%s\",\"slug\":\"%s\"},\"lighten_1\":15,\"alpha_2\":0.3}}",
|
||||
username, slug));
|
||||
this.sendRequest(request);
|
||||
int page = 0;
|
||||
boolean hasMore = false;
|
||||
@ -420,7 +414,7 @@ public class MixCloudComCrawler extends antiDDoSForDecrypt {
|
||||
logger.info("Skip dupe object: " + id);
|
||||
continue;
|
||||
}
|
||||
final Object cloudcastStreamInfo = entries.get("streamInfo");
|
||||
final Map<String, Object> cloudcastStreamInfo = (Map<String, Object>) entries.get("streamInfo");
|
||||
if (cloudcastStreamInfo == null && StringUtils.isEmpty(url_preview)) {
|
||||
/* Skip invalid objects */
|
||||
continue;
|
||||
@ -431,11 +425,10 @@ public class MixCloudComCrawler extends antiDDoSForDecrypt {
|
||||
if (cloudcastStreamInfo != null) {
|
||||
/* We should have found the correct object here! */
|
||||
// final String url_mp3_preview = (String) entries.get("previewUrl");
|
||||
entries = (Map<String, Object>) cloudcastStreamInfo;
|
||||
/*
|
||||
* 2017-11-15: We can chose between dash, http or hls
|
||||
* 2017-11-15: We can chose between dash, progressive or hls
|
||||
*/
|
||||
downloadurl = (String) entries.get("url");
|
||||
downloadurl = (String) cloudcastStreamInfo.get("url");
|
||||
}
|
||||
if (StringUtils.isEmpty(url_preview) && StringUtils.isEmpty(downloadurl)) {
|
||||
/* Skip objects without streams */
|
||||
@ -466,6 +459,12 @@ public class MixCloudComCrawler extends antiDDoSForDecrypt {
|
||||
dlink.setComment(description);
|
||||
}
|
||||
dlink.setAvailable(true);
|
||||
final Number lengthSeconds = (Number) entries.get("audioLength");
|
||||
if (lengthSeconds != null) {
|
||||
/* Set estimated filesize based on a bitrate of 64KB/s */
|
||||
final long trackEstimatedFilesize = (lengthSeconds.intValue() * 64 * 1024) / 8;
|
||||
dlink.setDownloadSize(trackEstimatedFilesize);
|
||||
}
|
||||
dlink._setFilePackage(fp);
|
||||
distribute(dlink);
|
||||
decryptedLinks.add(dlink);
|
||||
|
@ -64,7 +64,7 @@ public class BooruOrg extends PluginForHost {
|
||||
public static String[] getAnnotationUrls() {
|
||||
final List<String> ret = new ArrayList<String>();
|
||||
for (final String[] domains : getPluginDomains()) {
|
||||
ret.add("https?://(?:\\w+\\.)?" + buildHostsPatternPart(domains) + "/index\\.php\\?page=post\\&s=view\\&id=(\\d+)");
|
||||
ret.add("https?://(?:\\w+\\.)?" + buildHostsPatternPart(domains) + "/.*?index\\.php\\?page=post\\&s=view\\&id=(\\d+)");
|
||||
}
|
||||
return ret.toArray(new String[0]);
|
||||
}
|
||||
@ -88,7 +88,7 @@ public class BooruOrg extends PluginForHost {
|
||||
|
||||
@Override
|
||||
public String getAGBLink() {
|
||||
return "https://booru.org/tos.php";
|
||||
return "https://" + getHost() + "/tos.php";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,11 +15,16 @@
|
||||
//along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package jd.plugins.hoster;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import org.appwork.net.protocol.http.HTTPConstants;
|
||||
import org.appwork.utils.StringUtils;
|
||||
import org.jdownloader.plugins.controller.LazyPlugin;
|
||||
|
||||
import jd.PluginWrapper;
|
||||
import jd.http.Cookies;
|
||||
import jd.http.requests.PostRequest;
|
||||
import jd.nutils.encoding.Encoding;
|
||||
import jd.parser.Regex;
|
||||
import jd.plugins.Account;
|
||||
import jd.plugins.Account.AccountType;
|
||||
import jd.plugins.AccountInfo;
|
||||
@ -28,20 +33,17 @@ import jd.plugins.DownloadLink;
|
||||
import jd.plugins.DownloadLink.AvailableStatus;
|
||||
import jd.plugins.HostPlugin;
|
||||
import jd.plugins.LinkStatus;
|
||||
import jd.plugins.Plugin;
|
||||
import jd.plugins.PluginException;
|
||||
import jd.plugins.PluginForHost;
|
||||
import jd.plugins.components.PluginJSonUtils;
|
||||
import jd.plugins.decrypter.MixCloudComCrawler;
|
||||
|
||||
import org.appwork.net.protocol.http.HTTPConstants;
|
||||
import org.appwork.utils.StringUtils;
|
||||
import org.jdownloader.plugins.controller.LazyPlugin;
|
||||
|
||||
@HostPlugin(revision = "$Revision$", interfaceVersion = 3, names = { "mixcloud.com" }, urls = { "https?://stream\\d+\\.mixcloud\\.com/.+|https://thumbnailer\\.mixcloud\\.com/unsafe/.+" })
|
||||
public class MixCloudCom extends PluginForHost {
|
||||
public MixCloudCom(PluginWrapper wrapper) {
|
||||
super(wrapper);
|
||||
this.enablePremium("https://www.mixcloud.com/select/");
|
||||
this.enablePremium("https://www." + getHost() + "/select/");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -87,12 +89,12 @@ public class MixCloudCom extends PluginForHost {
|
||||
private AvailableStatus requestFileInformation(final DownloadLink link, final boolean isDownload) throws Exception {
|
||||
dllink = null;
|
||||
br.setFollowRedirects(true);
|
||||
final String url_filename = new Regex(link.getDownloadURL(), "mixcloud\\.com/(.+)").getMatch(0);
|
||||
final String url_filename = Plugin.getFileNameFromURL(new URL(link.getPluginPatternMatcher()));
|
||||
String filename = link.getFinalFileName();
|
||||
if (filename == null) {
|
||||
filename = url_filename;
|
||||
}
|
||||
dllink = link.getDownloadURL();
|
||||
dllink = link.getPluginPatternMatcher();
|
||||
if (filename == null) {
|
||||
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
|
||||
}
|
||||
@ -156,7 +158,7 @@ public class MixCloudCom extends PluginForHost {
|
||||
if (!StringUtils.isEmpty(username)) {
|
||||
logger.info("Cookie login successful");
|
||||
/* Refresh cookie timestamp */
|
||||
account.saveCookies(this.br.getCookies(br.getHost()), "");
|
||||
account.saveCookies(br.getCookies(br.getHost()), "");
|
||||
return true;
|
||||
} else {
|
||||
logger.info("Cookie login failed");
|
||||
|
@ -213,7 +213,7 @@ abstract public class ZeveraCore extends UseNet {
|
||||
link.setFinalFileName(filename);
|
||||
}
|
||||
if (filesize != null) {
|
||||
link.setDownloadSize(filesize.longValue());
|
||||
link.setVerifiedFileSize(filesize.longValue());
|
||||
}
|
||||
return details;
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ public class DomainInfo implements FavIconRequestor, Comparable<DomainInfo>, Ico
|
||||
|
||||
private static final HashMap<String, WeakReference<DomainInfo>> CACHE = new HashMap<String, WeakReference<DomainInfo>>();
|
||||
|
||||
private static String getCacheID(String domain) {
|
||||
private static String getCacheID(final String domain) {
|
||||
String ret = domain.toLowerCase(Locale.ENGLISH);
|
||||
int index = ret.indexOf(" ");
|
||||
if (index > 0) {
|
||||
@ -151,16 +151,21 @@ public class DomainInfo implements FavIconRequestor, Comparable<DomainInfo>, Ico
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Returns DomainInfo without subdomain */
|
||||
public static DomainInfo getInstance(final String domain) {
|
||||
return getInstance(domain, false);
|
||||
}
|
||||
|
||||
public static DomainInfo getInstance(final String domain, final boolean includeSubdomain) {
|
||||
if (domain == null) {
|
||||
return null;
|
||||
}
|
||||
final String lcaseTld = getCacheID(domain);
|
||||
synchronized (CACHE) {
|
||||
DomainInfo ret = null;
|
||||
WeakReference<DomainInfo> domainInfo = CACHE.get(lcaseTld);
|
||||
final WeakReference<DomainInfo> domainInfo = CACHE.get(lcaseTld);
|
||||
if (domainInfo == null || (ret = domainInfo.get()) == null) {
|
||||
ret = new DomainInfo(Browser.getHost(lcaseTld), lcaseTld);
|
||||
ret = new DomainInfo(Browser.getHost(lcaseTld, includeSubdomain), lcaseTld);
|
||||
CACHE.put(lcaseTld, new WeakReference<DomainInfo>(ret));
|
||||
}
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user