diff --git a/.run/Help.run.xml b/.run/Help.run.xml new file mode 100644 index 0000000..16706ca --- /dev/null +++ b/.run/Help.run.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/composer.json b/composer.json index 6fdc6b1..6880b6b 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,8 @@ }, "minimum-stability": "stable", "require": { - "php": "^8.3" + "php": "^8.3", + "symfony/console": "^7.0" }, "autoload": { "psr-4": { @@ -31,4 +32,4 @@ "docs": "https://git.jrosset.ovh/jrosset/calibre_metadata_parser_ff/wiki", "source": "https://git.jrosset.ovh/jrosset/calibre_metadata_parser_ff" } -} \ No newline at end of file +} diff --git a/run.php b/run.php new file mode 100644 index 0000000..bc81103 --- /dev/null +++ b/run.php @@ -0,0 +1,9 @@ +run(); diff --git a/src/Main.php b/src/Main.php new file mode 100644 index 0000000..ad26497 --- /dev/null +++ b/src/Main.php @@ -0,0 +1,137 @@ +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('Unable to find ' . ($fileInfo->isDir() ? 'directory' : 'file') . ': ' . $fileInfo->getPathname() . ''); + } + //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('Processing directory: ' . $directory->getPathname() . ''); + + if (!$directory->isReadable()) { + $output->writeln('The directory is not readable'); + 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 + { + + } +} \ No newline at end of file