searchUrl = str_replace('{realDebridKey}', $this->realDebridKey, $this->baseUrl); $this->client = new Client([ 'base_uri' => $this->searchUrl, ]); } public function search(string $imdbCode, string $type, bool $parseResults = true): array { $cacheKey = "torrentio.{$imdbCode}"; $results = $this->cache->get($cacheKey, function (ItemInterface $item) use ($imdbCode, $type) { $item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0)); $item->tag(['torrentio', $type, $imdbCode]); try { $response = $this->client->get("$this->searchUrl/$imdbCode.json"); return json_decode( $response->getBody()->getContents(), true ); } catch (\Throwable $exception) { if ($exception->getCode() === 429) { $this->logger->warning("> [TorrentioClient] Rate limit exceeded"); return null; } } $this->logger->error("> [TorrentioClient] Request error: " . $response->getStatusCode() . " - " . $response->getBody()->getContents()); return []; }); if (true === $parseResults) { return $this->parse($results); } return $results; } public function fetchEpisodeResults(string $imdbId, int $season, int $episode, bool $parseResults = true): array { $cacheKey = "torrentio.$imdbId.$season.$episode"; $results = $this->cache->get($cacheKey, function (ItemInterface $item) use ($imdbId, $season, $episode) { $item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0)); $item->tag(['torrentio', 'tvshows', 'torrentio.tvshows', $imdbId, "torrentio.$imdbId", "$imdbId.$season", "torrentio.$imdbId.$season", "$imdbId.$season.$episode", "torrentio.$imdbId.$season.$episode"]); try { $response = $this->client->get("$this->searchUrl/$imdbId:$season:$episode.json"); return json_decode( $response->getBody()->getContents(), true ); } catch (\Throwable $exception) { if ($exception->getCode() === 429) { $this->logger->warning("> [TorrentioClient] Rate limit exceeded"); return null; } } $this->logger->error("> [TorrentioClient] Request error: " . $response->getStatusCode() . " - " . $response->getBody()->getContents()); return []; }); if (null === $results) { throw new TorrentioRateLimitException(); } if (true === $parseResults) { return $this->parse($results); } return $results; } public function parse(array $data): array { $results = []; foreach ($data['streams'] as $stream) { if (!str_starts_with($stream['url'], "https")) { continue; } if ( array_key_exists('behaviorHints', $stream) && array_key_exists('bingeGroup', $stream['behaviorHints']) ) { $bingeGroup = $stream['behaviorHints']['bingeGroup']; } else { $bingeGroup = '-'; } $result = ResultFactory::map( $stream['url'], $stream['title'], $bingeGroup ); $results[] = $result; } return $results; } }