Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create CruncyrollBridge.php #4404

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions bridges/CruncyrollBridge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

/**
* CrunchyrollBridge fetches news articles from the Crunchyroll API.
*/
class CrunchyrollBridge extends BridgeAbstract
{
const NAME = 'Crunchyroll News Bridge';
const URI = 'https://www.crunchyroll.com/news';
const DESCRIPTION = 'Returns latest news from Crunchyroll';
const MAINTAINER = 'peppy6582';
const PARAMETERS = [
[
'category' => [
'name' => 'Category',
'type' => 'text',
'required' => true,
'exampleValue' => 'Announcements,News,News',
],
'page_size' => [
'name' => 'Page Size',
'type' => 'number',
'required' => false,
'defaultValue' => 16,
],
'page' => [
'name' => 'Page',
'type' => 'number',
'required' => false,
'defaultValue' => 1,
],
],
];

/**
* Collects data from the Crunchyroll API and populates items.
*
* @throws Exception If the API call or JSON decoding fails.
*/
public function collectData()
{
// Define API base URL
$apiBaseUrl = 'https://cr-news-api-service.prd.crunchyrollsvc.com/v1/en-US/stories/search';

// Retrieve input parameters
$category = $this->getInput('category');
$pageSize = $this->getInput('page_size');
$page = $this->getInput('page');

// Construct the API URL with query parameters
$apiUrl = sprintf(
'%s?category=%s&page_size=%d&page=%d',
$apiBaseUrl,
urlencode($category),
$pageSize,
$page
);

// Define HTTP headers for the API request
$options = [
'http' => [
'method' => 'GET',
'header' => [
'User-Agent: Mozilla/5.0 (compatible; RSSBridge/2025)',
'Accept: application/json',
'Accept-Language: en-US,en;q=0.5',
'Origin: https://www.crunchyroll.com',
'Referer: https://www.crunchyroll.com/',
],
],
];

// Use getContents for better error handling and compliance
$response = getContents($apiUrl, [], $options);

if ($response === false) {
throw new Exception('Failed to fetch data from the Crunchyroll API.');
}

// Parse the JSON response
$data = json_decode($response, true);

if (json_last_error() !== JSON_ERROR_NONE) {
throw new Exception('Failed to decode JSON response: ' . json_last_error_msg());
}

// Map UUIDs to author names from the `rels` array
$authorMap = [];
foreach ($data['rels'] as $rel) {
if (isset($rel['uuid'], $rel['content']['name'])) {
$authorMap[$rel['uuid']] = $rel['content']['name'];
}
}

// Process each story in the response
foreach ($data['stories'] as $story) {
$item = [];

// Find the author name(s) for the story
$authorNames = [];
if (!empty($story['content']['authors'])) {
foreach ($story['content']['authors'] as $authorUuid) {
if (isset($authorMap[$authorUuid])) {
$authorNames[] = $authorMap[$authorUuid];
}
}
}

// Set the `author` field to the resolved names or default to 'Unknown'
$item['author'] = implode(', ', $authorNames) ?: 'Unknown';

// Set the item properties
$item['uri'] = self::URI . '/' . $story['slug'];
$item['title'] = $story['content']['headline'];
$item['timestamp'] = strtotime($story['content']['article_date']);
$item['content'] = sprintf(
'<img src="%s" alt="%s"><br>%s',
$story['content']['thumbnail']['filename'],
htmlspecialchars($story['content']['thumbnail']['alt']),
htmlspecialchars($story['content']['lead'])
);
$item['categories'] = $story['tag_list'] ?? [];
$item['uid'] = $story['uuid'];

// Add the item to the feed
$this->items[] = $item;
}
}
}
101 changes: 101 additions & 0 deletions bridges/HidiveBridge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php
class HidiveBridge extends BridgeAbstract {
const NAME = 'HIDIVE News Bridge';
const URI = 'https://news.hidive.com/';
const DESCRIPTION = 'Fetches the latest news from HIDIVE.';
const MAINTAINER = 'Your Name';
const CACHE_TIMEOUT = 3600; // 1 hour cache

public function collectData() {
$apiUrl = 'https://apigw.hidive.com/news/news';

// Define POST payload
$postData = json_encode([
'take' => 9,
'skip' => 0,
'filter' => new stdClass()
]);

// Define headers
$headers = [
'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:133.0) Gecko/20100101 Firefox/133.0',
'Accept: */*',
'Accept-Language: en-US,en;q=0.5',
'Content-Type: application/json',
'Origin: https://news.hidive.com',
'Referer: https://news.hidive.com/'
];

// Prepare the HTTP options for getContents
$options = [
'http' => [
'method' => 'POST',
'header' => implode("\r\n", $headers),
'content' => $postData,
'ignore_errors' => true
]
];

// Use getContents for the HTTP request
$response = getContents($apiUrl, $options);

if ($response === false) {
returnServerError('Unable to fetch data from HIDIVE API.');
}

// Decode the JSON response
$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
returnServerError('Failed to decode JSON: ' . json_last_error_msg());
}

// Process each news item
foreach ($data as $item) {
$newsItem = [];

// Clean and format the data
$excerpt = isset($item['excerpt']) ? ltrim($item['excerpt']) : '';
$seoUrl = isset($item['seoUrl']) ? 'https://news.hidive.com' . $item['seoUrl'] : '';
$image = isset($item['image']) ? 'https:' . $item['image'] : '';

// Create feed item
$newsItem['uri'] = $seoUrl;
$newsItem['title'] = $item['title'] ?? '';
$newsItem['timestamp'] = strtotime($item['releaseDate'] ?? '');

// Construct content with image and excerpt
$content = '';
if ($image) {
$content .= '<img src="' . htmlspecialchars($image) . '" alt="' .
htmlspecialchars($item['title'] ?? '') . '">';
}
$content .= '<p>' . htmlspecialchars($excerpt) . '</p>';

$newsItem['content'] = $content;

// Add categories if available
if (isset($item['categories']) && is_array($item['categories'])) {
$newsItem['categories'] = $item['categories'];
}

// Add author if available
if (isset($item['author'])) {
$newsItem['author'] = $item['author'];
}

$this->items[] = $newsItem;
}
}

public function getName() {
return self::NAME;
}

public function getURI() {
return self::URI;
}

public function getIcon() {
return 'https://www.hidive.com/favicon.ico';
}
}
Loading