8 * @package Adapter_Cutycapt
9 * @author Christian Weiske <cweiske@cweiske.de>
10 * @copyright 2014 Christian Weiske
11 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
12 * @link http://cweiske.de/phancap.htm
17 * Screenshot rendering using the "cutycapt" command line tool.
20 * @package Adapter_Cutycapt
21 * @author Christian Weiske <cweiske@cweiske.de>
22 * @copyright 2014 Christian Weiske
23 * @license http://www.gnu.org/licenses/agpl.html GNU AGPL v3
24 * @version Release: @package_version@
25 * @link http://cweiske.de/phancap.htm
27 class Adapter_Cutycapt
39 protected $lockFile = null;
42 * Check if all dependencies are available.
44 * @return mixed TRUE if all is fine, array with error messages otherwise
46 public function isAvailable()
48 $old = error_reporting(error_reporting() & ~E_STRICT);
50 if (\System::which('xvfb-run') === false) {
51 $arErrors[] = '"xvfb-run" is not installed';
53 if (\System::which('cutycapt') === false) {
54 $arErrors[] = '"cutycapt" is not installed';
56 if (\System::which('convert') === false) {
57 $arErrors[] = '"convert" (imagemagick) is not installed';
60 error_reporting($old);
61 if (count($arErrors)) {
69 * Render a website screenshot
71 * @param Image $img Image configuration
72 * @param Options $options Screenshot configuration
75 * @throws \Exception When something fails
77 public function render(Image $img, Options $options)
79 $format = $options->values['sformat'];
80 if ($format == 'jpg') {
84 $serverNumber = $this->getServerNumber($options);
85 $tmpPath = $img->getPath() . '-tmp';
87 . ' --url=' . escapeshellarg($options->values['url'])
88 . ' --out-format=' . escapeshellarg($format)
89 . ' --out=' . escapeshellarg($tmpPath)
91 . ' --min-width=' . $options->values['bwidth'];
92 if ($options->values['bheight'] !== null) {
93 $cmd .= ' --min-height=' . $options->values['bheight'];
98 . ' --server-args="-screen 0, 1024x768x24"'
99 . ' --server-num=' . $serverNumber;
100 Executor::run($xvfbcmd . ' ' . $cmd);
102 $this->resize($tmpPath, $img, $options);
106 * Get a free X server number.
108 * Each xvfb-run process needs its own free server number.
109 * Needed for multiple parallel requests.
111 * @return integer Server number
113 protected function getServerNumber()
115 //clean stale lock files
122 $f = $this->config->cacheDir . 'tmp-curlycapt-server-' . $num . '.lock';
123 $this->lockHdl = fopen($f, 'w');
124 if (flock($this->lockHdl, LOCK_EX | LOCK_NB)) {
125 $this->lockFile = $f;
129 fclose($this->lockHdl);
131 } while ($num < 200);
134 throw new \Exception('Too many requests running');
137 $this->lockFile = $f;
142 * Unlock lock file and clean up old lock files
146 public function cleanup()
148 if ($this->lockFile !== null && $this->lockHdl) {
149 flock($this->lockHdl, LOCK_UN);
150 unlink($this->lockFile);
154 $this->config->cacheDir . 'tmp-curlycapt-server-*.lock'
158 foreach ($lockFiles as $file) {
159 if ($now - filemtime($file) > 120) {
160 //delete stale lock file; probably something crashed.
167 * Convert an image to the given size.
169 * Target file is the path of $img.
171 * @param string $tmpPath Path of image to be scaled.
172 * @param Image $img Image configuration
173 * @param Options $options Screenshot configuration
177 protected function resize($tmpPath, Image $img, Options $options)
179 if ($options->values['sformat'] == 'pdf') {
181 rename($tmpPath, $img->getPath());
186 if ($options->values['smode'] == 'screen') {
187 $crop = ' -crop ' . $options->values['swidth']
188 . 'x' . $options->values['sheight']
192 $convertcmd = 'convert'
193 . ' ' . escapeshellarg($tmpPath)
194 . ' -resize ' . $options->values['swidth']
196 . ' ' . escapeshellarg($img->getPath());
197 Executor::run($convertcmd);
198 //var_dump($convertcmd);die();
203 * Set phancap configuration
205 * @param Config $config Phancap configuration
209 public function setConfig(Config $config)
211 $this->config = $config;