feat: ✨ add preview providers
This commit is contained in:
parent
f41df55ff2
commit
a7da64b4de
@ -2,13 +2,6 @@
|
||||
"name": "nextcloud/opds_catalog",
|
||||
"description": "An example description",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"authors": [
|
||||
{
|
||||
"name": "example",
|
||||
"email": "example@example.com",
|
||||
"homepage": "https://example.com"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"OCA\\OpdsCatalog\\": "lib/"
|
||||
@ -17,7 +10,10 @@
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"OCP\\": "vendor/nextcloud/ocp/OCP/"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"stubs/OC_Image.php"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "find . -name \\*.php -not -path './vendor/*' -not -path './vendor-bin/*' -not -path './build/*' -print0 | xargs -0 -n1 php -l",
|
||||
|
@ -4,6 +4,10 @@ declare(strict_types=1);
|
||||
|
||||
namespace OCA\OpdsCatalog\AppInfo;
|
||||
|
||||
use OCA\OpdsCatalog\Provider\AmazonPreviewProvider;
|
||||
use OCA\OpdsCatalog\Provider\ComicBookPreviewProvider;
|
||||
use OCA\OpdsCatalog\Provider\EpubPreviewProvider;
|
||||
use OCA\OpdsCatalog\Provider\FictionBookPreviewProvider;
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\AppFramework\Bootstrap\IBootContext;
|
||||
use OCP\AppFramework\Bootstrap\IBootstrap;
|
||||
@ -17,7 +21,12 @@ class Application extends App implements IBootstrap
|
||||
parent::__construct(self::APP_ID);
|
||||
}
|
||||
|
||||
public function register(IRegistrationContext $context): void {}
|
||||
public function register(IRegistrationContext $context): void {
|
||||
$context->registerPreviewProvider(AmazonPreviewProvider::class, '/application\/(vnd.amazon.(ebook|mobi8-ebook)|x-(mobi8|mobipocket)-ebook)/');
|
||||
$context->registerPreviewProvider(ComicBookPreviewProvider::class, '/application\/(vnd.comicbook[+-](rar|zip)|x-cb[7rtz])/');
|
||||
$context->registerPreviewProvider(EpubPreviewProvider::class, '/application\/epub\+zip/');
|
||||
$context->registerPreviewProvider(FictionBookPreviewProvider::class, '/application\/x-fictionbook.*/');
|
||||
}
|
||||
|
||||
public function boot(IBootContext $context): void {}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace OCA\OpdsCatalog\Controller;
|
||||
|
||||
use Kiwilan\Opds\Entries\OpdsEntryNavigation;
|
||||
use Kiwilan\Opds\Enums\OpdsVersionEnum;
|
||||
use Kiwilan\Opds\Opds;
|
||||
use Kiwilan\Opds\OpdsConfig;
|
||||
@ -17,6 +18,9 @@ use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\Http\NotFoundResponse;
|
||||
use OCP\AppFramework\Http\Response;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\Folder;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCP\IRequest;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
@ -25,6 +29,7 @@ class PageController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
IRequest $request,
|
||||
private readonly IRootFolder $rootFolder,
|
||||
private readonly IUser $user,
|
||||
private readonly IURLGenerator $urlGenerator
|
||||
) {
|
||||
@ -33,8 +38,29 @@ class PageController extends Controller
|
||||
|
||||
#[NoCSRFRequired]
|
||||
#[NoAdminRequired]
|
||||
#[FrontpageRoute(verb: 'GET', url: '/')]
|
||||
public function index(): Response {
|
||||
#[FrontpageRoute(verb: 'GET', url: '/{path}', requirements: ['path' => '.+'])]
|
||||
public function index(string $path): Response {
|
||||
$userFolder = $this->rootFolder->getUserFolder($this->user->getUID());
|
||||
$root = $userFolder->get($path);
|
||||
$feeds = [];
|
||||
|
||||
if ($root instanceof Folder) {
|
||||
foreach ($root->getDirectoryListing() as $node) {
|
||||
if ($node instanceof Folder) {
|
||||
$feeds[] = new OpdsEntryNavigation(
|
||||
(string) $node->getId(),
|
||||
$node->getName(),
|
||||
$userFolder->getRelativePath($node->getPath()) ?? $path.'/'.$node->getName(),
|
||||
properties: [
|
||||
'numberOfItems' => count($node->getDirectoryListing()),
|
||||
],
|
||||
updated: new \DateTime('@'.$node->getMTime())
|
||||
);
|
||||
} elseif ($node instanceof File) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$config = new OpdsConfig(
|
||||
name: $this->user->getDisplayName()."'s Library",
|
||||
author: $this->user->getDisplayName(),
|
||||
|
12
lib/Provider/AmazonPreviewProvider.php
Normal file
12
lib/Provider/AmazonPreviewProvider.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\OpdsCatalog\Provider;
|
||||
|
||||
class AmazonPreviewProvider extends EbookPreviewProvider
|
||||
{
|
||||
public function getMimeType(): string {
|
||||
return '/application\/(vnd.amazon.(ebook|mobi8-ebook)|x-(mobi8|mobipocket)-ebook)/';
|
||||
}
|
||||
}
|
12
lib/Provider/ComicBookPreviewProvider.php
Normal file
12
lib/Provider/ComicBookPreviewProvider.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\OpdsCatalog\Provider;
|
||||
|
||||
class ComicBookPreviewProvider extends EbookPreviewProvider
|
||||
{
|
||||
public function getMimeType(): string {
|
||||
return '/application\/(vnd.comicbook[+-](rar|zip)|x-cb[7rtz])/';
|
||||
}
|
||||
}
|
42
lib/Provider/EbookPreviewProvider.php
Normal file
42
lib/Provider/EbookPreviewProvider.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\OpdsCatalog\Provider;
|
||||
|
||||
use Kiwilan\Ebook\Ebook;
|
||||
use Kiwilan\Ebook\EbookCover;
|
||||
use OCP\Files\File;
|
||||
use OCP\Files\FileInfo;
|
||||
use OCP\IImage;
|
||||
use OCP\Image;
|
||||
use OCP\Preview\IProviderV2;
|
||||
|
||||
abstract class EbookPreviewProvider implements IProviderV2
|
||||
{
|
||||
public function isAvailable(FileInfo $file): bool {
|
||||
return Ebook::isValid($file->getPath());
|
||||
}
|
||||
|
||||
public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
|
||||
$ebook = Ebook::read($file->getPath());
|
||||
|
||||
if ($ebook instanceof Ebook) {
|
||||
$cover = $ebook->getCover();
|
||||
|
||||
if ($cover instanceof EbookCover) {
|
||||
$path = $cover->getPath();
|
||||
|
||||
if (null !== $path) {
|
||||
$image = new Image();
|
||||
$image->loadFromFile($path);
|
||||
$image->scaleDownToFit($maxX, $maxY);
|
||||
|
||||
return $image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
12
lib/Provider/EpubPreviewProvider.php
Normal file
12
lib/Provider/EpubPreviewProvider.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\OpdsCatalog\Provider;
|
||||
|
||||
class EpubPreviewProvider extends EbookPreviewProvider
|
||||
{
|
||||
public function getMimeType(): string {
|
||||
return '/application\/epub\+zip/';
|
||||
}
|
||||
}
|
12
lib/Provider/FictionBookPreviewProvider.php
Normal file
12
lib/Provider/FictionBookPreviewProvider.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OCA\OpdsCatalog\Provider;
|
||||
|
||||
class FictionBookPreviewProvider extends EbookPreviewProvider
|
||||
{
|
||||
public function getMimeType(): string {
|
||||
return '/application\/x-fictionbook.*/';
|
||||
}
|
||||
}
|
20
stubs/OC_Image.php
Normal file
20
stubs/OC_Image.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
use OCP\IImage;
|
||||
|
||||
interface OC_Image extends IImage
|
||||
{
|
||||
/**
|
||||
* Loads an image from a local file.
|
||||
*
|
||||
* @param bool|string $imagePath the path to a local file
|
||||
*
|
||||
* @return bool|GdImage An image resource or false on error
|
||||
*/
|
||||
public function loadFromFile($imagePath = false);
|
||||
|
||||
/**
|
||||
* Shrinks larger images to fit within specified boundaries while preserving ratio.
|
||||
*/
|
||||
public function scaleDownToFit(int $maxWidth, int $maxHeight): bool;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user