Total Commander Forum Index Total Commander
Форум поддержки пользователей Total Commander
Сайты: Все о Total Commander | Totalcmd.net | Ghisler.com | RU.TCKB
 
 RulesRules   SearchSearch   FAQFAQ   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Single Post  Topic: Авторедактирование списка url-ов на основе HTTP статус кодов 
Author Message
MVV



PostPosted: Sat Jan 28, 2017 01:34    Post subject: Reply with quote

В общем, наворотил я многопроходность, число проходов и таймауты регулируются массивом $passTimeouts (сколько там таймаутов, столько и проходов).
Code:
@echo off
set "ARG_0=%~dpnx0"
powershell.exe -STA -NoProfile "iex (([IO.File]::ReadAllText($Env:ARG_0)) -replace '^(.*\n)*?.*<::::>.*\n', '')" & goto :EOF


Add-Type -Assembly System.Windows.Forms;


$workerCount = 8;
$passTimeouts = @(2000, 5000, 10000, 20000);


function testUrls($defs, $timeout, $workerCount = 1) {
   $job = @{
      queue = [Collections.Queue]::Synchronized((New-Object Collections.Queue (, $defs)));
      timeout = $timeout;
   };
   $script = {
      $job = $args[0];
      while (1) {
         try { $def = $job.queue.Dequeue(); } catch { return; }
         try {
            $req = [Net.WebRequest]::Create($def.url);
            $req.Method = 'HEAD';
            $req.Timeout = $job.timeout;
            $rsp = $req.GetResponse();
            $def.err = '';
         }
         catch {
            $e = $_.Exception;
            while ($e -and $e -isnot [Net.WebException]) { $e = $e.InnerException; }
            $rsp = $e.Response;
            $def.err = $e.Message;
         }
         if ($rsp) {
            $def.code = [int]$rsp.StatusCode;
            $rsp.Close();
         }
      }
   };
   if ($workerCount -gt 1) {
      $workers = @((1 .. $workerCount) | % { $w = [PowerShell]::Create().AddScript($script).AddArgument($job); @{ ps = $w; r = $w.BeginInvoke() } });
      $workers | % { $_.ps.EndInvoke($_.r) };
   }
   else {
      . $script $job;
   }
}


$defs = @([Windows.Forms.Clipboard]::GetText() -split '\r?\n' | ? { $_ -match '^\w+://' } | % { @{ url = $_; } });
$leftDefs = $defs;
$startTime = [DateTime]::Now;

Write-Host "Validating $($defs.Length) urls using $workerCount workers...`n";

$testDef = @{ url = 'http://google.com' };
testUrls @($testDef) 10000 1;
if (!$testDef.code) {
   Write-Host "Oops, self-check failed!";
   $host.SetShouldExit(1);
   return;
}

for ($step = 0; $step -lt $passTimeouts.Length -and $leftDefs.Length; ++$step) {
   $passStartTime = [DateTime]::Now;
   Write-Host "Executing pass #$step using timeout $($passTimeouts[$step])...";
   testUrls $leftDefs $passTimeouts[$step] $workerCount;
   $leftDefs = @($leftDefs | ? { !$_.code; if ($_.code) { Write-Host "$($_.url): $($_.code)" } });
   Write-Host "Pass #$step done in $([int]([DateTime]::Now - $passStartTime).TotalSeconds) seconds, $($leftDefs.Length) urls left.";
   '';
}

if ($leftDefs) {
   Write-Host 'Unresolved urls:';
   $leftDefs | % { Write-Host "$($_.url): $($_.err)" };
   '';
}

$goodUrls = @($defs | ? { $_.code -ge 200 -and $_.code -le 399 } | % { $_.url });
Write-Host "Validation done in $([int]([DateTime]::Now - $startTime).TotalSeconds) seconds.";
if ([Windows.Forms.MessageBox]::Show("Click OK to copy $($goodUrls.Length) good urls.", 'Url Validator', 1) -eq 1) {
   [Windows.Forms.Clipboard]::SetText(($goodUrls -join "`n") + "`n");
}


Каждая ссылка тестируется, пока не будет получен код статуса (который при таймаутах и ошибках DNS недоступен). После каждого прохода в консоль выводятся коды ссылок, полученные на этом проходе, и в конце выводятся ссылки без кодов статуса.
_________________
TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel…


Last edited by MVV on Sat Jan 28, 2017 17:45; edited 1 time in total
View user's profile Send private message ICQ Number


Powered by phpBB © 2001, 2005 phpBB Group