[PixivBridge] Add User context (#2650)

This commit is contained in:
Yaman Qalieh 2022-05-07 20:46:57 -04:00 committed by GitHub
parent adeaede930
commit 410daee1d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 156 additions and 50 deletions

View File

@ -1,81 +1,187 @@
<?php <?php
class PixivBridge extends BridgeAbstract { class PixivBridge extends BridgeAbstract {
// Good resource on API return values (Ex: illustType):
// https://hackage.haskell.org/package/pixiv-0.1.0/docs/Web-Pixiv-Types.html
const MAINTAINER = 'Yaman Qalieh'; const MAINTAINER = 'Yaman Qalieh';
const NAME = 'Pixiv Bridge'; const NAME = 'Pixiv Bridge';
const URI = 'https://www.pixiv.net/'; const URI = 'https://www.pixiv.net/';
const DESCRIPTION = 'Returns the tag search from pixiv.net'; const DESCRIPTION = 'Returns the tag search from pixiv.net';
const CACHE_TIMEOUT = 21600; // 6h
const PARAMETERS = array( array( const PARAMETERS = array(
'mode' => array( 'global' => array(
'name' => 'Post Type', 'posts' => array(
'type' => 'list', 'name' => 'Post Limit',
'values' => array('Illustration' => 'illustrations/', 'type' => 'number',
'Manga' => 'manga/', 'defaultValue' => '10'
'Novel' => 'novels/') ),
'fullsize' => array(
'name' => 'Full-size Image',
'type' => 'checkbox'
),
'mode' => array(
'name' => 'Post Type',
'type' => 'list',
'values' => array('All Works' => 'all',
'Illustrations' => 'illustrations/',
'Manga' => 'manga/',
'Novels' => 'novels/')
),
), ),
'tag' => array( // Backwards compatibility: Original bridge only had tags
'name' => 'Query to search', '' => array(
'exampleValue' => 'オリジナル', 'tag' => array(
'required' => true 'name' => 'Query to search',
'exampleValue' => 'オリジナル',
'required' => true
)
), ),
'posts' => array( 'User' => array(
'name' => 'Post Limit', 'userid' => array(
'type' => 'number', 'name' => 'User ID from profile URL',
'defaultValue' => '10' 'exampleValue' => '11',
), 'required' => true
'fullsize' => array( )
'name' => 'Full-size Image',
'type' => 'checkbox'
) )
)); );
// maps from URLs to json keys by context
const JSON_KEY_MAP = array( const JSON_KEY_MAP = array(
'illustrations/' => 'illust', '' => array(
'manga/' => 'manga', 'illustrations/' => 'illust',
'novels/' => 'novel' 'manga/' => 'manga',
); 'novels/' => 'novel'
const WORK_LINK_MAP = array( ),
'illustrations/' => 'artworks/', 'User' => array(
'manga/' => 'artworks/', 'illustrations/' => 'illusts',
'novels/' => 'novel/show.php?id=' 'manga/' => 'manga',
'novels/' => 'novels'
)
); );
// Hold the username for getName()
private $username = null;
public function getName() {
switch($this->queriedContext) {
// Tags context
case '':
$context = 'Tag';
$query = $this->getInput('tag');
break;
case 'User':
$context = 'User';
$query = $this->username ?? $this->getInput('userid');
break;
default:
return parent::getName();
}
$mode = array_search($this->getInput('mode'),
self::PARAMETERS['global']['mode']['values']);
return "Pixiv ${mode} from ${context} ${query}";
}
public function getURI() {
switch($this->queriedContext) {
// Tags context
case '':
$uri = static::URI . 'tags/' . urlencode($this->getInput('tag'));
break;
case 'User':
$uri = static::URI . 'users/' . $this->getInput('userid');
break;
default:
return parent::getURI();
}
if ($this->getInput('mode') != 'all') {
$uri = $uri . '/' . $this->getInput('mode');
}
return $uri;
}
private function getSearchURI($mode) {
switch($this->queriedContext) {
// Tags context
case '':
$query = urlencode($this->getInput('tag'));
$uri = static::URI . 'ajax/search/top/' . $query;
break;
case 'User':
$uri = static::URI . 'ajax/user/' . $this->getInput('userid')
. '/profile/top';
break;
default:
returnClientError('Invalid Context');
}
return $uri;
}
private function getDataFromJSON($json, $json_key) {
$json = $json['body'][$json_key];
// Tags context contains subkey
if ($this->queriedContext == '') {
$json = $json['data'];
}
return $json;
}
private function collectWorksArray() {
$content = getContents($this->getSearchURI($this->getInput('mode')));
$content = json_decode($content, true);
if ($this->getInput('mode') == 'all') {
$total = array();
foreach(self::JSON_KEY_MAP[$this->queriedContext] as $mode => $json_key) {
$current = $this->getDataFromJSON($content, $json_key);
$total = array_merge($total, $current);
}
$content = $total;
} else {
$json_key = self::JSON_KEY_MAP[$this->queriedContext][$this->getInput('mode')];
$content = $this->getDataFromJSON($content, $json_key);
}
return $content;
}
public function collectData() { public function collectData() {
$content = getContents($this->getSearchURI());
$content = json_decode($content, true);
$key = self::JSON_KEY_MAP[$this->getInput('mode')]; $content = $this->collectWorksArray();
$count = 0;
foreach($content['body'][$key]['data'] as $result) { $content = array_filter($content, function($v, $k) {
$count++; return !array_key_exists('isAdContainer', $v);
if ($count > $this->getInput('posts')) { }, ARRAY_FILTER_USE_BOTH);
break; // Sort by updateDate to get newest works
} usort($content, function($a, $b) {
return $b['updateDate'] <=> $a['updateDate'];
});
$content = array_slice($content, 0, $this->getInput('posts'));
foreach($content as $result) {
// Store username for getName()
if (!$this->username)
$this->username = $result['userName'];
$item = array(); $item = array();
$item['id'] = $result['id']; $item['uid'] = $result['id'];
$item['uri'] = static::URI . self::WORK_LINK_MAP[$this->getInput('mode')] . $result['id']; $subpath = array_key_exists('illustType', $result) ? 'artworks/' : 'novel/show.php?id=';
$item['uri'] = static::URI . $subpath . $result['id'];
$item['title'] = $result['title']; $item['title'] = $result['title'];
$item['author'] = $result['userName']; $item['author'] = $result['userName'];
$item['timestamp'] = $result['updateDate']; $item['timestamp'] = $result['updateDate'];
$item['content'] = "<img src='" . $this->cacheImage($result['url'], $item['id']) . "' />"; $item['tags'] = $result['tags'];
$item['content'] = "<img src='" . $this->cacheImage($result['url'], $result['id']) . "' />";
// Additional content items
if (array_key_exists('pageCount', $result)) {
$item['content'] .= '<br>Page Count: ' . $result['pageCount'];
} else {
$item['content'] .= '<br>Word Count: ' . $result['wordCount'];
}
$this->items[] = $item; $this->items[] = $item;
} }
} }
private function getSearchURI() {
$query = urlencode($this->getInput('tag'));
$uri = static::URI . 'ajax/search/' . $this->getInput('mode')
. $query . '?word=' . $query . '&order=date_d&mode=all&p=1';
return $uri;
}
private function cacheImage($url, $illustId) { private function cacheImage($url, $illustId) {
$illustId = preg_replace('/[^0-9]/', '', $illustId); $illustId = preg_replace('/[^0-9]/', '', $illustId);
$thumbnailurl = $url; $thumbnailurl = $url;