Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

admin: add capture test for gphoto2 #872

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
admin: add capture test for gphoto2
Change-Id: I6f88022ca76469817f3b0d91882660a9cfc3e8b9
  • Loading branch information
andi34 committed Dec 29, 2024
commit 853407a0cb430e4e5a525d5b23552703f00d37f9
75 changes: 75 additions & 0 deletions admin/capturetest/index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

require_once '../../lib/boot.php';

use Photobooth\PhotoboothCaptureTest;
use Photobooth\Service\ApplicationService;
use Photobooth\Service\LanguageService;
use Photobooth\Utility\PathUtility;

// Login / Authentication check
if (!(
!$config['login']['enabled'] ||
(!$config['protect']['localhost_admin'] && isset($_SERVER['SERVER_ADDR']) && $_SERVER['REMOTE_ADDR'] === $_SERVER['SERVER_ADDR']) ||
(isset($_SESSION['auth']) && $_SESSION['auth'] === true) || !$config['protect']['admin']
)) {
header('location: ' . PathUtility::getPublicPath('login'));
exit();
}

$languageService = LanguageService::getInstance();
$pageTitle = 'Capture test - ' . ApplicationService::getInstance()->getTitle();
include PathUtility::getAbsolutePath('admin/components/head.admin.php');
include PathUtility::getAbsolutePath('admin/helper/index.php');

?>
<div class="w-full h-full grid place-items-center fixed bg-brand-1 overflow-x-hidden overflow-y-auto">
<div class="w-full flex items-center justify-center flex-col px-6 py-12">

<div class="w-full max-w-xl h-144 rounded-lg p-4 md:p-8 bg-white flex flex-col shadow-xl">
<div class="w-full flex items-center pb-3 mb-3 border-b border-solid border-gray-200">
<a href="<?=PathUtility::getPublicPath('admin')?>" class="h-4 mr-4 flex items-center justify-center border-r border-solid border-black border-opacity-20 pr-3">
<span class="fa fa-chevron-left text-brand-1 text-opacity-60 text-md hover:text-opacity-100 transition-all"></span>
</a>
<h2 class="text-brand-1 text-xl font-bold">
<?= $languageService->translate('test_capture') ?>
</h2>
</div>
<?php

$test = new PhotoboothCaptureTest();

foreach ($test->captureCmds as $index => $command) {
// Set filename for each test command
$test->fileName = sprintf('test-%d.jpg', $index + 1);
$test->tmpFile = $test->tmpFolder . DIRECTORY_SEPARATOR . $test->fileName;

$test->addLog('debug', 'Executing Command #' . ($index + 1), ['command' => $command]);

// Execute the command
$test->executeCmd($command);

foreach ($test->logData as $log) {
$level = htmlspecialchars($log['level']);
$message = htmlspecialchars($log['message']);
$context = htmlspecialchars(json_encode($log['context'], JSON_PRETTY_PRINT));

echo '<div class="log-entry">
<div class="log-level ' . $level . '">' . strtoupper($level) . '</div>
<div class="log-message">' . $message . '</div>
<div class="log-context"><pre>' . $context . '</pre></div>
</div>';
}
$test->logData = [];
}

?>
</div>

</div>
</div>

<?php

include PathUtility::getAbsolutePath('admin/components/footer.scripts.php');
include PathUtility::getAbsolutePath('admin/components/footer.admin.php');
119 changes: 119 additions & 0 deletions src/PhotoboothCaptureTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
<?php

namespace Photobooth;

use Photobooth\Enum\FolderEnum;

/**
* Class PhotoboothCaptureTest
*/
class PhotoboothCaptureTest
{
public string $fileName;
public string $tmpFolder;
public string $tmpFile;
public array $logData = [];
public array $captureCmds = [
'gphoto2 --capture-image-and-download --filename=%s',
'gphoto2 --set-config output=Off --capture-image-and-download --filename=%s',
'gphoto2 --trigger-capture --wait-event-and-download=FILEADDED --filename=%s',
'gphoto2 --set-config output=Off --trigger-capture --wait-event-and-download=FILEADDED --filename=%s',
'gphoto2 --wait-event=300ms --capture-image-and-download --filename=%s',
'gphoto2 --set-config output=Off --wait-event=300ms --capture-image-and-download --filename=%s',
];

/**
* PhotoboothCaptureTest constructor.
*/
public function __construct()
{
$this->tmpFolder = FolderEnum::TEMP->absolute();
}

public function addLog(string $level, string $message, array $context = []): void
{
$this->logData[] = [
'level' => $level,
'message' => $message,
'context' => $context
];
}

/**
* Function to iterate through capture commands and execute them.
*/
public function executeCaptureTests(): void
{
foreach ($this->captureCmds as $index => $command) {
// Set filename for each test command
$this->fileName = sprintf('test-%d.jpg', $index + 1);
$this->tmpFile = $this->tmpFolder . DIRECTORY_SEPARATOR . $this->fileName;

$this->addLog('debug', 'Executing Command #' . ($index + 1), ['command' => $command]);

// Execute the command
$this->executeCmd($command);
}
}

/**
* Function to execute a single command.
*
* @param string $command The command to execute
*/
public function executeCmd(string $command): void
{
// Change directory if using gphoto command
if (substr($command, 0, strlen('gphoto')) === 'gphoto') {
chdir(dirname($this->tmpFile));
}

// Prepare the command and redirect stderr to stdout
$cmd = sprintf($command, $this->tmpFile);
$cmd .= ' 2>&1';
$start_time = hrtime(true);
exec($cmd, $output, $returnValue);

// Handle command errors
if ($returnValue) {
$this->addLog('error', 'Command failed', [
'command' => $command,
'output' => $output,
'returnValue' => $returnValue
]);
return;
} else {
$this->addLog('info', 'Command executed successfully', [
'command' => $command,
'output' => $output
]);
}

// Wait for the file to be created, if necessary
$i = 0;
$processingTime = 300; // 30 seconds (300 * 100ms)
while ($i < $processingTime) {
if (file_exists($this->tmpFile)) {
break;
} else {
$i++;
usleep(100000); // Wait 100ms
}
}

// If the file does not exist, print the error and proceed
if (!file_exists($this->tmpFile)) {
$this->addLog('error', 'File was not created', [
'command' => $command,
'output' => $output,
'returnValue' => $returnValue
]);
}
$end_time = hrtime(true);
$execution_time = $end_time - $start_time;
$execution_time_in_seconds = $execution_time / 1e9;
$this->addLog('info', 'Execution time', [
'output' => $execution_time_in_seconds . ' seconds'
]);
}
}