1
0
Files
Bridges/PixivUserIllustsBridge.php
2025-11-21 19:44:38 +01:00

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;
}
}
}
}