Merge Books class with BookInfo model and create services and resources

This commit is contained in:
DariusIII
2025-12-23 12:25:47 +01:00
parent acab740a5d
commit fb53c09671
8 changed files with 209 additions and 43 deletions
@@ -4,7 +4,7 @@ namespace App\Http\Controllers\Admin;
use App\Http\Controllers\BasePageController;
use App\Models\BookInfo;
use Blacklight\Books;
use App\Services\BookService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
@@ -32,7 +32,7 @@ class AdminBookController extends BasePageController
public function edit(Request $request): View|RedirectResponse
{
$this->setAdminPrefs();
$book = new Books;
$bookService = new BookService;
$meta_title = $title = 'Book Edit';
@@ -41,7 +41,7 @@ class AdminBookController extends BasePageController
if ($request->has('id')) {
$id = $request->input('id');
$b = $book->getBookInfo($id);
$b = $bookService->getBookInfo($id);
if (! $b) {
abort(404);
@@ -64,7 +64,7 @@ class AdminBookController extends BasePageController
? ($b['publishdate'] ?? null)
: Carbon::parse($request->input('publishdate'))->timestamp;
$book->update(
$bookService->update(
$id,
$request->input('title'),
$request->input('asin'),
@@ -78,7 +78,7 @@ class AdminBookController extends BasePageController
return redirect()->route('admin.book-list')->with('success', 'Book updated successfully');
case 'view':
default:
return view('admin.books.edit', compact('book', 'title', 'meta_title'))->with('book', $b);
return view('admin.books.edit', compact('title', 'meta_title'))->with('book', $b);
}
}
+4 -4
View File
@@ -3,7 +3,7 @@
namespace App\Http\Controllers;
use App\Models\Category;
use Blacklight\Books;
use App\Services\BookService;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
@@ -14,7 +14,7 @@ class BooksController extends BasePageController
*/
public function index(Request $request, string $id = '')
{
$book = new Books(['Settings' => $this->settings]);
$bookService = new BookService;
$boocats = Category::getChildren(Category::BOOKS_ROOT);
@@ -38,13 +38,13 @@ class BooksController extends BasePageController
$catarray = [];
$catarray[] = $category;
$ordering = $book->getBookOrdering();
$ordering = $bookService->getBookOrdering();
$orderby = $request->has('ob') && \in_array($request->input('ob'), $ordering, false) ? $request->input('ob') : '';
$books = [];
$page = $request->has('page') && is_numeric($request->input('page')) ? $request->input('page') : 1;
$offset = ($page - 1) * config('nntmux.items_per_cover_page');
$rslt = $book->getBookRange($page, $catarray, $offset, config('nntmux.items_per_cover_page'), $orderby, $this->userdata->categoryexclusions);
$rslt = $bookService->getBookRange($page, $catarray, $offset, config('nntmux.items_per_cover_page'), $orderby, $this->userdata->categoryexclusions);
$results = $this->paginate($rslt ?? [], $rslt[0]->_totalcount ?? 0, config('nntmux.items_per_cover_page'), $page, $request->url(), $request->query());
$maxwords = 50;
foreach ($results as $result) {
+2 -2
View File
@@ -14,8 +14,8 @@ use App\Models\UserDownload;
use App\Models\Video;
use App\Services\MovieService;
use App\Services\Releases\ReleaseSearchService;
use App\Services\BookService;
use Blacklight\AniDB;
use Blacklight\Books;
use Blacklight\Console;
use Blacklight\Games;
use Blacklight\Music;
@@ -119,7 +119,7 @@ class DetailsController extends BasePageController
$book = '';
if ($data['bookinfo_id'] !== '') {
$book = (new Books)->getBookInfo($data['bookinfo_id']);
$book = (new BookService)->getBookInfo($data['bookinfo_id']);
}
$con = '';
+32
View File
@@ -0,0 +1,32 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
/**
* Book Collection API Resource for transforming book collections.
*/
class BookCollection extends ResourceCollection
{
/**
* The resource that this resource collects.
*
* @var string
*/
public $collects = BookResource::class;
/**
* Transform the resource collection into an array.
*
* @return array<int|string, mixed>
*/
public function toArray(Request $request): array
{
return [
'data' => $this->collection,
];
}
}
+58
View File
@@ -0,0 +1,58 @@
<?php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
/**
* Book API Resource for transforming book data.
*/
class BookResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'author' => $this->author,
'asin' => $this->asin,
'isbn' => $this->isbn,
'ean' => $this->ean,
'url' => $this->url,
'salesrank' => $this->salesrank,
'publisher' => $this->publisher,
'publishdate' => $this->publishdate,
'pages' => $this->pages,
'overview' => $this->overview,
'genre' => $this->genre,
'cover' => $this->cover ? true : false,
'cover_url' => $this->getCoverUrl(),
'created_at' => $this->created_at?->toIso8601String(),
'updated_at' => $this->updated_at?->toIso8601String(),
];
}
/**
* Get the cover image URL.
*/
protected function getCoverUrl(): ?string
{
if (! $this->cover) {
return null;
}
$coverPath = storage_path('covers/book/'.$this->id.'.jpg');
if (file_exists($coverPath)) {
return url('/covers/book/'.$this->id.'.jpg');
}
return null;
}
}
+37
View File
@@ -3,6 +3,7 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Laravel\Scout\Searchable;
/**
@@ -79,4 +80,40 @@ class BookInfo extends Model
'title' => $this->title,
];
}
/**
* Get the releases associated with this book.
*/
public function releases(): HasMany
{
return $this->hasMany(Release::class, 'bookinfo_id');
}
/**
* Get the cover image path.
*/
public function getCoverPath(): string
{
return storage_path('covers/book/'.$this->id.'.jpg');
}
/**
* Check if cover image exists.
*/
public function hasCoverImage(): bool
{
return file_exists($this->getCoverPath());
}
/**
* Get the cover URL.
*/
public function getCoverUrl(): ?string
{
if (! $this->cover || ! $this->hasCoverImage()) {
return null;
}
return url('/covers/book/'.$this->id.'.jpg');
}
}
+70 -30
View File
@@ -1,48 +1,37 @@
<?php
namespace Blacklight;
namespace App\Services;
use App\Models\BookInfo;
use App\Models\Category;
use App\Models\Release;
use App\Models\Settings;
use App\Services\ItunesService;
use Blacklight\ColorCLI;
use Blacklight\ReleaseImage;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
/**
* Class Books.
* Service class for book data fetching and processing.
*/
class Books
class BookService
{
public bool $echooutput;
/**
* @var null|string
*/
public mixed $pubkey;
public ?string $pubkey;
/**
* @var null|string
*/
public mixed $privkey;
public ?string $privkey;
/**
* @var null|string
*/
public mixed $asstag;
public ?string $asstag;
public string|int|null $bookqty;
public int $bookqty;
public string|int|null $sleeptime;
public int $sleeptime;
public string $imgSavePath;
/**
* @var null|string
*/
public mixed $bookreqids;
public ?string $bookreqids;
public string $renamed;
@@ -51,14 +40,11 @@ class Books
protected ColorCLI $colorCli;
/**
* @param array $options Class instances / Echo to cli.
*
* @throws \Exception
*/
public function __construct()
{
$this->echooutput = config('nntmux.echocli');
$this->colorCli = new ColorCLI;
$this->pubkey = Settings::settingValue('amazonpubkey');
@@ -75,16 +61,22 @@ class Books
}
/**
* @return Model|null|static
* Get book info by ID.
*/
public function getBookInfo($id)
public function getBookInfo(?int $id): ?Model
{
if ($id === null) {
return null;
}
return BookInfo::query()->where('id', $id)->first();
}
/**
* Get book info by name using full-text search.
*/
public function getBookInfoByName(string $title): ?Model
{
// only used to get a count of words
$searchWords = '';
$title = preg_replace(['/( - | -|\(.+\)|\(|\))/', '/[^\w ]+/'], [' ', ''], $title);
$title = trim(trim(preg_replace('/\s\s+/i', ' ', $title)));
@@ -100,7 +92,10 @@ class Books
return BookInfo::search($searchWords)->first();
}
public function getBookRange($page, $cat, $start, $num, $orderBy, array $excludedCats = []): array
/**
* Get book range with pagination.
*/
public function getBookRange(int $page, array $cat, int $start, int $num, string $orderBy, array $excludedCats = []): array
{
$page = max(1, $page);
$start = max(0, $start);
@@ -188,7 +183,10 @@ class Books
return $return;
}
public function getBookOrder($orderBy): array
/**
* Get book order array.
*/
public function getBookOrder(string $orderBy): array
{
$order = $orderBy === '' ? 'r.postdate' : $orderBy;
$orderArr = explode('_', $order);
@@ -206,6 +204,9 @@ class Books
return [$orderfield, $ordersort];
}
/**
* Get book ordering options.
*/
public function getBookOrdering(): array
{
return [
@@ -226,11 +227,17 @@ class Books
];
}
/**
* Get browse by options.
*/
public function getBrowseByOptions(): array
{
return ['author' => 'author', 'title' => 'title'];
}
/**
* Get browse by SQL clause.
*/
public function getBrowseBy(): string
{
$browseby = ' ';
@@ -244,6 +251,30 @@ class Books
return $browseby;
}
/**
* Update book by ID.
*/
public function update(
int $id,
string $title,
?string $asin,
?string $url,
?string $author,
?string $publisher,
$publishdate,
int $cover
): bool {
return BookInfo::query()->where('id', $id)->update([
'title' => $title,
'asin' => $asin,
'url' => $url,
'author' => $author,
'publisher' => $publisher,
'publishdate' => $publishdate,
'cover' => $cover,
]) > 0;
}
/**
* Process book releases, 1 category at a time.
*
@@ -283,6 +314,8 @@ class Books
}
/**
* Process book releases helper.
*
* @throws \Exception
*/
protected function processBookReleasesHelper($res, $categoryID): void
@@ -349,6 +382,8 @@ class Books
}
/**
* Parse release title.
*
* @return bool|string
*/
public function parseTitle($release_name, $releaseID, $releasetype)
@@ -401,6 +436,8 @@ class Books
}
/**
* Update book info from external sources.
*
* @return false|int|string
*
* @throws \Exception
@@ -493,6 +530,8 @@ class Books
}
/**
* Fetch book properties from iTunes.
*
* @return array|bool
*/
public function fetchItunesBookProperties(string $bookInfo)
@@ -533,3 +572,4 @@ class Books
return $book;
}
}
+1 -2
View File
@@ -3,7 +3,6 @@
namespace App\Services;
use App\Models\Settings;
use Blacklight\Books;
class BooksProcessor
{
@@ -17,7 +16,7 @@ class BooksProcessor
public function process(string $groupID = '', string $guidChar = ''): void
{
if ((int) Settings::settingValue('lookupbooks') !== 0) {
(new Books)->processBookReleases($groupID, $guidChar);
(new BookService)->processBookReleases($groupID, $guidChar);
}
}
}