예제 #1
0
 protected override async Task <string> DownloadAsyncInner(CookieAwareWebClient client,
                                                           FlexibleLoaderGetPreferredDestinationCallback getPreferredDestination,
                                                           FlexibleLoaderReportDestinationCallback reportDestination, Func <bool> checkIfPaused,
                                                           IProgress <long> progress, CancellationToken cancellation)
 {
     using (client.SetDebugMode(OptionDebugMode))
         using (client.SetAutoRedirect(!OptionManualRedirect)) {
             return(await base.DownloadAsyncInner(client, getPreferredDestination, reportDestination, checkIfPaused, progress, cancellation));
         }
 }
예제 #2
0
        public override async Task <bool> PrepareAsync(CookieAwareWebClient client, CancellationToken cancellation)
        {
            for (var i = 0; i < 5; i++)
            {
                var str = await client.DownloadStringTaskAsync(Url);

                if (cancellation.IsCancellationRequested)
                {
                    return(false);
                }

                var f = Regex.Match(str, @"<div class=""fileName"">([^<]+)");
                FileName = f.Success ? f.Groups[1].Value : null;

                var m = Regex.Match(str, @"(https?:\/\/download[^""']+)");
                if (!m.Success)
                {
                    return(false);
                }

                Url = m.Success ? m.Groups[1].Value : null;

                if (Url != null)
                {
                    Logging.Debug("HEAD request is coming…");
                    try {
                        using (client.SetMethod("HEAD"))
                            using (client.SetAutoRedirect(false)) {
                                await client.DownloadStringTaskAsync(Url);

                                Logging.Debug("Done");
                            }
                    } catch (Exception e) {
                        Logging.Warning(e);
                        return(true);
                    }

                    var contentType = client.ResponseHeaders?.Get("Content-Type");
                    Logging.Debug("Content-Type: " + contentType);
                    if (contentType?.IndexOf("text/html") != -1)
                    {
                        Logging.Debug("Redirect to web-page detected! Let’s try again");
                        continue;
                    }
                }

                return(true);
            }

            Logging.Warning("Too many redirects!");
            return(false);
        }
예제 #3
0
        public override async Task <bool> PrepareAsync(CookieAwareWebClient client, CancellationToken cancellation)
        {
            Logging.Debug(Url);
            if (!Url.Contains("://drive.google.com/uc?", StringComparison.OrdinalIgnoreCase))
            {
                return(true);
            }

            // First of all, let’s see if there is an HTML-file under that link
            Logging.Debug("GET request is coming…");
            string webPageContent;

            using (client.SetAutoRedirect(false))
                using (var stream = await client.OpenReadTaskAsync(Url)) {
                    if (cancellation.IsCancellationRequested)
                    {
                        return(false);
                    }

                    // If file is freely available to download, server should redirect user to downloading
                    var location = client.ResponseHeaders?.Get("Location");
                    if (location != null)
                    {
                        Url      = location;
                        FileName = new Uri(Url, UriKind.RelativeOrAbsolute).GetQueryParam("id");
                        Logging.Debug("Download URL is ready: " + location);
                        client.LogResponseHeaders();
                        return(true);
                    }

                    Logging.Debug("Content-Type: " + client.ResponseHeaders?.Get("Content-Type"));
                    if (client.ResponseHeaders?.Get("Content-Type").Contains("text/html", StringComparison.OrdinalIgnoreCase) == false)
                    {
                        return(true);
                    }

                    // Looks like it’s a webpage, now we need to download and parse it
                    webPageContent = (await stream.ReadAsBytesAsync()).ToUtf8String();
                    if (cancellation.IsCancellationRequested)
                    {
                        return(false);
                    }

                    Logging.Debug("…done");
                }

            var doc = new HtmlDocument();

            doc.LoadHtml(webPageContent);

            var link = doc.DocumentNode.SelectSingleNode(@"//a[contains(@href, 'export=download')]").Attributes[@"href"].Value;

            if (link == null)
            {
                NonfatalError.Notify(ToolsStrings.Common_CannotDownloadFile, ToolsStrings.DirectLoader_GoogleDriveChanged);
                return(false);
            }

            Url      = @"https://drive.google.com" + HttpUtility.HtmlDecode(link);
            FileName = HttpUtility.HtmlDecode(doc.DocumentNode.SelectSingleNode(@"//span[@class='uc-name-size']/a")?.InnerText?.Trim());
            Logging.Write($"Google Drive download link: {Url}");

            try {
                var totalSize = HttpUtility.HtmlDecode(
                    doc.DocumentNode.SelectSingleNode(@"//span[@class='uc-name-size']/text()")?.InnerText?.Trim(' ', '(', ')'));
                Logging.Write($"Total size: {totalSize}");
                if (totalSize != null && LocalizationHelper.TryParseReadableSize(totalSize, null, out var size))
                {
                    Logging.Write($"Parsed size: {size} bytes");
                    TotalSize = size;
                }
            } catch (Exception e) {
                Logging.Warning(e);
            }

            if (OptionManualRedirect)
            {
                using (client.SetDebugMode(OptionDebugMode))
                    using (client.SetAutoRedirect(false)) {
                        var redirect = await client.DownloadStringTaskAsync(Url);

                        Logging.Debug(redirect);

                        if (!redirect.Contains("<TITLE>Moved Temporarily</TITLE>"))
                        {
                            NonfatalError.Notify(ToolsStrings.Common_CannotDownloadFile, ToolsStrings.DirectLoader_GoogleDriveChanged);
                            return(false);
                        }

                        var redirectMatch = Regex.Match(redirect, @"href=""([^""]+)", RegexOptions.IgnoreCase);
                        if (!redirectMatch.Success)
                        {
                            NonfatalError.Notify(ToolsStrings.Common_CannotDownloadFile, ToolsStrings.DirectLoader_GoogleDriveChanged);
                            return(false);
                        }

                        Url = HttpUtility.HtmlDecode(redirectMatch.Groups[1].Value);
                        Logging.Debug(Url);
                    }
            }

            return(true);
        }
