244 lines
7.2 KiB
PHP
244 lines
7.2 KiB
PHP
#!/usr/bin/php
|
|
<?php
|
|
|
|
if (PHP_SAPI != 'cli') {
|
|
exit("Command line execution only.");
|
|
}
|
|
|
|
include __DIR__ . "/../include/boot.php";
|
|
include_once __DIR__ . "/../include/image_processing.php";
|
|
|
|
# Prevent this script from creating offline jobs for tasks such as extracting text.
|
|
# Offline jobs shouldn't be created here as they require a valid user ref to be processed.
|
|
# This is running offline anyway so no need to create more jobs.
|
|
$offline_job_queue = false;
|
|
|
|
$ignoremaxsize = false;
|
|
$noimage = false;
|
|
if ($argc >= 2) {
|
|
$validargs = false;
|
|
if (in_array($argv[1], array('--help', '-help', '-h', '-?'))) {
|
|
echo "To clear the lock after a failed run, ";
|
|
echo "pass in '-clearlock'\n";
|
|
echo "To ignore the maximum preview size configured ($preview_generate_max_file_size), ";
|
|
echo "pass in '-ignoremaxsize'.\n";
|
|
exit("Bye!");
|
|
}
|
|
if (in_array('-ignoremaxsize', $argv)) {
|
|
$ignoremaxsize = true;
|
|
$validargs = true;
|
|
}
|
|
if (in_array('-noimage', $argv)) {
|
|
$noimage = true; #
|
|
$validargs = true;
|
|
}
|
|
if (in_array('-clearlock', $argv)) {
|
|
if (is_process_lock("create_previews")) {
|
|
clear_process_lock("create_previews");
|
|
}
|
|
$validargs = true;
|
|
}
|
|
if (!$validargs) {
|
|
exit("Unknown argv: " . $argv[1]);
|
|
}
|
|
}
|
|
|
|
|
|
# Check for a process lock
|
|
if (is_process_lock("create_previews")) {
|
|
exit("Process lock is in place. Deferring.");
|
|
}
|
|
set_process_lock("create_previews");
|
|
|
|
if (function_exists("pcntl_signal")) {
|
|
$multiprocess = true;
|
|
} else {
|
|
$multiprocess = false;
|
|
}
|
|
|
|
// We store the start date.
|
|
$global_start_time = microtime(true);
|
|
|
|
// We define the number of threads.
|
|
$max_forks = 3;
|
|
|
|
$lock_directory = '.';
|
|
|
|
// We create an array to store children pids.
|
|
$children = array();
|
|
|
|
/**
|
|
* This function clean up the list of children pids.
|
|
* This allow to detect the freeing of a thread slot.
|
|
*/
|
|
function reap_children()
|
|
{
|
|
global $children;
|
|
|
|
$tmp = array();
|
|
|
|
foreach ($children as $pid) {
|
|
if (pcntl_waitpid($pid, $status, WNOHANG) != $pid) {
|
|
array_push($tmp, $pid);
|
|
}
|
|
}
|
|
|
|
$children = $tmp;
|
|
|
|
return count($tmp);
|
|
} // reap_children()
|
|
|
|
|
|
|
|
/**
|
|
* This function is used to process SIGALRM signal.
|
|
* This is usefull when the parent process is killed.
|
|
*/
|
|
function sigalrm_handler()
|
|
{
|
|
die("[SIGALRM] hang in thumbnails creation ?\n");
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* This function is used to process SIGCHLD signal.
|
|
*
|
|
*/
|
|
function sigchld_handler($signal)
|
|
{
|
|
reap_children();
|
|
|
|
pcntl_waitpid(-1, $status, WNOHANG);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* This function is used to process SIGINT signal.
|
|
*
|
|
*/
|
|
function sigint_handler()
|
|
{
|
|
die("[SIGINT] exiting.\n");
|
|
}
|
|
|
|
|
|
// We define the functions to use for signal handling.
|
|
if ($multiprocess) {
|
|
pcntl_signal(SIGALRM, 'sigalrm_handler');
|
|
pcntl_signal(SIGCHLD, 'sigchld_handler');
|
|
}
|
|
$sql = "SELECT ref,
|
|
file_extension,
|
|
IFNULL(preview_attempts, 1) preview_attempts,
|
|
creation_date
|
|
FROM resource
|
|
WHERE ref > 0
|
|
AND no_file <> 1
|
|
AND (preview_attempts < ? OR preview_attempts IS NULL)
|
|
AND file_extension IS NOT NULL
|
|
AND LENGTH(file_extension) > 0
|
|
AND LOWER(file_extension) NOT IN (" . ps_param_insert(count($no_preview_extensions)) . ")";
|
|
$params = array_merge(["i", SYSTEM_MAX_PREVIEW_ATTEMPTS], ps_param_fill($no_preview_extensions, "s"));
|
|
|
|
$extraconditions = "";
|
|
if (!$noimage) {
|
|
$extraconditions .= " AND has_image != ? ";
|
|
$params[] = "i";
|
|
$params[] = RESOURCE_PREVIEWS_ALL;
|
|
}
|
|
|
|
$resources = ps_query($sql . $extraconditions, $params);
|
|
|
|
foreach ($resources as $resource) { // For each resources
|
|
// We wait for a fork emplacement to be freed.
|
|
if ($multiprocess) {
|
|
while (count($children) >= $max_forks) {
|
|
// We clean children list.
|
|
reap_children();
|
|
sleep(1);
|
|
}
|
|
}
|
|
|
|
if (!$multiprocess || count($children) < $max_forks) { // Test if we can create a new fork.
|
|
// fork
|
|
if (!$multiprocess) {
|
|
$pid = false;
|
|
} else {
|
|
$pid = pcntl_fork();
|
|
}
|
|
|
|
if ($pid == -1) {
|
|
die("fork failed!\n");
|
|
} elseif ($pid) {
|
|
array_push($children, $pid);
|
|
} else {
|
|
if ($multiprocess) {
|
|
pcntl_signal(SIGCHLD, SIG_IGN);
|
|
pcntl_signal(SIGINT, SIG_DFL);
|
|
}
|
|
|
|
// Processing resource.
|
|
echo sprintf("Processing resource id " . $resource['ref'] . " - preview attempt #" . $resource['preview_attempts'] . "\n");
|
|
|
|
$start_time = microtime(true);
|
|
|
|
// For each fork, we need a new connection to database.
|
|
sql_connect();
|
|
|
|
# Below added to catch an issue with previews failing when large video files were taking a long time to copy to StaticSync location
|
|
echo "Created at: " . $resource['creation_date'] . "\nTime now: " . date("Y-m-d H:i:s") . "\n";
|
|
$resourceage = time() - strtotime($resource['creation_date']);
|
|
if ($resource['preview_attempts'] > 3 && $resourceage < 1000) {
|
|
echo "Just added so may not have finished copying, resetting attempts \n";
|
|
ps_query("UPDATE resource SET preview_attempts = 0 WHERE ref = ?", array("i", $resource['ref']));
|
|
continue;
|
|
}
|
|
|
|
#check whether resource already has mp3 preview in which case we set preview_attempts to 5
|
|
if (
|
|
$resource['file_extension'] != "mp3"
|
|
&& in_array($resource['file_extension'], $ffmpeg_audio_extensions)
|
|
&& file_exists(get_resource_path($resource['ref'], true, "", false, "mp3"))
|
|
) {
|
|
$ref = $resource['ref'];
|
|
echo "Resource already has mp3 preview\n";
|
|
ps_query("UPDATE resource SET preview_attempts = 5 WHERE ref = ?", array("i", $ref));
|
|
} elseif ($resource['preview_attempts'] < 5 && $resource['file_extension'] != "") {
|
|
if (!empty($resource['file_path'])) {
|
|
$ingested = false;
|
|
} else {
|
|
$ingested = true;
|
|
}
|
|
|
|
# Increment the preview count.
|
|
ps_query("UPDATE resource SET preview_attempts = IFNULL(preview_attempts, 1) + 1 WHERE ref = ?", array("i", $resource['ref']));
|
|
|
|
$success = create_previews($resource['ref'], false, $resource['file_extension'], false, false, -1, $ignoremaxsize, $ingested);
|
|
hook('after_batch_create_preview');
|
|
$success_string = ($success ? "successfully" : "with error" );
|
|
echo sprintf("Processed resource %d %s in %01.2f seconds.\n", $resource['ref'], $success_string, microtime(true) - $start_time);
|
|
}
|
|
|
|
if ($multiprocess) {
|
|
// We exit in order to avoid fork bombing.
|
|
exit(0);
|
|
}
|
|
}
|
|
} // Test if we can create a new fork
|
|
} // For each resources
|
|
|
|
// We wait for all forks to exit.
|
|
if ($multiprocess) {
|
|
while (count($children)) {
|
|
// We clean children list.
|
|
reap_children();
|
|
sleep(1);
|
|
}
|
|
}
|
|
|
|
echo sprintf("Completed in %01.2f seconds.\n", microtime(true) - $global_start_time);
|
|
|
|
clear_process_lock("create_previews");
|