From bdb92142d98dccdee1005918334659ba603b6712 Mon Sep 17 00:00:00 2001 From: Simon Vieille Date: Thu, 25 Apr 2019 10:28:03 +0200 Subject: [PATCH] add Parser and refactor CheckCommand --- src/Deblan/Command/CheckCommand.php | 157 +++++++++++++++++++--------- src/Deblan/Whois/Parser.php | 60 +++++++++++ 2 files changed, 169 insertions(+), 48 deletions(-) create mode 100644 src/Deblan/Whois/Parser.php diff --git a/src/Deblan/Command/CheckCommand.php b/src/Deblan/Command/CheckCommand.php index 3fa9f82..ce71090 100644 --- a/src/Deblan/Command/CheckCommand.php +++ b/src/Deblan/Command/CheckCommand.php @@ -8,6 +8,7 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Command\Command as BaseCommand; use Symfony\Component\Console\Helper\Table; use Symfony\Component\Process\Process; +use Deblan\Whois\Parser; /** * class CheckCommand. @@ -26,6 +27,16 @@ class CheckCommand extends BaseCommand */ protected $fails = []; + /** + * @var InputInterface + */ + protected $input; + + /** + * @var OutputInterface + */ + protected $output; + /** * {@inheritdoc} */ @@ -33,7 +44,7 @@ class CheckCommand extends BaseCommand { $this ->setName('check') - ->addArgument('domains', InputArgument::REQUIRED, ''); + ->addArgument('domains', InputArgument::REQUIRED, 'List of domains separated by commas'); } /** @@ -41,22 +52,97 @@ class CheckCommand extends BaseCommand */ protected function execute(InputInterface $input, OutputInterface $output) { - $domains = explode(',', $input->getArgument('domains')); - $domains = array_map('trim', $domains); + $this->input = $input; + $this->output = $output; - sort($domains); + $this->checkDomains(); - foreach ($domains as $domain) { - $this->check($domain); + $table = new Table($output); + $table->setHeaders(['Domain', 'Date']); + + foreach ($this->sort($this->successes) as $result) { + $table->addRow([ + $result['domain'], + $this->createDateRender($result['expiryDate']), + ]); } - usort($this->successes, function($a, $b) { - if ($a[2] > $b[2]) { + foreach ($this->sort($this->fails) as $result) { + $table->addRow([ + $result['domain'], + $result['expiryDate'], + ]); + } + + $table->render(); + } + + /** + * Extracts domains. + * + * @return array + */ + protected function getDomains():array + { + $domains = explode(',', $this->input->getArgument('domains')); + $domains = array_map('trim', $domains); + + return $domains; + } + + /** + * Checks domains. + */ + protected function checkDomains():void + { + foreach ($this->getDomains() as $domain) { + $data = $this->checkDomain($domain); + + if ($data['expiryDate'] === null) { + $this->fails[] = $data; + } else { + $this->successes[] = $data; + } + } + } + + /** + * Checks domain. + * + * @return array + */ + protected function checkDomain($domain):array + { + $process = new Process(['whois', $domain]); + $process->run(); + + $whois = $process->getOutput(); + $parser = new Parser($whois); + $expiryDate = $parser->getExpiryDate(); + + return [ + 'domain' => $domain, + 'expiryDate' => $expiryDate, + 'comparaison' => $expiryDate ? $expiryDate->getTimestamp() : 'FAIL', + ]; + } + + /** + * Sorts by expiry date and domain. + * + * @param array $data + * + * @return array + */ + protected function sort(array $data):array + { + usort($data, function ($a, $b) { + if ($a['comparaison'] > $b['comparaison']) { return 1; } - if ($a[2] === $b[2]) { - if ($a[0] > $b[0]) { + if ($a['comparaison'] === $b['comparaison']) { + if ($a['domain'] > $b['domain']) { return 1; } @@ -66,53 +152,28 @@ class CheckCommand extends BaseCommand return 0; }); - foreach ($this->successes as $k => $v) { - unset($this->successes[$k][2]); - } - - $results = array_merge($this->successes, $this->fails); - - $table = new Table($output); - $table - ->setHeaders(['Domain', 'Date']) - ->setRows($results); - - $table->render(); + return $data; } - protected function check($domain) + /** + * Creates date render for the table. + * + * @param \DateTime $date + * + * @return string + */ + protected function createDateRender(\DateTime $date):string { - $process = new Process(['whois', $domain]); - $process->run(); + $timestamp = $date->getTimestamp(); - if (!$process->isSuccessful()) { - $this->fails[] = [$domain, 'FAIL']; - - return; - } - - $whois = $process->getOutput(); - - preg_match('/Expiry Date: ([^\s]+)/i', $whois, $match); - - if (!isset($match[0])) { - $this->fails[] = [$domain, 'FAIL']; - - return; - } - - $date = new \DateTime($match[1]); - - if ($date->getTimestamp() - time() < 3600*24*14) { + if ($timestamp - time() < 3600 * 24 * 14) { $color = 'red'; - } elseif ($date->getTimestamp() - time() < 3600*24*30) { + } elseif ($timestamp - time() < 3600 * 24 * 30) { $color = 'yellow'; } else { $color = 'green'; } - $content = sprintf('%s', $color, $date->format('Y-m-d H:i:s')); - - $this->successes[] = [$domain, $content, $date->format('Y-m-d H:i:s')]; + return sprintf('%s', $color, $date->format('Y-m-d H:i:s')); } } diff --git a/src/Deblan/Whois/Parser.php b/src/Deblan/Whois/Parser.php new file mode 100644 index 0000000..f823165 --- /dev/null +++ b/src/Deblan/Whois/Parser.php @@ -0,0 +1,60 @@ + + */ +class Parser +{ + /** + * @var string + */ + protected $whois; + + /** + * Constructor. + * + * @param mixed $whois + */ + public function __construct(string $whois) + { + $this->whois = $whois; + } + + /** + * Extracts expiry date. + * + * @return DateTime|null + */ + public function getExpiryDate(): ? \DateTime + { + $formats = [ + 'expiration date', + 'expiry date', + 'expires on', + 'paid-till', + 'renewal', + 'expires', + 'domain_datebilleduntil', + 'expiration', + 'registry expiry', + 'registrar registration expiration', + ]; + + foreach ($formats as $format) { + preg_match('/'.preg_quote($format).'\s*:?\s*([^\s]+)/i', $this->whois, $match); + + if (isset($match[1])) { + try { + return new \DateTime($match[1]); + } catch (\Exception $e) { + } + } + } + + return null; + } +}