From: Christian Weiske Date: Mon, 31 Mar 2014 12:53:00 +0000 (+0200) Subject: first working version X-Git-Tag: v0.1.0~34 X-Git-Url: https://git.cweiske.de/phancap.git/commitdiff_plain/9a568c09ae8cef2f0222e82dc93ed122615c2590 first working version --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7426688 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/www/imgcache diff --git a/src/phancap/Adapter/Cutycapt.php b/src/phancap/Adapter/Cutycapt.php new file mode 100644 index 0000000..173a86c --- /dev/null +++ b/src/phancap/Adapter/Cutycapt.php @@ -0,0 +1,57 @@ +getPath() . '-tmp'; + $cmd = 'cutycapt' + . ' --url=' . escapeshellarg($options->values['url']) + . ' --out-format=' . escapeshellarg($options->values['sformat']) + . ' --out=' . escapeshellarg($tmpPath) + . ' --max-wait=10000' + . ' --min-width=' . $options->values['bwidth']; + if ($options->values['bheight'] !== null) { + $cmd .= ' --min-height=' . $options->values['bheight']; + } + + $xvfbcmd = 'xvfb-run' + . ' -e /dev/stdout' + . ' --server-args="-screen 0, 1024x768x24"'; + Executor::run($xvfbcmd . ' ' . $cmd); + + $this->resize($tmpPath, $img, $options); + } + + protected function resize($tmpPath, $img, $options) + { + if ($options->values['sformat'] == 'pdf') { + //nothing to resize. + rename($tmpPath, $img->getPath()); + return; + } + + $crop = ''; + if ($options->values['smode'] == 'screen') { + $crop = ' -crop ' . $options->values['swidth'] + . 'x' . $options->values['sheight'] + . '+0x0'; + } + + $convertcmd = 'convert' + . ' ' . escapeshellarg($tmpPath) + . ' -resize ' . $options->values['swidth'] + . $crop + . ' ' . escapeshellarg($img->getPath()); + Executor::run($convertcmd); + //var_dump($convertcmd);die(); + unlink($tmpPath); + } +} +?> diff --git a/src/phancap/Config.php b/src/phancap/Config.php new file mode 100644 index 0000000..d69bd04 --- /dev/null +++ b/src/phancap/Config.php @@ -0,0 +1,56 @@ +cacheDir = getcwd() . '/imgcache/'; + $this->cacheDirUrl = $this->getCurrentUrlDir() . '/imgcache/'; + } + + public function setupCheck() + { + if (!is_dir($this->cacheDir)) { + throw new \Exception('Cache directory does not exist: ' . $this->cacheDir); + } + if (!is_writable($this->cacheDir)) { + throw new \Exception('Cache directory is not writable: ' . $this->cacheDir); + } + } + + protected function getCurrentUrl() + { + if (!isset($_SERVER['REQUEST_SCHEME'])) { + $_SERVER['REQUEST_SCHEME'] = 'http'; + } + return $_SERVER['REQUEST_SCHEME'] . '://' + . $_SERVER['HTTP_HOST'] + . preg_replace('/#.*$/', '', $_SERVER['REQUEST_URI']); + } + + protected function getCurrentUrlDir() + { + $url = $this->getCurrentUrl(); + $url = preg_replace('/\?.*$/', '', $url); + if (substr($url, -1) == '/') { + return $url; + } + + return substr($url, 0, -strlen(basename($url)) - 1); + } +} +?> diff --git a/src/phancap/Executor.php b/src/phancap/Executor.php new file mode 100644 index 0000000..12a34c3 --- /dev/null +++ b/src/phancap/Executor.php @@ -0,0 +1,17 @@ +&1', $arOutput, $exitcode); + if ($exitcode != 0) { + //FIXME: do something with $arOutput + echo implode("\n", $arOutput) . "\n"; + throw new \Exception('Error running cutycapt', $exitcode); + } + } +} + +?> diff --git a/src/phancap/Image.php b/src/phancap/Image.php new file mode 100644 index 0000000..6750cfc --- /dev/null +++ b/src/phancap/Image.php @@ -0,0 +1,30 @@ +name = $name; + } + + public function getPath() + { + return $this->config->cacheDir . $this->name; + } + + public function getUrl() + { + return $this->config->cacheDirUrl . $this->name; + } + + public function setConfig(Config $config) + { + $this->config = $config; + } +} +?> \ No newline at end of file diff --git a/src/phancap/Options.php b/src/phancap/Options.php index b5c96d9..ee129e8 100644 --- a/src/phancap/Options.php +++ b/src/phancap/Options.php @@ -11,6 +11,7 @@ class Options 'title' => 'Website URL', 'default' => null, 'type' => 'url', + 'required' => true, ), 'bwidth' => array( 'title' => 'Browser width', @@ -31,7 +32,7 @@ class Options */ 'swidth' => array( 'title' => 'Screenshot width', - 'default' => 300, + 'default' => null, 'type' => 'int', 'min' => 16, 'max' => 8192, @@ -69,8 +70,14 @@ class Options foreach (static::$options as $name => $arOption) { $this->values[$name] = $arOption['default']; if (!isset($arValues[$name])) { + if (isset($arOption['required'])) { + throw new \InvalidArgumentException( + $name . ' parameter missing' + ); + } continue; } + if ($arOption['type'] == 'url') { $this->values[$name] = $this->validateUrl($arValues[$name]); } else if ($arOption['type'] == 'int') { @@ -100,6 +107,9 @@ class Options protected function calcPageSize() { + if ($this->values['swidth'] === null) { + $this->values['swidth'] = $this->values['bwidth']; + } if ($this->values['smode'] == 'page') { return; } diff --git a/src/phancap/Repository.php b/src/phancap/Repository.php new file mode 100644 index 0000000..2058bb6 --- /dev/null +++ b/src/phancap/Repository.php @@ -0,0 +1,46 @@ +config = $config; + } + + public function getImage(Options $options) + { + $name = $this->getFilename($options); + $img = new Image($name); + $img->setConfig($this->config); + if (!$this->isAvailable($img)) { + $this->render($img, $options); + } + return $img; + } + + public function getFilename(Options $options) + { + return parse_url($options->values['url'], PHP_URL_HOST) + . '-' . md5(\serialize($options->values)) + . '.' . $options->values['sformat']; + } + + public function isAvailable(Image $img) + { + $path = $img->getPath(); + if (!file_exists($path)) { + return false; + } + //FIXME: add cache lifetime check + + return true; + } + + protected function render(Image $img, Options $options) + { + $adapter = new Adapter_Cutycapt(); + $adapter->render($img, $options); + } +} +?> diff --git a/www/get.php b/www/get.php index 5212e99..6bb5c7f 100644 --- a/www/get.php +++ b/www/get.php @@ -3,6 +3,8 @@ namespace phancap; /** * Get a screenshot for a website. */ +header('HTTP/1.0 500 Internal Server Error'); + if (file_exists(__DIR__ . '/../src/phancap/Autoloader.php')) { include_once __DIR__ . '/../src/phancap/Autoloader.php'; Autoloader::register(); @@ -10,15 +12,30 @@ if (file_exists(__DIR__ . '/../src/phancap/Autoloader.php')) { include_once 'phancap/Autoloader.php'; } +$config = new Config(); +$config->setupCheck(); + $options = new Options(); try { $options->parse($_GET); } catch (\InvalidArgumentException $e) { header('HTTP/1.0 400 Bad Request'); header('Content-type: text/plain'); - echo $e->getMessage(); + echo $e->getMessage() . "\n"; exit(1); } -var_dump($options->values); +$rep = new Repository(); +$rep->setConfig($config); +try { + $img = $rep->getImage($options); + header('HTTP/1.0 302 Found'); + header('Location: ' . $img->getUrl()); +} catch (\Exception $e) { + //FIXME: handle 404s and so properly + header('HTTP/1.0 500 Internal Server error'); + header('Content-type: text/plain'); + echo $e->getMessage() . "\n"; + exit(2); +} ?>