Skip to content

Commit

Permalink
add anime videos episodes
Browse files Browse the repository at this point in the history
  • Loading branch information
irfan-dahir committed Jul 7, 2022
1 parent 8b596f4 commit 1e6d7f5
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 3 deletions.
74 changes: 74 additions & 0 deletions src/Model/Anime/AnimeVideosEpisodes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Jikan\Model\Anime;

use Jikan\Model\Common\Collection\Pagination;
use Jikan\Model\Common\Collection\Results;
use Jikan\Parser;

/**
* Class AnimeVideosEpisodes
*
* @package Jikan\Model\Anime\AnimeVideosEpisodes
*/
class AnimeVideosEpisodes extends Results implements Pagination
{

/**
* @var bool
*/
private $hasNextPage = false;

/**
* @var int
*/
private $lastVisiblePage = 1;


/**
* @param Parser\Anime\VideosParser $parser
* @return static
*/
public static function fromParser(Parser\Anime\VideosParser $parser): self
{
$instance = new self();

$instance->results = $parser->getEpisodes();
$instance->hasNextPage = $parser->getHasNextPage();
$instance->lastVisiblePage = $parser->getLastPage();

return $instance;
}

/**
* @return static
*/
public static function mock() : self
{
return new self();
}

/**
* @return bool
*/
public function hasNextPage(): bool
{
return $this->hasNextPage;
}

/**
* @return int
*/
public function getLastVisiblePage(): int
{
return $this->lastVisiblePage;
}

/**
* @return array
*/
public function getResults(): array
{
return $this->results;
}
}
18 changes: 18 additions & 0 deletions src/MyAnimeList/MalClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,24 @@ public function getAnimeVideos(Request\Anime\AnimeVideosRequest $request): Model
}
}

/**
* @param Request\Anime\AnimeVideosEpisodesRequest $request
* @return Model\Anime\AnimeVideosEpisodes
* @throws BadResponseException
* @throws ParserException
*/
public function getAnimeVideosEpisodes(Request\Anime\AnimeVideosEpisodesRequest $request): Model\Anime\AnimeVideosEpisodes
{
$crawler = $this->ghoutte->request('GET', $request->getPath());
try {
$parser = new Parser\Anime\VideosParser($crawler);

return $parser->getResultsModel();
} catch (\Exception $e) {
throw ParserException::fromRequest($request, $e);
}
}

/**
* @param Request\Manga\MangaRequest $request
* @return Model\Manga\Manga
Expand Down
92 changes: 91 additions & 1 deletion src/Parser/Anime/VideosParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Jikan\Parser\Anime;

use Jikan\Model\Anime\AnimeVideos;
use Jikan\Model\Anime\AnimeVideosEpisodes;
use Jikan\Model\Anime\PromoListItem;
use Jikan\Parser\ParserInterface;
use Symfony\Component\DomCrawler\Crawler;
Expand All @@ -17,7 +18,7 @@ class VideosParser implements ParserInterface
/**
* @var Crawler
*/
private $crawler;
private Crawler $crawler;

/**
* EpisodesParser constructor.
Expand Down Expand Up @@ -72,6 +73,85 @@ function (Crawler $crawler) {
);
}

/**
* @return bool
*/
public function getHasNextPage(): bool
{
$node = $this->crawler
->filterXPath('//div[contains(@class, "video-block episode-video")]//div[contains(@class, "pagination")]/a[text()[contains(.,"More")]]');

if ($node->count()) {
return true;
}

return false;
}

/**
* @return int
*/
public function getLastPage(): int
{
$node = $this->crawler
->filterXPath('//div[contains(@class, "video-block episode-video")]//div[contains(@class, "pagination")]/a[text()[contains(.,"Last")]]');

// All pages except the last page returns "Last" button
if ($node->count()) {
parse_str(
parse_url($node->attr('href'), PHP_URL_QUERY),
$params
);

return (int) $params['p'];
}

// Fallback 1
// The second last page doesn't return "Last" and only returns "More" as an indicator
// for the next or last page
$node = $this->crawler
->filterXPath('//div[contains(@class, "video-block episode-video")]//div[contains(@class, "pagination")]/a[text()[contains(.,"More")]]');

if ($node->count()) {
parse_str(
parse_url($node->attr('href'), PHP_URL_QUERY),
$params
);

return (int) $params['p'];
}

// Fallback 2
// The last page only indicates the last page through a span element
$node = $this->crawler
->filterXPath('//div[contains(@class, "video-block episode-video")]//div[contains(@class, "pagination")]/*[position()=last()]');

// Fallback 3
// The user has exceeded the pagination
// MAL still generates pagination here for some reason
// So we'll check other properties to see whether the page has ended or not
// otherwise fallback 2 will keep returning the generated page
$hasReachedTheEnd = $this->crawler
->filterXPath('//div[contains(@class, "video-block episode-video")]//p[text()[contains(.,"No episode video has been added to this title")]]');

if ($hasReachedTheEnd->count()) {
// there is no way for us to know
// what the last accessible page is
// e.g https://myanimelist.net/anime/21/One_Piece/video?p=300
return 1;
}


if ($node->count()) {
// this element is not clickable and is returned as text

return (int) $node->text();
}

// if anything breaks
return 1;
}

/**
* Return the model
*
Expand All @@ -81,4 +161,14 @@ public function getModel(): AnimeVideos
{
return AnimeVideos::fromParser($this);
}

/**
* Return the results based model
*
* @throws \InvalidArgumentException
*/
public function getResultsModel(): AnimeVideosEpisodes
{
return AnimeVideosEpisodes::fromParser($this);
}
}
58 changes: 58 additions & 0 deletions src/Request/Anime/AnimeVideosEpisodesRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Jikan\Request\Anime;

use Jikan\Request\RequestInterface;

/**
* Class AnimeVideosEpisodesRequest
*
* @package Jikan\Request
*/
class AnimeVideosEpisodesRequest implements RequestInterface
{
/**
* @var int
*/
private int $id;

/**
* @var int
*/
private int $page;

/**
* AnimeVideosEpisodesRequest constructor.
*
* @param int $id
*/
public function __construct(int $id, int $page)
{
$this->id = $id;
$this->page = $page;
}

/**
* @return string
*/
public function getPath(): string
{
return sprintf('https://myanimelist.net/anime/%d/_/video?p=%d', $this->id, $this->page);
}

/**
* @return int
*/
public function getId(): int
{
return $this->id;
}

/**
* @return int
*/
public function getPage(): int
{
return $this->page;
}
}
4 changes: 2 additions & 2 deletions src/Request/Anime/AnimeVideosRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use Jikan\Request\RequestInterface;

/**
* Class AnimeVideos
* Class AnimeVideosRequest
*
* @package Jikan\Request
*/
Expand All @@ -14,7 +14,7 @@ class AnimeVideosRequest implements RequestInterface
/**
* @var int
*/
private $id;
private int $id;

/**
* AnimeVideosRequest constructor.
Expand Down

0 comments on commit 1e6d7f5

Please sign in to comment.