Create main command

master
Julien Rosset 1 year ago
parent 29f1e1c0b2
commit f4c9014c79

@ -0,0 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Help" type="PhpLocalRunConfigurationType" factoryName="PHP Console"
path="$PROJECT_DIR$/run.php" scriptParameters="--help">
<method v="2"/>
</configuration>
</component>

@ -8,7 +8,8 @@
}, },
"minimum-stability": "stable", "minimum-stability": "stable",
"require": { "require": {
"php": "^8.3" "php": "^8.3",
"symfony/console": "^7.0"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

@ -0,0 +1,9 @@
<?php
/** @noinspection PhpUnhandledExceptionInspection */
require_once __DIR__ . '/vendor/autoload.php';
use jrosset\Main;
(new Main())
->run();

@ -0,0 +1,137 @@
<?php
namespace jrosset;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use RegexIterator;
use SplFileInfo;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\SingleCommandApplication;
use Throwable;
/**
* The "main" command
*/
class Main
{
/**
* Argument name for input files
*/
private const string ARGUMENT_FILES = 'files';
/**
* @var SingleCommandApplication The command
*/
private readonly SingleCommandApplication $command;
/**
* Initialization
*/
public function __construct()
{
$this->command = (new SingleCommandApplication())
->setName('calibre_metadata_parser_ff')
->setDescription(<<<'EOF'
Calibre metadata parser for FanFiction files
Each input file, if valid (EPUB file), is transformed to a Calibre input directory, containing the EPUB file and the metadata file (metadata.opf).
The metadata are extracted from the "title" page of the EPUB, based on FicHub.net or FF2EBOOK.com.
EOF
)
->addArgument(
Main::ARGUMENT_FILES,
InputArgument::REQUIRED | InputArgument::IS_ARRAY,
'The files or directories to process'
)
->setCode($this->execute(...));
}
/**
* Run the command
*
* @return void
*
* @throws Throwable If an error occurs
*/
public function run(): void
{
$this->command->run();
}
/**
* Execute the command
*
* @param InputInterface $input The command line input
* @param OutputInterface $output The command line output
*
* @return int The command exit status code
*
* @throws Throwable If an error occurs
*/
private function execute(InputInterface $input, OutputInterface $output): int
{
foreach ($input->getArgument(self::ARGUMENT_FILES) as $file) {
//region Check if file or directory exists
$fileInfo = new SplFileInfo($file);
if (!file_exists($file)) {
$output->writeln('<error>Unable to find ' . ($fileInfo->isDir() ? 'directory' : 'file') . ': ' . $fileInfo->getPathname() . '</error>');
}
//endregion
if ($fileInfo->isDir()) {
$this->processDirectory($file, $output);
} else {
$this->processFile($file, $output);
}
}
return Command::SUCCESS;
}
/**
* Process a directory
*
* @param SplFileInfo $directory The directory
* @param OutputInterface $output The command line output
*
* @return void
*
* @throws Throwable If an error occurs
*/
private function processDirectory(SplFileInfo $directory, OutputInterface $output): void
{
$output->writeln('<info>Processing directory: ' . $directory->getPathname() . '</info>');
if (!$directory->isReadable()) {
$output->writeln('<error>The directory is not readable</error>');
return;
}
$directoryIterator = new RecursiveDirectoryIterator($directory->getPathname());
$directoryIterator = new RecursiveIteratorIterator($directoryIterator);
$directoryIterator = new RegexIterator($directoryIterator, /** @lang PhpRegExp */ '/\.epub$/', RegexIterator::MATCH);
/** @var SplFileInfo $file */
foreach ($directoryIterator as $file) {
$this->processFile($file, $output);
}
}
/**
* Process a file
*
* @param SplFileInfo $file The file
* @param OutputInterface $output The command line output
*
* @return void
*
* @throws Throwable If an error occurs
*/
private function processFile(SplFileInfo $file, OutputInterface $output): void
{
}
}
Loading…
Cancel
Save