diff --git a/inc/api.php b/inc/api.php index 81358698..3c9a5f1c 100644 --- a/inc/api.php +++ b/inc/api.php @@ -18,6 +18,7 @@ include_once('classes/Captcha.php'); include_once('classes/MyAnimeList.php'); include_once('classes/BilibiliFavList.php'); +include_once('classes/bangumi.php'); use Sakura\API\Images; use Sakura\API\QQ; use Sakura\API\Cache; @@ -74,6 +75,18 @@ 'permission_callback' => '__return_true' ) ); + register_rest_route('sakura/v1', '/bangumi', array( + 'methods' => 'POST', + 'callback' => function ($request) { + $userID = $request->get_param('userID'); + $page = $request->get_param('page') ?: 1; + + $bgmList = new \Sakura\API\BangumiList(); + return $bgmList->get_bgm_items($userID, (int)$page); + }, + 'permission_callback' => '__return_true' + ) + ); register_rest_route('sakura/v1', '/movies/bilibili', array( 'methods' => 'POST', 'callback' => 'bfv_bilibili', diff --git a/inc/classes/bangumi.php b/inc/classes/bangumi.php new file mode 100644 index 00000000..0897c8f3 --- /dev/null +++ b/inc/classes/bangumi.php @@ -0,0 +1,134 @@ +userID = $userID; + $this->collectionApi = $this->apiUrl . '/v0/users/' . $this->userID . '/collections'; + } + + public function getCollections($isWatching = true, $isWatched = true) + { + $collDataArr = []; + + if ($isWatching) { + $collDataArr = array_merge($collDataArr, $this->fetchCollections(3)); + } + + if ($isWatched) { + $collDataArr = array_merge($collDataArr, $this->fetchCollections(2)); + } + + $collArr = []; + foreach ($collDataArr as $value) { + $collArr[] = [ + 'name' => $value['subject']['name'], + 'name_cn' => $value['subject']['name_cn'], + 'date' => $value['subject']['date'], + 'summary' => $value['subject']['short_summary'], + 'url' => 'https://bgm.tv/subject/' . $value['subject']['id'], + 'images' => $value['subject']['images']['large'] ?? '', + 'eps' => $value['subject']['eps'] ?? 0, + 'ep_status' => $value['ep_status'] ?? 0, + ]; + } + + return $collArr; + } + + private function fetchCollections($type) + { + $collOffset = 0; + $collDataArr = []; + + do { + $response = $this->http_get_contents($this->collectionApi . '?subject_type=2&type=' . $type . '&limit=50&offset=' . $collOffset); + $collData = json_decode($response, true); + + if (isset($collData['data'])) { + $collDataArr = array_merge($collDataArr, $collData['data']); + } + + $collOffset += 50; + } while (!empty($collData['data']) && $collOffset < ($collData['total'] ?? 0)); + + return $collDataArr; + } + + private function http_get_contents($url) + { + $response = wp_remote_get($url, ['user-agent' => 'mirai-mamori/Sakurairo(https://github.com/mirai-mamori/Sakurairo):WordPressTheme']); + if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) { + return wp_remote_retrieve_body($response); + } + + return json_encode(['error' => is_wp_error($response) ? $response->get_error_message() : 'An unknown error occurred.']); + } +} + +class BangumiList +{ + public function get_bgm_items($userID, $page = 1) + { + if (empty($userID)) { + return '

' . __('Bangumi ID not set.', 'sakurairo') . '

'; + } + + try { + $bgmAPI = new BangumiAPI($userID); + $collections = $bgmAPI->getCollections(true, true); + + if (empty($collections)) { + return '

' . __('No data', 'sakurairo') . '

'; + } + + $total = count($collections); // 总条目数 + $perPage = 12; // 每页条目数 + $totalPages = ceil($total / $perPage); // 总页数 + $offset = ($page - 1) * $perPage; + $collections = array_slice($collections, $offset, $perPage); // 当前页数据 + + $html = ''; + foreach ($collections as $item) { + $html .= '
'; + $html .= ''; + $html .= '' . esc_attr($item['name']) . ''; + $html .= ''; + $html .= '
'; + $html .= '

' . esc_html($item['name_cn'] ?: $item['name']) . '

'; + $html .= '
' . __('上映日期: ', 'sakurairo') . esc_html($item['date']) . '
'; + $html .= '
'; + $html .= '
'; + $html .= '

' . __('已观看集数: ', 'sakurairo') . esc_html($item['ep_status'] . '/' . $item['eps']) . '

'; + $html .= '
' . esc_html($item['summary'] ?: __('No introduction yet', 'sakurairo')) . '
'; + $html .= '
'; + } + + // 分页 + if ($page < $totalPages) { + $nextPageUrl = rest_url('sakura/v1/bangumi') . '?userID=' . urlencode($userID) . '&page=' . ($page + 1); + $html .= '
' . self::anchor_pagination_next($nextPageUrl) . '
'; + } + + return $html; + } catch (\Exception $e) { + return '

' . __('An error occured: ', 'sakurairo') . esc_html($e->getMessage()) . '

'; + } + } + + private static function anchor_pagination_next(string $href) + { + return ' ' . __('Load more...', 'sakurairo') . ''; + } +} \ No newline at end of file diff --git a/opt/options/theme-options.php b/opt/options/theme-options.php index 9b9a12e2..4a4f4e58 100644 --- a/opt/options/theme-options.php +++ b/opt/options/theme-options.php @@ -2770,6 +2770,7 @@ function iro_validate_optional_url( $value ) { 'options' => array( 'bilibili' => 'https://s.nmxc.ltd/sakurairo_vision/@2.7/options/bangumi_tep_bili.webp', 'myanimelist' => 'https://s.nmxc.ltd/sakurairo_vision/@2.7/options/bangumi_tep_mal.webp', + 'bangumi' => 'https://s.nmxc.ltd/sakurairo_vision/@2.7/options/bangumi_tep_bangumi.webp' ), 'default' => 'bilibili' ), @@ -2814,6 +2815,15 @@ function iro_validate_optional_url( $value ) { 'default' => 'LIVE_BUVID=' ), + array( + 'id' => 'bangumi_id', + 'type' => 'text', + 'title' => __('Bangumi Account UID','sakurairo_csf'), + 'desc' => __('Fill in your Bangumi account ID, e.g. https://bangumi.tv/user/944883, just the number part "944883"','sakurairo_csf'), + 'dependency' => array( 'bangumi_source', '==', 'bangumi', '', 'true' ), + 'default' => '944883' + ), + array( 'type' => 'subheading', 'content' => __('Friend Link Template Settings','sakurairo_csf'), diff --git a/user/page-bangumi.php b/user/page-bangumi.php index 8d1d758e..af079b90 100644 --- a/user/page-bangumi.php +++ b/user/page-bangumi.php @@ -1,7 +1,7 @@ @@ -12,42 +12,53 @@ - - - - -
> - -
- - -
- get_bgm_items(); - ?> - -
-

-
- - - -
- get_all_items(); - ?> -
- -
-

-
- - -
-
+ + + + + +
> + +
+ + +
+ get_bgm_items(); + } else { + echo '

' . __("Please fill in the Bilibili UID in Sakura Options.", "sakurairo") . '

'; + } + } elseif ($bangumi_source === 'bangumi') { + if (!empty($bangumi_id)) { + $bgmList = new \Sakura\API\BangumiList(); + echo $bgmList->get_bgm_items($bangumi_id); + } else { + echo '

' . __("Please fill in the Bangumi UID in Sakura Options.", "sakurairo") . '

'; + } + } elseif ($mal_username) { + $bgm = new \Sakura\API\MyAnimeList(); + echo $bgm->get_all_items(); + } else { + echo '

' . __("Please fill in the My Anime List Username in Sakura Options.", "sakurairo") . '

'; + } + ?> +
+
+