read filenames from cli
[surrogator.git] / surrogator.php
1 #!/usr/bin/env php
2 <?php
3 namespace surrogator;
4 $cfgFile = __DIR__ . '/data/surrogator.config.php';
5 if (!file_exists($cfgFile)) {
6     $cfgFile = '/etc/surrogator.config.php';
7     if (!file_exists($cfgFile)) {
8         logErr(
9             "Configuration file does not exist.\n"
10             . "Copy data/surrogator.config.php.dist to data/surrogator.config.php"
11         );
12         exit(2);
13     }
14 }
15 require $cfgFile;
16
17 array_shift($argv);
18 $files = array();
19 foreach ($argv as $arg) {
20     if ($arg == '-v' || $arg == '--verbose') {
21         ++$logLevel;
22     } else if ($arg == '-vv') {
23         $logLevel += 2;
24     } else if ($arg == '-q' || $arg == '--quiet') {
25         $logLevel = 0;
26     } else if ($arg == '-f' || $arg == '--force') {
27         $forceUpdate = true;
28     } else if ($arg == '-h' || $arg == '--help') {
29         showHelp();
30         exit(4);
31     } else if ($arg == '--version') {
32         echo "surrogator 0.0.1\n";
33         exit();
34     } else if (file_exists($arg)) {
35         $files[] = $arg;
36     } else {
37         logErr('Unknown argument: ' . $arg);
38         exit(3);
39     }
40 }
41
42 function showHelp()
43 {
44     echo <<<HLP
45 Usage: php surrogator.php [options] [filename(s)]
46
47 surrogator - a simple libravatar server
48  Put files in raw/ dir and run surrogator.php to generate different sizes
49
50 Options:
51
52  -h, --help     Show help
53  -v, --verbose  Be verbose (more log messages, also -vv)
54  -q, --quiet    Be quiet (no log messages)
55  -f, --force    Force update of all files
56      --version  Show program version
57
58 filenames       One or several files whose small images shall get generated.
59                 If none given, all will be checked
60
61 HLP;
62 }
63
64 if (!isset($rawDir)) {
65     logErr('$rawDir not set');
66     exit(1);
67 }
68 if (!isset($varDir)) {
69     logErr('$varDir not set');
70     exit(1);
71 }
72 if (!isset($sizes)) {
73     logErr('$sizes not set');
74     exit(1);
75 }
76 if (!isset($maxSize)) {
77     logErr('$maxSize not set');
78     exit(1);
79 }
80 if (!isset($logLevel)) {
81     logErr('$logLevel not set');
82     exit(1);
83 }
84
85
86 if (!is_dir($varDir . '/square')) {
87     log('creating square dir: ' . $varDir . '/square');
88     mkdir($varDir . '/square', 0755, true);
89 }
90 log('sizes: ' . implode(', ', $sizes), 2);
91 foreach ($sizes as $size) {
92     if (!is_dir($varDir . '/' . $size)) {
93         log('creating size dir: ' . $varDir . '/' . $size);
94         mkdir($varDir . '/' . $size, 0755);
95     }
96 }
97
98 if (count($files)) {
99     $fileInfos = array();
100     foreach ($files as $file) {
101         $fileInfos[] = new \SplFileInfo($file);
102     }
103 } else {
104     $fileInfos = new \RegexIterator(
105         new \DirectoryIterator($rawDir),
106         '#^.+\.(png|jpg)$#'
107     );
108 }
109 foreach ($fileInfos as $fileInfo) {
110     $origPath   = $fileInfo->getPathname();
111     $fileName   = $fileInfo->getFilename();
112     $ext        = strtolower(substr($fileName, strrpos($fileName, '.') + 1));
113     $squarePath = $varDir . '/square/'
114         . substr($fileName, 0, -strlen($ext)) . 'png';
115
116     log('processing ' . $fileName, 1);
117     if (image_uptodate($origPath, $squarePath)) {
118         log(' image up to date', 2);
119         continue;
120     }
121
122     if (!createSquare($origPath, $ext, $squarePath, $maxSize)) {
123         continue;
124     }
125
126     if ($fileName == 'default.png') {
127         $md5 = $sha256 = 'default';
128     } else {
129         list($md5, $sha256) = getHashes($fileName);
130     }
131
132     log(' creating sizes for ' . $fileName, 2);
133     log(' md5:    ' . $md5, 3);
134     log(' sha256: ' . $sha256, 3);
135     $imgSquare = imagecreatefrompng($squarePath);
136     foreach ($sizes as $size) {
137         log(' size ' . $size, 3);
138         $sizePathMd5    = $varDir . '/' . $size . '/' . $md5 . '.png';
139         $sizePathSha256 = $varDir . '/' . $size . '/' . $sha256 . '.png';
140
141         $imgSize = imagecreatetruecolor($size, $size);
142         imagealphablending($imgSize, false);
143         imagefilledrectangle(
144             $imgSize, 0, 0, $size - 1, $size - 1,
145             imagecolorallocatealpha($imgSize, 0, 0, 0, 127)
146         );
147         imagecopyresampled(
148             $imgSize, $imgSquare, 
149             0, 0, 0, 0,
150             $size, $size, $maxSize, $maxSize
151         );
152         imagesavealpha($imgSize, true);
153         imagepng($imgSize, $sizePathMd5);
154         imagepng($imgSize, $sizePathSha256);
155         imagedestroy($imgSize);
156         
157     }
158     imagedestroy($imgSquare);
159 }
160
161 function getHashes($fileName)
162 {
163     $fileNameNoExt = substr($fileName, 0, -strlen(strrpos($fileName, '.')) - 2);
164     $emailAddress  = trim(strtolower($fileNameNoExt));
165
166     return array(
167         md5($emailAddress), hash('sha256', $emailAddress)
168     );
169 }
170
171
172 function createSquare($origPath, $ext, $targetPath, $maxSize)
173 {
174     if ($ext == 'png') {
175         $imgOrig = imagecreatefrompng($origPath);
176     } else if ($ext == 'jpg' || $ext == 'jpeg') {
177         $imgOrig = imagecreatefromjpeg($origPath);
178     } else {
179         //unsupported format
180         return false;
181     }
182
183     if ($imgOrig === false) {
184         logErr('Error loading image file: ' . $origPath);
185         return false;
186     }
187
188     $imgSquare = imagecreatetruecolor($maxSize, $maxSize);
189     imagealphablending($imgSquare, false);
190     imagefilledrectangle(
191         $imgSquare, 0, 0, $maxSize - 1, $maxSize - 1,
192         imagecolorallocatealpha($imgSquare, 0, 0, 0, 127)
193     );
194     imagealphablending($imgSquare, true);
195
196     $oWidth    = imagesx($imgOrig);
197     $oHeight   = imagesy($imgOrig);
198     if ($oWidth > $oHeight) {
199         $flScale = $maxSize / $oWidth;
200     } else {
201         $flScale = $maxSize / $oHeight;
202     }
203     $nWidth  = (int)($oWidth * $flScale);
204     $nHeight = (int)($oHeight * $flScale);
205
206     imagecopyresampled(
207         $imgSquare, $imgOrig, 
208         ($maxSize - $nWidth) / 2, ($maxSize - $nHeight) / 2,
209         0, 0,
210         $nWidth, $nHeight,
211         $oWidth, $oHeight
212     );
213
214     imagesavealpha($imgSquare, true);
215     imagepng($imgSquare, $targetPath);
216
217     imagedestroy($imgSquare);
218     imagedestroy($imgOrig);
219     return true;
220 }
221
222 function image_uptodate($sourcePath, $targetPath)
223 {
224     global $forceUpdate;
225     if ($forceUpdate) {
226         return false;
227     }
228     if (!file_exists($targetPath)) {
229         return false;
230     }
231     if (filemtime($sourcePath) > filemtime($targetPath)) {
232         //source newer
233         return false;
234     }
235
236     return true;
237 }
238
239 function log($msg, $level = 1)
240 {
241     global $logLevel;
242     if ($level <= $logLevel) {
243         echo $msg . "\n";
244     }
245 }
246
247 function logErr($msg)
248 {
249     file_put_contents('php://stderr', $msg . "\n");
250 }
251
252 ?>