mirror of
https://github.com/jikan-me/jikan-rest.git
synced 2025-02-20 11:23:35 +08:00
various fixes and refactorings
- genre filtering - added unapproved filtering - fixed sfw filtering - fixed kids filtering - fixed deprecation warnings as of php 8.1 - DateTime ctor can't take `null` anymore as first param - preg_replace doesn't accept `null` values as `$subject` - fixed failed items indexer (the --failed option of indexers) -- it didn't load the correct file making it impossible to retry the indexing - changed the document schema for search indexed anime/manga - added `approved` field to them - staging will require a reimport into TypeSense - the central filtering system will now process `sfw` and `unapproved` filters, so they will be applied implicitly through the `filter` model scope method.
This commit is contained in:
parent
61af2e0420
commit
6eff2af172
17
.env.dist
17
.env.dist
@ -99,7 +99,6 @@ QUEUE_DELAY_PER_JOB=5
|
||||
# Scout config
|
||||
###
|
||||
# For TypeSense use: typesense
|
||||
# For ElasticSearch use: Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine
|
||||
#SCOUT_DRIVER=typesense
|
||||
#SCOUT_QUEUE=false
|
||||
|
||||
@ -112,22 +111,6 @@ QUEUE_DELAY_PER_JOB=5
|
||||
#TYPESENSE_SEARCH_EXHAUSTIVE=true
|
||||
#TYPESENSE_SEARCH_CUTTOFF_MS=450
|
||||
|
||||
###
|
||||
# ElasticSearch Config
|
||||
###
|
||||
# Host -- required
|
||||
# ELASTICSEARCH_HOST=host:port
|
||||
# you can use commas as sperator for additional nodes:
|
||||
# ELASTICSEARCH_HOST=host:port,host:port
|
||||
# username (optional)
|
||||
# ELASTICSEARCH_USER=user
|
||||
# password (optional)
|
||||
# ELASTICSEARCH_PASSWORD=password
|
||||
# api key (optional)
|
||||
# ELASTICSEARCH_API_KEY=apikey
|
||||
# cloud id (optional)
|
||||
# ELASTICSEARCH_CLOUD_ID=cloudid
|
||||
|
||||
###
|
||||
# GitHub generate report URL on fatal errors
|
||||
###
|
||||
|
@ -11,6 +11,7 @@ use Carbon\CarbonImmutable;
|
||||
use Database\Factories\AnimeFactory;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Jikan\Helper\Constants;
|
||||
use Jikan\Jikan;
|
||||
use Jikan\Request\Anime\AnimeRequest;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@ -19,7 +20,10 @@ class Anime extends JikanApiSearchableModel
|
||||
{
|
||||
use HasFactory, MediaFilters, FilteredByLetter;
|
||||
|
||||
protected array $filters = ["order_by", "status", "type", "sort", "max_score", "min_score", "score", "rating", "start_date", "end_date", "producer", "producers", "letter", "genres", "genres_exclude"];
|
||||
protected array $filters = [
|
||||
"order_by", "status", "type", "sort", "max_score", "min_score", "score", "rating", "start_date", "end_date",
|
||||
"producer", "producers", "letter", "genres", "genres_exclude", "sfw", "unapproved", "kids"
|
||||
];
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
@ -191,6 +195,29 @@ class Anime extends JikanApiSearchableModel
|
||||
return $query;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
public function scopeExceptItemsWithAdultRating(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
return $query
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_HENTAI)
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_EROTICA)
|
||||
->where("rating", "!=", AnimeRatingEnum::rx()->label);
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
public function scopeExceptKidsItems(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
return $query
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_KIDS);
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
public function scopeOnlyKidsItems(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
return $query
|
||||
->where("demographics.mal_id", Constants::GENRE_ANIME_KIDS);
|
||||
}
|
||||
|
||||
public static function scrape(int $id)
|
||||
{
|
||||
$data = app('JikanParser')->getAnime(new AnimeRequest($id));
|
||||
@ -237,6 +264,7 @@ class Anime extends JikanApiSearchableModel
|
||||
'synopsis' => $this->synopsis,
|
||||
'season' => $this->season,
|
||||
'year' => $this->year,
|
||||
'approved' => $this->approved ?? false,
|
||||
'producers' => $this->getMalIdsOfField($this->producers),
|
||||
'studios' => $this->getMalIdsOfField($this->studios),
|
||||
'licensors' => $this->getMalIdsOfField($this->licensors),
|
||||
|
@ -45,10 +45,15 @@ trait MediaFilters
|
||||
|
||||
foreach ($genres as $genreItem) {
|
||||
$genre = (int) $genreItem;
|
||||
$query = $query->orWhere('genres.mal_id', $genre)
|
||||
// here we need a nested where clause
|
||||
// this logically looks like: (genre = x OR demographic = x OR theme = x)
|
||||
// so: (any other where clauses from before) AND (genre = x OR demographic = x OR theme = x)
|
||||
$query = $query->where(function ($q) use ($genre) {
|
||||
return $q->where('genres.mal_id', $genre)
|
||||
->orWhere('demographics.mal_id', $genre)
|
||||
->orWhere('themes.mal_id', $genre)
|
||||
->orWhere('explicit_genres.mal_id', $genre);
|
||||
});
|
||||
}
|
||||
|
||||
return $query;
|
||||
@ -72,4 +77,26 @@ trait MediaFilters
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function filterBySfw(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, bool $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
// call scopeExceptItemsWithAdultRating method via $query->exceptItemsWithAdultRating()
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
return $value ? $query->exceptItemsWithAdultRating() : $query;
|
||||
}
|
||||
|
||||
public function filterByUnapproved(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, ?bool $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
return !$value ? $query->where("approved", true) : $query;
|
||||
}
|
||||
|
||||
public function filterByKids(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query, ?bool $value): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
if (is_null($value)) {
|
||||
return $query;
|
||||
}
|
||||
// call scopeOnlyKidsItems method via $query->onlyKidsItems()
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
return $value ? $query->onlyKidsItems() : $query->exceptKidsItems();
|
||||
}
|
||||
}
|
||||
|
@ -37,12 +37,11 @@ class AnimeScheduleIndexer extends Command
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
echo "Note: AnimeScheduleIndexer makes sure anime currently airing are upto update so the schedules endpoint returns fresh information\n\n";
|
||||
echo "Note: AnimeScheduleIndexer makes sure anime currently airing are up to date so the schedules endpoint returns fresh information\n\n";
|
||||
|
||||
/**
|
||||
* Schedule
|
||||
@ -80,10 +79,6 @@ class AnimeScheduleIndexer extends Command
|
||||
sleep(3); // prevent rate-limit
|
||||
|
||||
echo "Updating {$i}/{$itemCount} \r";
|
||||
try {
|
||||
} catch (\Exception $e) {
|
||||
echo "[SKIPPED] Failed to fetch {$url}";
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
|
@ -25,8 +25,6 @@ use Spatie\LaravelData\Optional;
|
||||
*/
|
||||
final class AnimeSearchCommand extends MediaSearchCommand implements DataRequest
|
||||
{
|
||||
use HasSfwParameter;
|
||||
|
||||
#[WithCast(EnumCast::class, AnimeStatusEnum::class), EnumValidation(AnimeStatusEnum::class)]
|
||||
public AnimeStatusEnum|Optional $status;
|
||||
|
||||
|
@ -22,5 +22,5 @@ trait HasKidsParameter
|
||||
use PreparesData;
|
||||
|
||||
#[BooleanType, WithCast(ContextualBooleanCast::class)]
|
||||
public bool|Optional $kids = false;
|
||||
public bool|Optional $kids;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Dto;
|
||||
|
||||
use App\Dto\Concerns\HasSfwParameter;
|
||||
use App\Dto\Concerns\HasUnapprovedParameter;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Spatie\LaravelData\Attributes\MapInputName;
|
||||
@ -23,7 +24,7 @@ use Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer;
|
||||
|
||||
class MediaSearchCommand extends SearchCommand
|
||||
{
|
||||
use HasSfwParameter;
|
||||
use HasSfwParameter, HasUnapprovedParameter;
|
||||
|
||||
#[MapInputName("min_score"), MapOutputName("min_score"), Between(0.00, 10.00), Numeric]
|
||||
public float|Optional $minScore;
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
namespace App\Dto;
|
||||
|
||||
|
||||
use App\Casts\ContextualBooleanCast;
|
||||
use App\Casts\EnumCast;
|
||||
use App\Concerns\HasRequestFingerprint;
|
||||
use App\Contracts\DataRequest;
|
||||
@ -17,10 +15,8 @@ use App\Dto\Concerns\PreparesData;
|
||||
use App\Enums\AnimeScheduleFilterEnum;
|
||||
use App\Rules\Attributes\EnumValidation;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Spatie\LaravelData\Attributes\Validation\BooleanType;
|
||||
use Spatie\LaravelData\Attributes\WithCast;
|
||||
use Spatie\LaravelData\Data;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<JsonResponse>
|
||||
|
@ -6,9 +6,7 @@ use App\Contracts\DataRequest;
|
||||
use App\Dto\Concerns\HasSfwParameter;
|
||||
use App\Dto\Concerns\HasUnapprovedParameter;
|
||||
use App\Http\Resources\V4\MangaResource;
|
||||
use Spatie\LaravelData\Attributes\Validation\BooleanType;
|
||||
use Spatie\LaravelData\Data;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements DataRequest<MangaResource>
|
||||
|
@ -17,7 +17,8 @@ final class MediaReviewsSortEnum extends Enum
|
||||
return [
|
||||
"mostVoted" => Constants::REVIEWS_SORT_MOST_VOTED,
|
||||
"newest" => Constants::REVIEWS_SORT_NEWEST,
|
||||
"oldest" => Constants::REVIEWS_SORT_OLDEST
|
||||
"oldest" => Constants::REVIEWS_SORT_OLDEST,
|
||||
"suggested" => "suggested",
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,12 @@ final class QueryAnimeSchedulesHandler implements RequestHandler
|
||||
*/
|
||||
public function handle($request)
|
||||
{
|
||||
$limit = intval($request->limit ?? Env::get("MAX_RESULTS_PER_PAGE", 25));
|
||||
$results = $this->repository->getCurrentlyAiring($request->dayFilter, $request->kids, $request->sfw, $request->unapproved);
|
||||
$requestParams = collect($request->all());
|
||||
$limit = $requestParams->get("limit");
|
||||
$results = $this->repository->getCurrentlyAiring($request->dayFilter);
|
||||
// apply sfw, kids and unapproved filters
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$results = $results->filter($requestParams);
|
||||
$results = $results->paginate(
|
||||
$limit,
|
||||
["*"],
|
||||
|
@ -33,23 +33,9 @@ abstract class QueryAnimeSeasonHandlerBase implements RequestHandler
|
||||
$requestParams = collect($request->all());
|
||||
$type = $requestParams->has("filter") ? $request->filter : null;
|
||||
$results = $this->getSeasonItems($request, $type);
|
||||
|
||||
$includeUnapproved = $requestParams->get("unapproved", false);
|
||||
$includeKids = $requestParams->get("kids", false);
|
||||
$shouldBeSfw = $requestParams->get("sfw", false);
|
||||
|
||||
if (!$includeUnapproved) {
|
||||
$results = $this->repository->excludeUnapprovedItems($results);
|
||||
}
|
||||
|
||||
if (!$includeKids) {
|
||||
$results = $this->repository->excludeKidsItems($results);
|
||||
}
|
||||
|
||||
if ($shouldBeSfw) {
|
||||
$results = $this->repository->excludeNsfwItems($results);
|
||||
}
|
||||
|
||||
// apply sfw, kids and unapproved filters
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$results = $results->filter($requestParams);
|
||||
$results = $results->paginate($request->limit, ["*"], null, $request->page);
|
||||
|
||||
$animeCollection = new AnimeCollection($results);
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Contracts\AnimeRepository;
|
||||
use App\Contracts\RequestHandler;
|
||||
use App\Dto\QueryCurrentAnimeSeasonCommand;
|
||||
use App\Enums\AnimeSeasonEnum;
|
||||
@ -28,7 +27,7 @@ final class QueryCurrentAnimeSeasonHandler extends QueryAnimeSeasonHandlerBase
|
||||
*/
|
||||
private function getCurrentSeason() : array
|
||||
{
|
||||
$date = new \DateTime(null, new \DateTimeZone('Asia/Tokyo'));
|
||||
$date = new \DateTime('now', new \DateTimeZone('Asia/Tokyo'));
|
||||
|
||||
$year = (int) $date->format('Y');
|
||||
$month = (int) $date->format('n');
|
||||
|
@ -2,47 +2,28 @@
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Contracts\AnimeRepository;
|
||||
use App\Anime;
|
||||
use App\Contracts\RequestHandler;
|
||||
use App\Dto\QueryRandomAnimeCommand;
|
||||
use App\Http\Resources\V4\AnimeResource;
|
||||
use Illuminate\Support\Collection;
|
||||
use Spatie\LaravelData\Optional;
|
||||
|
||||
/**
|
||||
* @implements RequestHandler<QueryRandomAnimeCommand, AnimeResource>
|
||||
*/
|
||||
final class QueryRandomAnimeHandler implements RequestHandler
|
||||
{
|
||||
public function __construct(
|
||||
private readonly AnimeRepository $repository
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function handle($request): AnimeResource
|
||||
{
|
||||
$sfw = Optional::create() !== $request->sfw ? $request->sfw : null;
|
||||
$unapproved = Optional::create() !== $request->unapproved ? $request->unapproved : null;
|
||||
|
||||
/**
|
||||
* @var Collection $results;
|
||||
*/
|
||||
$results = $this->repository;
|
||||
|
||||
if (!$unapproved) {
|
||||
$results->excludeUnapprovedItems($results);
|
||||
}
|
||||
|
||||
if ($sfw) {
|
||||
$results->excludeNsfwItems($results);
|
||||
}
|
||||
$queryable = Anime::query();
|
||||
// apply sfw, kids and unapproved filters
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$queryable = $queryable->filter(collect($request->all()));
|
||||
|
||||
return new AnimeResource(
|
||||
$results->random()->first()
|
||||
$queryable->random()->first()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -2,47 +2,28 @@
|
||||
|
||||
namespace App\Features;
|
||||
|
||||
use App\Contracts\MangaRepository;
|
||||
use App\Contracts\RequestHandler;
|
||||
use App\Dto\QueryRandomMangaCommand;
|
||||
use App\Http\Resources\V4\MangaResource;
|
||||
use Illuminate\Support\Collection;
|
||||
use Spatie\LaravelData\Optional;
|
||||
use App\Manga;
|
||||
|
||||
/**
|
||||
* @implements RequestHandler<QueryRandomMangaCommand, MangaResource>
|
||||
*/
|
||||
final class QueryRandomMangaHandler implements RequestHandler
|
||||
{
|
||||
public function __construct(
|
||||
private readonly MangaRepository $repository
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function handle($request)
|
||||
{
|
||||
$sfw = Optional::create() !== $request->sfw ? $request->sfw : null;
|
||||
$unapproved = Optional::create() !== $request->unapproved ? $request->unapproved : null;
|
||||
|
||||
/**
|
||||
* @var Collection $results;
|
||||
*/
|
||||
$results = $this->repository;
|
||||
|
||||
if (!$unapproved) {
|
||||
$results->excludeUnapprovedItems($results);
|
||||
}
|
||||
|
||||
if ($sfw) {
|
||||
$results->excludeNsfwItems($results);
|
||||
}
|
||||
$queryable = Manga::query();
|
||||
// apply sfw, kids and unapproved filters
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$queryable = $queryable->filter(collect($request->all()));
|
||||
|
||||
return new MangaResource(
|
||||
$results->random()->first()
|
||||
$queryable->random()->first()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ trait FilterQueryString
|
||||
};
|
||||
|
||||
$result = collect(array_filter($queryParameters->all(), $filter, ARRAY_FILTER_USE_KEY))
|
||||
->filter(fn ($v, $k) => !empty($v)) ?? Collection::empty();
|
||||
->filter(fn ($v, $k) => $v !== "" && $v !== null && !(is_float($v) && is_nan($v))) ?? Collection::empty();
|
||||
|
||||
return $this->_normalizeOrderBy($result);
|
||||
}
|
||||
|
@ -83,6 +83,9 @@ abstract class JikanApiSearchableModel extends JikanApiModel implements Typesens
|
||||
|
||||
protected function simplifyStringForSearch($val): string
|
||||
{
|
||||
if (!$val) {
|
||||
return "";
|
||||
}
|
||||
return preg_replace("/[^[:alnum:][:space:]]/u", ' ', $val) ?? "";
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,12 @@ namespace App;
|
||||
|
||||
use App\Concerns\FilteredByLetter;
|
||||
use App\Concerns\MediaFilters;
|
||||
use App\Enums\MangaTypeEnum;
|
||||
use App\Http\HttpHelper;
|
||||
use Carbon\CarbonImmutable;
|
||||
use Database\Factories\MangaFactory;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Jikan\Helper\Constants;
|
||||
use Jikan\Jikan;
|
||||
use Jikan\Request\Manga\MangaRequest;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
@ -16,7 +18,10 @@ class Manga extends JikanApiSearchableModel
|
||||
{
|
||||
use HasFactory, MediaFilters, FilteredByLetter;
|
||||
|
||||
protected array $filters = ["order_by", "status", "type", "sort", "max_score", "min_score", "score", "start_date", "end_date", "magazine", "magazines", "letter", "genres", "genres_exclude"];
|
||||
protected array $filters = [
|
||||
"order_by", "status", "type", "sort", "max_score", "min_score", "score", "start_date", "end_date", "magazine",
|
||||
"magazines", "letter", "genres", "genres_exclude", "sfw", "unapproved", "kids"
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
@ -28,7 +33,7 @@ class Manga extends JikanApiSearchableModel
|
||||
'images', 'status', 'type', 'volumes', 'chapters', 'publishing', 'published', 'rank', 'score',
|
||||
'scored_by', 'popularity', 'members', 'favorites', 'synopsis', 'background', 'related',
|
||||
'genres', 'explicit_genres', 'themes', 'demographics', 'authors', 'serializations',
|
||||
'createdAt', 'modifiedAt'
|
||||
'createdAt', 'modifiedAt', 'approved'
|
||||
];
|
||||
|
||||
/**
|
||||
@ -102,6 +107,29 @@ class Manga extends JikanApiSearchableModel
|
||||
return $query;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
public function scopeExceptItemsWithAdultRating(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
return $query
|
||||
->where("type", "!=", MangaTypeEnum::doujin()->label)
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_HENTAI)
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_EROTICA);
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
public function scopeExceptKidsItems(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
return $query
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_KIDS);
|
||||
}
|
||||
|
||||
/** @noinspection PhpUnused */
|
||||
public function scopeOnlyKidsItems(\Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder $query): \Laravel\Scout\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
return $query
|
||||
->where("demographics.mal_id", Constants::GENRE_MANGA_KIDS);
|
||||
}
|
||||
|
||||
public static function scrape(int $id)
|
||||
{
|
||||
$data = app('JikanParser')->getManga(new MangaRequest($id));
|
||||
@ -145,7 +173,7 @@ class Manga extends JikanApiSearchableModel
|
||||
'members' => $this->members,
|
||||
'favorites' => $this->favorites,
|
||||
'synopsis' => $this->synopsis,
|
||||
'season' => $this->season,
|
||||
'approved' => $this->approved ?? false,
|
||||
'magazines' => $this->getMalIdsOfField($this->magazines),
|
||||
'genres' => $this->getMalIdsOfField($this->genres),
|
||||
'explicit_genres' => $this->getMalIdsOfField($this->explicit_genres)
|
||||
|
@ -96,6 +96,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
$scoutDriver = static::getSearchIndexDriver($this->app);
|
||||
$serviceClass = match ($scoutDriver) {
|
||||
"typesense" => TypeSenseScoutSearchService::class,
|
||||
// experimental
|
||||
"Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine" => ElasticScoutSearchService::class,
|
||||
default => DefaultScoutSearchService::class
|
||||
};
|
||||
@ -360,6 +361,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
$services[] = Typesense::class;
|
||||
}
|
||||
|
||||
// experimental
|
||||
if (Env::get("SCOUT_DRIVER") === "Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine") {
|
||||
$services[] = \Elastic\Elasticsearch\Client::class;
|
||||
}
|
||||
|
@ -45,8 +45,7 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe
|
||||
|
||||
public function exceptItemsWithAdultRating(): EloquentBuilder|ScoutBuilder
|
||||
{
|
||||
$builder = $this->queryable()
|
||||
->where("rating", "!=", AnimeRatingEnum::rx()->label);
|
||||
$builder = $this->queryable();
|
||||
|
||||
$this->excludeNsfwItems($builder);
|
||||
return $builder;
|
||||
@ -54,9 +53,7 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe
|
||||
|
||||
public function excludeNsfwItems($builder): EloquentBuilder|ScoutBuilder
|
||||
{
|
||||
return $builder
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_HENTAI)
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_EROTICA);
|
||||
return $builder->exceptItemsWithAdultRating();
|
||||
}
|
||||
|
||||
public function excludeUnapprovedItems($builder): Collection|EloquentBuilder|ScoutBuilder
|
||||
@ -67,8 +64,7 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe
|
||||
|
||||
public function excludeKidsItems($builder): EloquentBuilder|ScoutBuilder
|
||||
{
|
||||
return $builder
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_ANIME_KIDS);
|
||||
return $builder->exceptKidsItems();
|
||||
}
|
||||
|
||||
public function orderByPopularity(): EloquentBuilder|ScoutBuilder
|
||||
@ -121,9 +117,17 @@ final class DefaultAnimeRepository extends DatabaseRepository implements AnimeRe
|
||||
?AnimeTypeEnum $type = null
|
||||
): EloquentBuilder
|
||||
{
|
||||
$queryable = $this->queryable(true)->whereBetween("aired.from", [
|
||||
$from->toAtomString(),
|
||||
$to->modify("last day of this month")->toAtomString()
|
||||
// $queryable = $this->queryable(true)->whereBetween("aired.from", [
|
||||
// $from->toAtomString(),
|
||||
// $to->modify("last day of this month")->toAtomString()
|
||||
// ]);
|
||||
|
||||
/** @noinspection PhpParamsInspection */
|
||||
$queryable = $this->queryable(true)->whereRaw([
|
||||
"aired.from" => [
|
||||
'$gte' => $from->toAtomString(),
|
||||
'$lte' => $to->modify("last day of this month")->toAtomString()
|
||||
]
|
||||
]);
|
||||
|
||||
if (!is_null($type)) {
|
||||
|
@ -50,9 +50,7 @@ final class DefaultMangaRepository extends DatabaseRepository implements MangaRe
|
||||
|
||||
public function exceptItemsWithAdultRating(): EloquentBuilder|ScoutBuilder
|
||||
{
|
||||
return $this->queryable()
|
||||
->where("type", "!=", MangaTypeEnum::doujin()->label)
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_HENTAI)
|
||||
->where("demographics.mal_id", "!=", Constants::GENRE_MANGA_EROTICA);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
return $this->queryable()->exceptItemsWithAdultRating();
|
||||
}
|
||||
}
|
||||
|
@ -143,11 +143,12 @@ $app->instance('JikanParser', $jikan);
|
||||
$app->instance('SerializerV4', SerializerFactory::createV4());
|
||||
$app->register(Laravel\Scout\ScoutServiceProvider::class);
|
||||
|
||||
// we support TypeSense and ElasticSearch as search indexes.
|
||||
// we support TypeSense search index.
|
||||
if (env("SCOUT_DRIVER") === "typesense") {
|
||||
// in this case the TYPESENSE_HOST env var should be set too
|
||||
$app->register(\Typesense\LaravelTypesense\TypesenseServiceProvider::class);
|
||||
}
|
||||
// experimental support for ElasticSearch search index
|
||||
if (env("SCOUT_DRIVER") === "Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine") {
|
||||
// in this case the ELASTICSEARCH_HOST env var should be set too
|
||||
$app->register(\Matchish\ScoutElasticSearch\ElasticSearchServiceProvider::class);
|
||||
|
@ -21,7 +21,7 @@
|
||||
"fabpot/goutte": "^4.0",
|
||||
"flipbox/lumen-generator": "^9.0",
|
||||
"illuminate/redis": "^9.0",
|
||||
"jenssegers/mongodb": "^3.8",
|
||||
"jenssegers/mongodb": "^3.9",
|
||||
"jikan-me/jikan": "^4",
|
||||
"jms/serializer": "^3.0",
|
||||
"laravel/legacy-factories": "^1.1",
|
||||
|
14
composer.lock
generated
14
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "8aae72ff5c407ed2db0de3d15ef88c6d",
|
||||
"content-hash": "bd75cf3fe6348185584fa3cbde3754e7",
|
||||
"packages": [
|
||||
{
|
||||
"name": "amphp/amp",
|
||||
@ -4286,16 +4286,16 @@
|
||||
},
|
||||
{
|
||||
"name": "jenssegers/mongodb",
|
||||
"version": "v3.9.4",
|
||||
"version": "v3.9.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jenssegers/laravel-mongodb.git",
|
||||
"reference": "0b03010682e5041ea80177a3db2d6509da92a9a5"
|
||||
"reference": "6ce35ace85a5946f943d7f493f93aebb9a6d129d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jenssegers/laravel-mongodb/zipball/0b03010682e5041ea80177a3db2d6509da92a9a5",
|
||||
"reference": "0b03010682e5041ea80177a3db2d6509da92a9a5",
|
||||
"url": "https://api.github.com/repos/jenssegers/laravel-mongodb/zipball/6ce35ace85a5946f943d7f493f93aebb9a6d129d",
|
||||
"reference": "6ce35ace85a5946f943d7f493f93aebb9a6d129d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -4352,7 +4352,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/jenssegers/laravel-mongodb/issues",
|
||||
"source": "https://github.com/jenssegers/laravel-mongodb/tree/v3.9.4"
|
||||
"source": "https://github.com/jenssegers/laravel-mongodb/tree/v3.9.5"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -4364,7 +4364,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-02-10T13:18:35+00:00"
|
||||
"time": "2023-02-16T12:20:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jetbrains/phpstorm-stubs",
|
||||
|
@ -66,6 +66,7 @@ class AnimeFactory extends JikanMediaModelFactory
|
||||
"members" => $this->faker->randomDigitNotnull(),
|
||||
"favorites" => $this->faker->randomDigitNotnull(),
|
||||
"synopsis" => "test",
|
||||
"approved" => true,
|
||||
"background" => "test",
|
||||
"premiered" => $this->faker->randomElement(["Winter", "Spring", "Fall", "Summer"]),
|
||||
"broadcast" => [
|
||||
|
@ -57,6 +57,7 @@ class MangaFactory extends JikanMediaModelFactory
|
||||
"members" => $this->faker->randomDigitNotNull(),
|
||||
"favorites" => $this->faker->randomDigitNotNull(),
|
||||
"synopsis" => "test",
|
||||
"approved" => true,
|
||||
"background" => "test",
|
||||
"authors" => [
|
||||
[
|
||||
|
Loading…
x
Reference in New Issue
Block a user