예제 #4
0
        public override async Task <bool> PrepareAsync(CookieAwareWebClient client, CancellationToken cancellation)
        {
            Logging.Debug(Url);
            if (!Url.Contains("://drive.google.com/uc?", StringComparison.OrdinalIgnoreCase))
            {
                return(true);
            }

            // First of all, let’s see if there is an HTML-file under that link
            Logging.Debug("HEAD request is coming…");
            try {
                using (client.SetMethod("HEAD"))
                    using (client.SetAutoRedirect(false)) {
                        await client.DownloadStringTaskAsync(Url);

                        Logging.Debug("Done");
                    }
            } catch (Exception e) {
                Logging.Warning(e);
            }

            // If file is freely available to download, server should redirect user to downloading
            var location = client.ResponseHeaders?.Get("Location");

            if (location != null)
            {
                Url = location;
                Logging.Debug("Download URL is ready: " + location);
                return(true);
            }

            Logging.Debug("Loading page…");
            var downloadPage = await client.DownloadStringTaskAsync(Url);

            if (cancellation.IsCancellationRequested)
            {
                return(false);
            }

            if (client.ResponseHeaders?.Get("Content-Type").Contains("text/html", StringComparison.OrdinalIgnoreCase) == false)
            {
                return(true);
            }
            var match = Regex.Match(downloadPage, @"href=""(/uc\?export=download[^""]+)", RegexOptions.IgnoreCase);

            if (!match.Success)
            {
                NonfatalError.Notify(ToolsStrings.Common_CannotDownloadFile, ToolsStrings.DirectLoader_GoogleDriveChanged);
                return(false);
            }

            Url = "https://drive.google.com" + HttpUtility.HtmlDecode(match.Groups[1].Value);
            Logging.Write("Google Drive download link: " + Url);

            var fileNameMatch = Regex.Match(downloadPage, @"/<span class=""uc-name-size""><a[^>]*>([^<]+)");

            FileName = fileNameMatch.Success ? fileNameMatch.Groups[1].Value : null;

            try {
                var totalSizeMatch = Regex.Match(downloadPage, @"</a> \((\d+(?:\.\d+)?)([KMGT])\)</span> ");
                if (totalSizeMatch.Success)
                {
                    var value = double.Parse(totalSizeMatch.Groups[1].Value, CultureInfo.InvariantCulture);
                    var unit  = totalSizeMatch.Groups[2].Value;

                    switch (unit.ToLowerInvariant())
                    {
                    case "k":
                        value *= 1024;
                        break;

                    case "m":
                        value *= 1024 * 1024;
                        break;

                    case "g":
                        value *= 1024 * 1024 * 1024;
                        break;

                    case "t":
                        value *= 1024d * 1024 * 1024 * 1024;
                        break;
                    }

                    TotalSize = (long)value;
                }
            } catch (Exception) {
                // ignored
            }

            return(true);
        }