148 lines
4.8 KiB
PHP
148 lines
4.8 KiB
PHP
<?php
|
|
|
|
class PixivUserIllustsBridge extends BridgeAbstract
|
|
{
|
|
const NAME = 'Pixiv User Illustrations';
|
|
const URI = 'https://www.pixiv.net';
|
|
const DESCRIPTION = 'Returns latest illustrations from a Pixiv user (only safe content, R-18 and sensitive works require login)';
|
|
const MAINTAINER = 'Akamaru';
|
|
const CACHE_TIMEOUT = 3600; // 1 hour
|
|
|
|
const PARAMETERS = [
|
|
[
|
|
'user_id' => [
|
|
'name' => 'User ID',
|
|
'type' => 'text',
|
|
'required' => true,
|
|
'exampleValue' => '55400004'
|
|
],
|
|
'limit' => [
|
|
'name' => 'Limit',
|
|
'type' => 'number',
|
|
'defaultValue' => 10,
|
|
'required' => false
|
|
]
|
|
]
|
|
];
|
|
|
|
private $userName = null;
|
|
|
|
public function getIcon()
|
|
{
|
|
return 'https://www.google.com/s2/favicons?domain=pixiv.net&sz=32';
|
|
}
|
|
|
|
public function getName()
|
|
{
|
|
if ($this->userName) {
|
|
return $this->userName . ' - Pixiv';
|
|
}
|
|
return self::NAME;
|
|
}
|
|
|
|
public function getURI()
|
|
{
|
|
$userId = $this->getInput('user_id');
|
|
if ($userId) {
|
|
return self::URI . '/users/' . $userId . '/illustrations';
|
|
}
|
|
return self::URI;
|
|
}
|
|
|
|
public function collectData()
|
|
{
|
|
$userId = $this->getInput('user_id');
|
|
$limit = $this->getInput('limit') ?: 10;
|
|
|
|
// Fetch user profile to get all illust IDs
|
|
$profileUrl = self::URI . '/ajax/user/' . $userId . '/profile/all';
|
|
$profileJson = getContents($profileUrl, [
|
|
'Referer: https://www.pixiv.net/'
|
|
]);
|
|
$profileData = json_decode($profileJson, true);
|
|
|
|
if (!isset($profileData['body']['illusts']) || !is_array($profileData['body']['illusts'])) {
|
|
returnServerError('Could not fetch user illustrations');
|
|
}
|
|
|
|
// Get illust IDs (they are the keys of the illusts object)
|
|
$illustIds = array_keys($profileData['body']['illusts']);
|
|
|
|
// Sort by ID descending (newest first - higher ID = newer)
|
|
usort($illustIds, function ($a, $b) {
|
|
return (int)$b - (int)$a;
|
|
});
|
|
|
|
// Limit the number of illustrations
|
|
$illustIds = array_slice($illustIds, 0, $limit);
|
|
|
|
// Fetch detailed information for each illustration
|
|
foreach ($illustIds as $illustId) {
|
|
$illustUrl = self::URI . '/ajax/illust/' . $illustId;
|
|
|
|
try {
|
|
$illustJson = getContents($illustUrl, [
|
|
'Referer: https://www.pixiv.net/'
|
|
]);
|
|
$illustData = json_decode($illustJson, true);
|
|
|
|
if (!$illustData || !isset($illustData['body'])) {
|
|
continue;
|
|
}
|
|
|
|
$illust = $illustData['body'];
|
|
$item = [];
|
|
|
|
// Store username for getName()
|
|
if (!$this->userName && isset($illust['userName'])) {
|
|
$this->userName = $illust['userName'];
|
|
}
|
|
|
|
// Title
|
|
$item['title'] = $illust['illustTitle'] ?? $illust['title'] ?? 'Untitled';
|
|
|
|
// Content (image via pixiv.re proxy + description)
|
|
$content = '';
|
|
if (isset($illust['urls']['regular'])) {
|
|
// Use pixiv.re proxy (replace i.pximg.net with i.pixiv.re)
|
|
$imageUrl = str_replace('i.pximg.net', 'i.pixiv.re', $illust['urls']['regular']);
|
|
$content .= '<p><img src="' . $imageUrl . '" /></p>';
|
|
}
|
|
if (!empty($illust['illustComment'])) {
|
|
$content .= '<p>' . $illust['illustComment'] . '</p>';
|
|
}
|
|
$item['content'] = $content;
|
|
|
|
// URI
|
|
$item['uri'] = self::URI . '/artworks/' . $illustId;
|
|
|
|
// Timestamp
|
|
if (isset($illust['createDate'])) {
|
|
$item['timestamp'] = strtotime($illust['createDate']);
|
|
} elseif (isset($illust['uploadDate'])) {
|
|
$item['timestamp'] = strtotime($illust['uploadDate']);
|
|
}
|
|
|
|
// Author
|
|
$item['author'] = $illust['userName'] ?? 'Unknown';
|
|
|
|
// Categories (tags)
|
|
if (isset($illust['tags']['tags']) && is_array($illust['tags']['tags'])) {
|
|
$item['categories'] = array_map(function ($tag) {
|
|
return $tag['tag'] ?? '';
|
|
}, $illust['tags']['tags']);
|
|
}
|
|
|
|
// UID
|
|
$item['uid'] = 'pixiv-' . $illustId;
|
|
|
|
$this->items[] = $item;
|
|
|
|
} catch (Exception $e) {
|
|
// Skip illustrations that fail to load
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|