827
|
1 #!/usr/bin/php
|
|
2 <?
|
|
3 require_once "mconfig.inc.php";
|
|
4 require_once "msite.inc.php";
|
|
5
|
|
6 stCheckCLIExec();
|
|
7
|
|
8
|
902
|
9 function wtExec($exe, $args)
|
|
10 {
|
|
11 echo "@@EXEC: ".$exe." ".$args."\n";
|
|
12 if (passthru($exe." ".$args) == 0)
|
|
13 {
|
|
14 echo "Error executing ".$exe.":\n".$args."\n";
|
|
15 return FALSE;
|
|
16 }
|
|
17 return TRUE;
|
|
18 }
|
|
19
|
882
|
20 function wtExecOrDie($exe, $args)
|
|
21 {
|
902
|
22 if (wtExec($exe, $args) === false)
|
|
23 die();
|
882
|
24 }
|
|
25
|
|
26
|
|
27 function wtConvertImage($inFilename, $inFileType, $outFilename, $setDim, $setFormat, $setQuality, $thumb)
|
|
28 {
|
|
29 global $setPreviewPath;
|
|
30
|
|
31 if (($outDim = stGetSetting($setDim)) === FALSE ||
|
|
32 ($outFormat = stGetSetting($osetFormat)) === FALSE ||
|
|
33 ($outQuality = stGetSetting($setQuality)) === FALSE)
|
|
34 {
|
|
35 die("Missing one of res/format/quality settings for '".$outFilename."'\n");
|
|
36 }
|
|
37
|
884
|
38 if ($inFileType == "gfx")
|
|
39 {
|
|
40 // Oh great .. we need gfxconv here because Imagick handles ILBM like shit
|
|
41 $filename = tempnam($setPreviewPath, "tmp");
|
|
42 wtExecOrDie(
|
|
43 "/usr/local/bin/gfxconv",
|
|
44 escapeshellarg($inFilename)." -f png -o ".escapeshellarg($filename));
|
|
45 }
|
|
46 else
|
|
47 $filename = $inFilename;
|
|
48
|
882
|
49 // convert -resize 640x480 -background black -gravity center -extent 640x480
|
|
50 // -unsharp "0x0.75+0.75+0.008" lol.lbm -quality 95 test.jpg
|
884
|
51
|
|
52 // Create conversion entity
|
|
53 $img = new Imagick($filename);
|
|
54 if ($img === false)
|
|
55 die("Oh noes! ImageMagick could not digest the file '".$filename."' (".$inFilename.")\n");
|
|
56
|
|
57 // Get dimensions, setup background
|
|
58 $dim = $img->getImageGeometry();
|
|
59 $img->setBackgroundColor(imagick::COLOR_BLACK);
|
|
60 $img->setGravity(imagick::GRAVITY_CENTER);
|
|
61
|
|
62 // Act based on image size vs. desired size and $thumb mode
|
|
63 if ($thumb || $dim["width"] > $outDim[0] || $dim["height"] > $outDim[1])
|
|
64 {
|
|
65 // Image is larger
|
|
66 $img->resizeImage($outDim[0], $outDim[1], Imagick::FILTER_QUADRATIC, 1);
|
|
67 $img->setExtent($outDim[0], $outDim[1]);
|
|
68 $img->normalizeImage();
|
|
69 $img->unsharpMaskImage(0, 0.5, 1, 0.05);
|
|
70 }
|
|
71 else
|
|
72 if ($dim["width"] < $outDim[0] || $dim["height"] < $outDim[1])
|
|
73 {
|
|
74 // Image is smaller than requested dimension(s)?
|
|
75 $img->resizeImage($outDim[0], $outDim[1], Imagick::FILTER_POINT, 1);
|
|
76 $img->setExtent($outDim[0], $outDim[1]);
|
|
77 }
|
|
78
|
|
79 $img->setFormat($outFormat);
|
|
80 $img->setCompressionQuality($outQuality);
|
|
81
|
|
82 $img->stripImage();
|
|
83 $img->writeImage($outFilename);
|
|
84 $img->removeImage();
|
882
|
85 }
|
|
86
|
|
87
|
898
|
88 function wtRenderSample($inFilename, $outFilename)
|
882
|
89 {
|
898
|
90 $sfreq = intval(stGetSetting("sampleFreq"));
|
|
91 $sduration = intval(stGetSetting("sampleDuration"));
|
|
92 $schannels = intval(stGetSetting("sampleChannels"));
|
882
|
93
|
902
|
94 return wtExec(
|
898
|
95 "/usr/local/bin/openmpt123"
|
|
96 ,
|
884
|
97 "--quiet --render ".
|
|
98 "--samplerate ".$sfreq." ".
|
|
99 "--channels ".$schannels." ".
|
|
100 "--playtime ".$sduration." ".
|
898
|
101 escapeshellarg($inFilename)." -o ".escapeshellarg($outFilename));
|
882
|
102 }
|
|
103
|
|
104
|
898
|
105 function wtConvertSample($inFilename, $outFilename, $opts)
|
882
|
106 {
|
898
|
107 $sfreq = intval(stGetSetting("sampleFreq"));
|
|
108 $sduration = intval(stGetSetting("sampleDuration"));
|
|
109 $schannels = intval(stGetSetting("sampleChannels"));
|
882
|
110
|
898
|
111 foreach ($opts as $okey => $oval)
|
|
112 $optStr .= $okey." ".$oval." ";
|
|
113
|
902
|
114 return wtExec(
|
898
|
115 "/usr/local/bin/avconv",
|
|
116 "-y -t ".intval($sduration)." ".
|
|
117 "-i ".escapeshellarg($inFilename).
|
|
118 " ".$optStr." -ac ".$schannels.
|
|
119 " -map_metadata -1 ".
|
|
120 escapeshellarg($outFilename));
|
882
|
121 }
|
|
122
|
|
123
|
|
124 function wtPurgeDir($path)
|
|
125 {
|
|
126 if (file_exists($path))
|
|
127 wtExecOrDie("/bin/echo", "-fR ".escapeshellarg($path));
|
|
128 }
|
|
129
|
|
130
|
902
|
131 function wtUnpackArchiveTo($atype, $filename, $path)
|
882
|
132 {
|
|
133 // Check file type before doing anything
|
902
|
134 echo "Preparing to unpack archive file '".$filename."' ...\n";
|
|
135 switch ($atype)
|
882
|
136 {
|
|
137 case "LHA":
|
|
138 $exe = "/usr/bin/lha";
|
|
139 $args = "e ".escapeshellarg($filename);
|
|
140 break;
|
|
141
|
|
142 case "ZIP":
|
|
143 $exe = "/usr/bin/unzip";
|
|
144 $args = "-d ".escapeshellarg($path)." ".escapeshellarg($filename);
|
|
145 break;
|
|
146
|
898
|
147 case "RAR":
|
|
148 $exe = "/usr/bin/rar";
|
|
149 $args = "e ".escapeshellarg($filename);
|
|
150 break;
|
|
151
|
882
|
152 default:
|
902
|
153 echo "Unsupported archive file type: ".$atype."\n";
|
898
|
154 return FALSE;
|
882
|
155 }
|
|
156
|
|
157 // Create temporary directory
|
|
158 wtPurgeDir($path);
|
|
159 stMakeDir($path, 0700);
|
|
160
|
|
161 if (!is_dir($path) || chdir($path) === false)
|
902
|
162 {
|
|
163 echo "Failed to chdir to '".$path."', can't unpack archive.\n";
|
|
164 return FALSE;
|
|
165 }
|
882
|
166
|
|
167 // Unpack archive
|
902
|
168 return wtExec($exe, $args);
|
|
169 }
|
|
170
|
|
171
|
|
172 function wtScanArchive($efile, $filename)
|
|
173 {
|
|
174 global $setEntryPath;
|
|
175
|
|
176 $path = stMakePath(FALSE, FALSE, array($setEntryPath, "UNPACKS", $filename));
|
|
177
|
|
178 echo "Attempting to scan archive file '".$filename."' ...\n";
|
|
179
|
|
180 if (wtUnpackArchiveTo($efile["filetype"], $filename, $path)) === false)
|
|
181 return FALSE;
|
882
|
182
|
|
183 // Scan through files ...
|
|
184 $dir = opendir($path);
|
|
185 while (($dentry = readdir($dir)) !== false)
|
|
186 {
|
|
187 }
|
|
188 closedir($dir);
|
|
189
|
|
190 wtPurgeDir($path);
|
902
|
191 return TRUE;
|
882
|
192 }
|
|
193
|
|
194
|
|
195 function wtHandleEntryPreview($compo, $entry, $mode)
|
|
196 {
|
898
|
197 // Get current preview file data
|
|
198 if (!stGetPreviewFileData($compo, $entry, $pdata))
|
|
199 return FALSE;
|
|
200
|
|
201 if ($entry["file_id"] != 0)
|
|
202 $efile = stFetchSQL("SELECT * FROM files WHERE deleted=0 AND id=".$entry["file_id"]);
|
|
203 else
|
|
204 $efile = FALSE;
|
|
205
|
|
206 // Check preview file(s) status
|
|
207 if ($mode == "sta")
|
|
208 {
|
|
209 printf(" %03d | %s%s%s | %-40s | %-5s | %s\n",
|
|
210 $entry["id"],
|
|
211 ($efile !== false) ? "1" : ".",
|
|
212 isset($pdata["file"]) ? "2" : ".",
|
|
213 $pdata["valid"] ? "3" : ".",
|
|
214 $entry["name"]." by ".$entry["author"],
|
|
215 isset($pdata["file"]) ? $pdata["file"]["filetype"] : "",
|
|
216 isset($pdata["file"]) ? $pdata["file"]["filename"] : ""
|
|
217 );
|
|
218 }
|
|
219 else
|
|
220 if ($mode == "upd")
|
|
221 {
|
882
|
222 /*
|
898
|
223 if (previewSourceFile does not exist)
|
882
|
224 {
|
|
225 if (entry is module file)
|
|
226 {
|
|
227 render sample
|
|
228 }
|
|
229 else
|
|
230 if (entry is image file)
|
|
231 {
|
|
232 convert image
|
|
233 }
|
898
|
234 else
|
|
235 if (entry is archive)
|
|
236 {
|
|
237 if compo preview type is image, scan archive for images ..
|
|
238 }
|
|
239 }
|
|
240
|
|
241 if (previewFiles older than previewSourceFile)
|
|
242 {
|
|
243 if (source == audio)
|
|
244 convert via avconv
|
|
245 else
|
|
246 if (source == image)
|
|
247 convert via imagick
|
882
|
248 }
|
|
249
|
|
250 // Based on compo / entry preview type ..
|
|
251
|
|
252 // Convert preview image file, if any
|
|
253 // Create thumbnail for it, too
|
|
254 wtConvertImage($inFilename, $outFilename,
|
|
255 "previewImageSize", "previewImageType",
|
|
256 "previewImageQuality", FALSE);
|
|
257
|
|
258 wtConvertImage($inFilename, $outFilename,
|
|
259 "previewThumbSize", "previewThumbType",
|
|
260 "previewThumbQuality", TRUE);
|
|
261 */
|
898
|
262 }
|
|
263 else
|
|
264 die("OMG!\n");
|
882
|
265 }
|
|
266
|
|
267
|
884
|
268 function wtHandleEntry($compo, $entry, $mode)
|
|
269 {
|
|
270 }
|
|
271
|
|
272
|
827
|
273 //
|
|
274 // Create directories
|
|
275 //
|
|
276 function stMakeDir($path, $perm)
|
|
277 {
|
|
278 if (!file_exists($path))
|
|
279 {
|
|
280 echo " - Creating ".$path."\n";
|
|
281 if (mkdir($path, $perm, TRUE) === false)
|
|
282 die("Could not create directory '".$path."'\n");
|
|
283 }
|
|
284 }
|
|
285
|
|
286
|
|
287 function stInitializeDirs()
|
|
288 {
|
902
|
289 global
|
|
290 $setEntryPath, $setPreviewPath, $setThumbDir,
|
827
|
291 $setEntryPathPerms, $setPrevPathPerms;
|
|
292
|
|
293 echo "Checking for missing directories ...\n";
|
|
294 stMakeDir($setEntryPath, $setEntryPathPerms);
|
|
295 stMakeDir($setPreviewPath, $setPrevPathPerms);
|
880
|
296 stMakeDir(stMakePath(FALSE, FALSE, array($setPreviewPath, $setThumbDir)), $setPrevPathPerms);
|
827
|
297
|
|
298 foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL") as $compo)
|
|
299 {
|
|
300 stMakeDir(stMakePath(FALSE, FALSE, array($setEntryPath, $compo["cpath"])), $setEntryPathPerms);
|
|
301 }
|
|
302 }
|
|
303
|
|
304
|
|
305 //
|
|
306 // Main program starts
|
|
307 //
|
|
308 if ($argc < 2)
|
|
309 {
|
|
310 echo
|
|
311 "faptool - Do stuff with FAPWeb database\n".
|
|
312 "(C) Copyright 2014 ccr/TNSP\n".
|
|
313 "\n".
|
|
314 "Usage: ".$argv[0]." <mode> [args]\n".
|
|
315 "Where mode is one of following:\n".
|
|
316 "\n".
|
|
317 " init\n".
|
|
318 " Create directories for entries and previews, if needed.\n".
|
|
319 "\n".
|
901
|
320 " clean [delete]\n".
|
|
321 " Clean files marked to be deleted. This includes any old\n".
|
|
322 " or stale preview files and entry files.\n"
|
|
323 " Without 'delete' parameter just checks and shows what would\n".
|
|
324 " be deleted, but with it ACTUALLY DELETES THE FILES, SO BE CAREFUL!\n".
|
|
325 "\n".
|
881
|
326 " previews <cmd> [args]\n".
|
|
327 " Where <cmd> is one of:\n".
|
|
328 " status - List files and show what is missing, etc.\n".
|
901
|
329 "\n".
|
|
330 " entry <cmd> [args]\n".
|
|
331 " status - List entries for all compos.\n".
|
|
332 " unpack - Create subdirs and unpack archives under them.\n".
|
827
|
333 "\n";
|
|
334 exit;
|
|
335 }
|
|
336
|
|
337 // Try to connect to database
|
|
338 $spec = stGetSetting("sqlDB");
|
|
339 if (($db = stConnectSQLDBSpec($spec)) === false)
|
|
340 die("Could not connect to SQL database '".$spec."'.\n");
|
|
341
|
|
342 echo "Using database spec '".$spec."'.\n";
|
|
343
|
|
344 // Fetch non-"hardcoded" settings from SQL database
|
|
345 stReloadSettings();
|
|
346
|
|
347 // Set some globals for our benefit
|
900
|
348 $setWidth = 75;
|
827
|
349 $setEntryPath = stGetSetting("entryPath");
|
|
350 $setPreviewPath = stGetSetting("previewPath");
|
|
351 $setPreviewURL = stGetSetting("previewURL");
|
|
352 $setThumbDir = stGetSetting("thumbnailSubDir");
|
832
|
353 $setEntryPathPerms = stGetSetting("entryPathPerms");
|
|
354 $setPrevPathPerms = stGetSetting("previewPathPerms");
|
827
|
355
|
|
356 if ($setEntryPath === FALSE || $setPreviewPath === FALSE ||
|
832
|
357 $setPreviewURL === FALSE || $setThumbDir === FALSE ||
|
|
358 $setEntryPathPerms === FALSE || $setPrevPathPerms === FALSE)
|
827
|
359 {
|
831
|
360 die("Some required settings not defined in mconfig.inc.php!\n");
|
827
|
361 }
|
|
362
|
|
363
|
|
364 // Act according to specified command
|
884
|
365 switch (substr(stCArgLC(1), 0, 3))
|
827
|
366 {
|
884
|
367 case "ini":
|
827
|
368 //
|
|
369 // Initialize the data directories etc
|
|
370 //
|
|
371 stInitializeDirs();
|
|
372 break;
|
|
373
|
901
|
374 case "cle":
|
|
375 $doDelete = (stCArgLC(2) == "delete");
|
|
376 foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL") as $compo)
|
|
377 if (stFetchSQLColumn("SELECT COUNT(*) FROM entries WHERE compo_id=".$compo["id"]) > 0)
|
|
378 {
|
|
379 printf(
|
|
380 "==%'=-".($setWidth-2)."s\n".
|
|
381 sprintf("[ #%03d - %s ]", $compo["id"], substr($compo["name"], 0, 40))
|
|
382 );
|
|
383 echo str_repeat("-", $setWidth)."\n";
|
|
384
|
|
385 foreach (stExecSQL("SELECT * FROM entries WHERE compo_id=".$compo["id"]) as $entry)
|
|
386 {
|
|
387 foreach (stExecSQL("SELECT * FROM files WHERE entry_id=".$entry["id"]) as $efile)
|
|
388 {
|
|
389 if ($efile["delete"] != 0)
|
|
390 {
|
|
391 echo "X";
|
|
392 }
|
|
393 }
|
|
394 }
|
|
395 echo "\n";
|
|
396 echo str_repeat("-", $setWidth)."\n";
|
|
397 }
|
|
398 break;
|
|
399
|
|
400 case "ent":
|
|
401 //
|
|
402 // Entry files handling
|
|
403 //
|
|
404 $mode = substr(stCArgLC(2), 0, 3);
|
|
405 switch ($mode)
|
|
406 {
|
|
407 case "unp":
|
|
408 case "sta":
|
|
409 foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL") as $compo)
|
|
410 if (stFetchSQLColumn("SELECT COUNT(*) FROM entries WHERE compo_id=".$compo["id"]) > 0)
|
|
411 {
|
|
412 printf(
|
|
413 "==%'=-".($setWidth-2)."s\n".
|
|
414 sprintf("[ #%03d - %s ]", $compo["id"], substr($compo["name"], 0, 40))
|
|
415 );
|
|
416 echo str_repeat("-", $setWidth)."\n";
|
|
417
|
|
418 foreach (stExecSQL("SELECT * FROM entries WHERE compo_id=".$compo["id"]) as $entry)
|
|
419 wtHandleEntry($compo, $entry, $mode);
|
|
420
|
|
421 echo str_repeat("-", $setWidth)."\n";
|
|
422 }
|
|
423 break;
|
|
424
|
|
425 case "pac":
|
|
426 break;
|
|
427
|
|
428 case "add":
|
|
429 break;
|
|
430
|
|
431 default:
|
|
432 if ($mode == "")
|
|
433 die("ERROR! Entry command requires a sub-command argument.\n");
|
|
434 else
|
|
435 die("ERROR! Invalid entry sub-command '".stCArg(2)."'.\n");
|
|
436 break;
|
|
437 }
|
|
438 break;
|
|
439
|
884
|
440 case "pre":
|
881
|
441 //
|
|
442 // Preview files handling
|
|
443 //
|
|
444 $mode = substr(stCArgLC(2), 0, 3);
|
|
445 switch ($mode)
|
|
446 {
|
898
|
447 case "upd":
|
881
|
448 case "sta":
|
|
449 foreach (stExecSQL("SELECT * FROM compos WHERE cpath <> '' AND cpath IS NOT NULL") as $compo)
|
898
|
450 if (stFetchSQLColumn("SELECT COUNT(*) FROM entries WHERE compo_id=".$compo["id"]) > 0)
|
881
|
451 {
|
|
452 printf(
|
900
|
453 "==%'=-".($setWidth-2)."s\n".
|
898
|
454 "PrevType : %s\n",
|
|
455 sprintf("[ #%03d - %s ]", $compo["id"], substr($compo["name"], 0, 40)),
|
|
456 $previewTypeList[$compo["preview_type"]][0]);
|
|
457
|
|
458 printf(" %-3s | %-3s | %-40s |\n",
|
|
459 "#ID", "FLG", "Entry name/author");
|
|
460
|
900
|
461 echo str_repeat("-", $setWidth)."\n";
|
881
|
462
|
|
463 foreach (stExecSQL("SELECT * FROM entries WHERE compo_id=".$compo["id"]) as $entry)
|
|
464 wtHandleEntryPreview($compo, $entry, $mode);
|
898
|
465
|
900
|
466 echo str_repeat("=", $setWidth)."\n\n";
|
881
|
467 }
|
|
468 break;
|
|
469
|
901
|
470 case "add":
|
|
471 break;
|
|
472
|
881
|
473 default:
|
|
474 if ($mode == "")
|
|
475 die("ERROR! Previews command requires a sub-command argument.\n");
|
|
476 else
|
|
477 die("ERROR! Invalid previews sub-command '".stCArg(2)."'.\n");
|
|
478 break;
|
|
479 }
|
|
480 break;
|
|
481
|
827
|
482 default:
|
|
483 echo "ERROR! Invalid operation mode '".stCArg(1)."'.\n";
|
|
484 break;
|
|
485 }
|
|
486
|
|
487 ?> |