rss-bridge/bridges/NineGagBridge.php

372 lines
11 KiB
PHP
Raw Normal View History

<?php
class NineGagBridge extends BridgeAbstract
{
const NAME = '9gag Bridge';
const URI = 'https://9gag.com/';
const DESCRIPTION = 'Returns latest quotes from 9gag.';
const MAINTAINER = 'ZeNairolf';
const CACHE_TIMEOUT = 3600;
const PARAMETERS = [
'Popular' => [
'd' => [
'name' => 'Section',
'type' => 'list',
'values' => [
'Hot' => 'hot',
'Trending' => 'trending',
'Fresh' => 'fresh',
],
],
'video' => [
'name' => 'Filter Video',
'type' => 'list',
'values' => [
'NotFiltred' => 'none',
'VideoFiltred' => 'without',
'VideoOnly' => 'only',
],
],
'p' => [
'name' => 'Pages',
'type' => 'number',
'defaultValue' => 3,
],
],
'Sections' => [
'g' => [
'name' => 'Section',
'type' => 'list',
'values' => [
'Among Us' => 'among-us',
'Animals' => 'animals',
'Anime & Manga' => 'anime-manga',
'Anime Waifu' => 'animewaifu',
'Anime Wallpaper' => 'animewallpaper',
'Apex Legends' => 'apexlegends',
'Ask 9GAG' => 'ask9gag',
'Awesome' => 'awesome',
'Car' => 'car',
'Comic & Webtoon' => 'comic-webtoon',
'Coronavirus ' => 'coronavirus',
'Cosplay' => 'cosplay',
'Countryballs' => 'countryballs',
'Cozy & Comfy' => 'home-living',
'Crappy Design' => 'crappydesign',
'Cryptocurrency ' => 'cryptocurrency',
'Cyberpunk 2077' => 'cyberpunk2077',
'Dark Humor' => 'darkhumor',
'Drawing, DIY & Crafts' => 'drawing-diy-crafts',
'Fashion & Beauty' => 'rate-my-outfit',
'Food & Drinks' => 'food-drinks',
'Football' => 'football',
'Fortnite' => 'fortnite',
'Funny' => 'funny',
'Game of Thrones' => 'got',
'Gaming' => 'gaming',
'GIF' => 'gif',
'Girl' => 'girl',
'Girl Celebrity' => 'girlcelebrity',
'Guy' => 'guy',
'History' => 'history',
'Horror' => 'horror',
'K-Pop' => 'kpop',
'Latest News' => 'timely',
'League of Legends' => 'leagueoflegends',
'LEGO' => 'lego',
'Marvel & DC' => 'superhero',
'Meme' => 'meme',
'Movie & TV' => 'movie-tv',
'Music' => 'music',
'NBA' => 'basketball',
'Overwatch' => 'overwatch',
'PC Master Race' => 'pcmr',
'Pokémon' => 'pokemon',
'Politics ' => 'politics',
'PUBG' => 'pubg',
'Random ' => 'random',
'Relationship' => 'relationship',
'Satisfying' => 'satisfying',
'Savage' => 'savage',
'Science & Tech' => 'science-tech',
'Sport ' => 'sport',
'Star Wars' => 'starwars',
'Teens Can Relate' => 'school',
'Travel & Photography' => 'travel-photography',
'Video' => 'video',
'Wallpaper' => 'wallpaper',
'Warhammer' => 'warhammer',
'Wholesome' => 'wholesome',
'WTF' => 'wtf',
],
],
't' => [
'name' => 'Type',
'type' => 'list',
'values' => [
'Hot' => 'hot',
'Fresh' => 'fresh',
],
],
'video' => [
'name' => 'Filter Video',
'type' => 'list',
'values' => [
'NotFiltred' => 'none',
'VideoFiltred' => 'without',
'VideoOnly' => 'only',
],
],
'p' => [
'name' => 'Pages',
'type' => 'number',
'defaultValue' => 3,
],
],
];
const MIN_NBR_PAGE = 1;
const MAX_NBR_PAGE = 6;
protected $p = null;
public function collectData()
{
$url = sprintf(
'%sv1/group-posts/group/%s/type/%s?',
self::URI,
$this->getGroup(),
$this->getType()
);
$cursor = 'c=10';
$posts = [];
for ($i = 0; $i < $this->getPages(); ++$i) {
$content = getContents($url . $cursor);
$json = json_decode($content, true);
$posts = array_merge($posts, $json['data']['posts']);
$cursor = $json['data']['nextCursor'];
}
foreach ($posts as $post) {
$AvoidElement = false;
switch ($this->getInput('video')) {
case 'without':
if ($post['type'] === 'Animated') {
$AvoidElement = true;
}
break;
case 'only':
echo $post['type'];
if ($post['type'] !== 'Animated') {
$AvoidElement = true;
}
break;
case 'none':
default:
break;
}
if (!$AvoidElement) {
$item['uri'] = preg_replace('/^http:/i', 'https:', $post['url']);
$item['title'] = $post['title'];
$item['content'] = self::getContent($post);
$item['categories'] = self::getCategories($post);
$item['timestamp'] = self::getTimestamp($post);
$this->items[] = $item;
}
}
}
public function getName()
{
if ($this->getInput('d')) {
$name = sprintf('%s - %s', '9GAG', $this->getKey('d'));
} elseif ($this->getInput('g')) {
$name = sprintf('%s - %s', '9GAG', $this->getKey('g'));
if ($this->getInput('t')) {
$name = sprintf('%s [%s]', $name, $this->getKey('t'));
}
}
if (!empty($name)) {
return $name;
}
return self::NAME;
}
public function getURI()
{
$uri = $this->getInput('g');
if ($uri === 'default') {
$uri = $this->getInput('t');
}
return self::URI . $uri;
}
protected function getGroup()
{
if ($this->getInput('d')) {
return 'default';
}
return $this->getInput('g');
}
protected function getType()
{
if ($this->getInput('d')) {
return $this->getInput('d');
}
return $this->getInput('t');
}
protected function getPages()
{
if ($this->p === null) {
$value = (int) $this->getInput('p');
$value = ($value < self::MIN_NBR_PAGE) ? self::MIN_NBR_PAGE : $value;
$value = ($value > self::MAX_NBR_PAGE) ? self::MAX_NBR_PAGE : $value;
$this->p = $value;
}
return $this->p;
}
protected static function getContent($post)
{
if ($post['type'] === 'Animated') {
$content = self::getAnimated($post);
} elseif ($post['type'] === 'Article') {
$content = self::getArticle($post);
} else {
$content = self::getPhoto($post);
}
return $content;
}
protected static function getPhoto($post)
{
$image = $post['images']['image460'];
$photo = '<picture>';
$photo .= sprintf(
'<source srcset="%s" type="image/webp">',
$image['webpUrl']
);
$photo .= sprintf(
'<img src="%s" alt="%s" %s>',
$image['url'],
$post['title'],
'width="500"'
);
$photo .= '</picture>';
return $photo;
}
protected static function getAnimated($post)
{
$poster = $post['images']['image460']['url'];
$sources = $post['images'];
$video = sprintf(
'<video poster="%s" %s>',
$poster,
'preload="auto" loop controls style="min-height: 300px" width="500"'
);
$video .= sprintf(
'<source src="%s" type="video/webm">',
$sources['image460sv']['vp9Url']
);
$video .= sprintf(
'<source src="%s" type="video/mp4">',
$sources['image460sv']['h265Url']
);
$video .= sprintf(
'<source src="%s" type="video/mp4">',
$sources['image460svwm']['url']
);
$video .= '</video>';
return $video;
}
protected static function getArticle($post)
{
$blocks = $post['article']['blocks'];
$medias = $post['article']['medias'];
$contents = [];
foreach ($blocks as $block) {
if ('Media' === $block['type']) {
$mediaId = $block['mediaId'];
$contents[] = self::getContent($medias[$mediaId]);
} elseif ('RichText' === $block['type']) {
$contents[] = self::getRichText($block['content']);
}
}
$content = join('</div><div>', $contents);
$content = sprintf(
'<%1$s>%2$s</%1$s>',
'div',
$content
);
return $content;
}
protected static function getRichText($text = '')
{
$text = trim($text);
if (preg_match('/^>\s(?<text>.*)/', $text, $matches)) {
$text = sprintf(
'<%1$s>%2$s</%1$s>',
'blockquote',
$matches['text']
);
} else {
$text = sprintf(
'<%1$s>%2$s</%1$s>',
'p',
$text
);
}
return $text;
}
protected static function getCategories($post)
{
$params = self::PARAMETERS;
$sections = $params['Sections']['g']['values'];
if (isset($post['sections'])) {
$postSections = $post['sections'];
} elseif (isset($post['postSection'])) {
$postSections = [$post['postSection']];
} else {
$postSections = [];
}
foreach ($postSections as $key => $section) {
$postSections[$key] = array_search($section, $sections);
}
return $postSections;
}
protected static function getTimestamp($post)
{
$url = $post['images']['image460']['url'];
$headers = get_headers($url, true);
$date = $headers['Date'];
$time = strtotime($date);
return $time;
}
}