diff --git a/bin/gpm b/bin/gpm index c229f7f89..0a0e1941c 100755 --- a/bin/gpm +++ b/bin/gpm @@ -21,5 +21,7 @@ if (!file_exists(ROOT_DIR . 'index.php')) { $grav = Grav::instance(['loader' => $autoload]); $app = new Application('Grav Package Manager', '0.1.0'); -$app->addCommands(array()); +$app->addCommands(array( + new \Grav\Console\Gpm\FetchCommand($grav), +)); $app->run(); diff --git a/system/src/Grav/Console/Gpm/FetchCommand.php b/system/src/Grav/Console/Gpm/FetchCommand.php new file mode 100644 index 000000000..31d51b9e1 --- /dev/null +++ b/system/src/Grav/Console/Gpm/FetchCommand.php @@ -0,0 +1,136 @@ +grav = $grav; + + // just for the gpm cli we force the filesystem driver cache + $this->grav['config']->set('system.cache.driver', 'default'); + $this->cache = $this->grav['cache']->fetch(md5('cli:gpm')); + + parent::__construct(); + } + + protected function configure() { + $this + ->setName("fetch") + ->addOption( + 'force', + 'f', + InputOption::VALUE_NONE, + 'Force fetching the new data remotely' + ) + ->setDescription("Fetches the data for plugins and themes available") + ->setHelp('The fetch command downloads the list of plugins and themes available'); + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + $this->output = $output; + + $this->setColors(); + $this->fetch($this->output); + } + + private function fetch() + { + if (!$this->cache || $this->input->getOption('force')){ + $data = $this->fetch_data(); + $date = new \DateTime(); + $this->grav['cache']->save(md5('cli:gpm'), $data, 86400); + $date = $date->modify('+1 day')->format('D, d M Y H:i:s'); + $this->cache = $data; + $this->output->writeln("Data cached until ".$date."\n"); + } + } + + private function fetch_data() + { + $this->output->writeln(""); + $this->output->writeln('Fetching data from getgrav.org'); + $this->output->writeln(""); + $curl = $this->getCurl(); + $response = array(); + + $this->progress = new ProgressBar($this->output, count($this->pkg_types)); + $this->progress->setFormat("%message%\n%current%/%max% [%bar%] %percent:3s%%"); + //$progress->setFormat('Downloading %current% files [%bar%] %elapsed:6s% %memory:6s%'); + + $this->progress->setMessage('Task in progress'); + $this->progress->start(); + foreach($this->pkg_types as $pkg_type) { + $this->progress->setMessage('Fetching "'.$pkg_type.'"...'); + $url = $this->repository . '/' . $pkg_type . '.json'; + + curl_setopt($curl, CURLOPT_URL, $url); + $response[$pkg_type] = curl_exec($curl); + + $this->progress->advance(); + } + + curl_close($curl); + $this->progress->setMessage("Fetch completed"); + $this->progress->finish(); + $this->output->writeln(""); + + return $response; + } + + private function setColors() + { + $this->output->getFormatter()->setStyle('normal', new OutputFormatterStyle('white')); + $this->output->getFormatter()->setStyle('red', new OutputFormatterStyle('red', null, array('bold'))); + $this->output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan', null, array('bold'))); + $this->output->getFormatter()->setStyle('green', new OutputFormatterStyle('green', null, array('bold'))); + $this->output->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta', null, array('bold'))); + $this->output->getFormatter()->setStyle('white', new OutputFormatterStyle('white', null, array('bold'))); + } + + private function getCurl($progress = false) + { + $curl = curl_init(); + + curl_setopt($curl, CURLOPT_REFERER, 'Grav GPM v'.GRAV_VERSION); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_USERAGENT, 'Grav GPM v'.GRAV_VERSION); + curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); + + if ($progress) + { + curl_setopt($curl, CURLOPT_NOPROGRESS, false); + curl_setopt($curl, CURLOPT_HEADER, 1); + curl_setopt($curl, CURLOPT_PROGRESSFUNCTION, array($this, 'progress')); + } + + return $curl; + } + + private function progress($download_size, $downloaded) + { + if ($download_size > 0) + { + $this->output->writeln($downloaded / $download_size * 100); + } + } +}