diff --git a/footer.php b/footer.php index 4e2a435..3641f35 100644 --- a/footer.php +++ b/footer.php @@ -148,11 +148,11 @@
- +
diff --git a/inc/api.php b/inc/api.php index a216104..b2f50c2 100755 --- a/inc/api.php +++ b/inc/api.php @@ -1,5 +1,18 @@ 'POST', 'callback' => 'bgm_bilibili', )); + register_rest_route('sakura/v1', '/meting/aplayer', array( + 'methods' => 'GET', + 'callback' => 'meting_aplayer', + )); }); -/** - * QQ info - * https://sakura.2heng.xin/wp-json/sakura/v1/qqinfo/json - */ -function get_qq_info(WP_REST_Request $request) -{ - if (!check_ajax_referer('wp_rest', '_wpnonce', false)) { - $output = array( - 'status' => 403, - 'success' => false, - 'message' => 'Unauthorized client.' - ); - } elseif ($_GET['qq']) { - $qq = $_GET['qq']; - /** - * TODO: 设置host,国外服务器默认解析的不是国内IP,可能无法获取数据 - * 182.254.92.32 r.qzone.qq.com - * 参考:https://www.php.net/manual/zh/function.file-get-contents.php#108309 - */ - $get_info = file_get_contents('http://r.qzone.qq.com/fcg-bin/cgi_get_portrait.fcg?get_nick=1&uins=' . $qq); - $get_info = mb_convert_encoding($get_info, "UTF-8", "GBK"); - $name = json_decode(substr($get_info, 17, -1), true); - if ($name) { - $output = array( - 'status' => 200, - 'success' => true, - 'message' => 'success', - 'avatar' => 'https://q.qlogo.cn/headimg_dl?dst_uin=' . $qq . '&spec=100', - 'name' => $name[$qq][6], - ); - } else { - $output = array( - 'status' => 404, - 'success' => false, - 'message' => 'QQ number not exist.' - ); - } - } else { - $output = array( - 'status' => 400, - 'success' => false, - 'message' => 'Bad Request' - ); - } - - $result = new WP_REST_Response($output, $output['status']); - $result->set_headers(array('Content-Type' => 'application/json')); - return $result; -} - /** * Image uploader response */ -function upload_image(WP_REST_Request $request) -{ +function upload_image(WP_REST_Request $request) { // see: https://developer.wordpress.org/rest-api/requests/ // handle file params $file === $_FILES @@ -114,19 +80,19 @@ function upload_image(WP_REST_Request $request) $result->set_headers(array('Content-Type' => 'application/json')); return $result; } - + $images = new \Sakura\API\Images(); switch (akina_option("img_upload_api")) { case 'imgur': $image = file_get_contents($_FILES["cmt_img_file"]["tmp_name"]); - $API_Request = Imgur_API($image); + $API_Request = $images->Imgur_API($image); break; case 'smms': $image = $_FILES; - $API_Request = SMMS_API($image); + $API_Request = $images->SMMS_API($image); break; case 'chevereto': $image = file_get_contents($_FILES["cmt_img_file"]["tmp_name"]); - $API_Request = Chevereto_API($image); + $API_Request = $images->Chevereto_API($image); break; } @@ -135,244 +101,13 @@ function upload_image(WP_REST_Request $request) return $result; } -/** - * Chevereto upload interface - */ -function Chevereto_API($image) -{ - $upload_url = akina_option('cheverto_url') . '/api/1/upload'; - $args = array( - 'body' => array( - 'source' => base64_encode($image), - 'key' => akina_option('chevereto_api_key'), - ), - ); - - $response = wp_remote_post($upload_url, $args); - $reply = json_decode($response["body"]); - - if ($reply->status_txt == 'OK' && $reply->status_code == 200) { - $status = 200; - $success = true; - $message = "success"; - $link = $reply->image->image->url; - $proxy = akina_option('cmt_image_proxy') . $link; - } else { - $status = $reply->status_code; - $success = false; - $message = $reply->error->message; - $link = 'https://view.moezx.cc/images/2019/10/28/default_d_h_large.gif'; - $proxy = akina_option('cmt_image_proxy') . $link; - } - $output = array( - 'status' => $status, - 'success' => $success, - 'message' => $message, - 'link' => $link, - 'proxy' => $proxy, - ); - return $output; -} - -/** - * Imgur upload interface - */ -function Imgur_API($image) -{ - $client_id = akina_option('imgur_client_id'); - $upload_url = akina_option('imgur_upload_image_proxy'); - $args = array( - 'headers' => array( - 'Authorization' => 'Client-ID ' . $client_id, - ), - 'body' => array( - 'image' => base64_encode($image), - ), - ); - - $response = wp_remote_post($upload_url, $args); - $reply = json_decode($response["body"]); - - if ($reply->success && $reply->status == 200) { - $status = 200; - $success = true; - $message = "success"; - $link = $reply->data->link; - $proxy = akina_option('cmt_image_proxy') . $link; - } else { - $status = $reply->status; - $success = false; - $message = $reply->data->error; - $link = 'https://view.moezx.cc/images/2019/10/28/default_d_h_large.gif'; - $proxy = akina_option('cmt_image_proxy') . $link; - } - $output = array( - 'status' => $status, - 'success' => $success, - 'message' => $message, - 'link' => $link, - 'proxy' => $proxy, - ); - return $output; -} - -/** - * smms upload interface - */ -function SMMS_API($image) -{ - $client_id = akina_option('smms_client_id'); - $upload_url = "https://sm.ms/api/v2/upload"; - $filename = $image['cmt_img_file']['name']; - $filedata = $image['cmt_img_file']['tmp_name']; - $Boundary = wp_generate_password(); - $bits = file_get_contents($filedata); - - $args = array( - "headers" => "Content-Type: multipart/form-data; boundary=$Boundary\r\n\r\nAuthorization: Basic $client_id\r\n\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97", - "body" => "--$Boundary\r\nContent-Disposition: form-data; name=\"smfile\"; filename=\"$filename\"\r\n\r\n$bits\r\n\r\n--$Boundary--" - ); - - $response = wp_remote_post($upload_url, $args); - $reply = json_decode($response["body"]); - - if ($reply->success && $reply->code == 'success') { - $status = 200; - $success = true; - $message = $reply->message; - $link = $reply->data->url; - $proxy = akina_option('cmt_image_proxy') . $link; - } else if (preg_match("/Image upload repeated limit/i", $reply->message, $matches)) { - $status = 200; // sm.ms 接口不规范,建议检测到重复的情况下返回标准化的 code,并单独把 url 放进一个字段 - $success = true; - $message = $reply->message; - $link = str_replace('Image upload repeated limit, this image exists at: ', '', $reply->message); - $proxy = akina_option('cmt_image_proxy') . $link; - } else { - $status = 400; - $success = false; - $message = $reply->message; - $link = 'https://view.moezx.cc/images/2019/10/28/default_d_h_large.gif'; - $proxy = akina_option('cmt_image_proxy') . $link; - } - $output = array( - 'status' => $status, - 'success' => $success, - 'message' => $message, - 'link' => $link, - 'proxy' => $proxy, - ); - return $output; -} - -/* - * 定制实时搜索 rest api - * @rest api接口路径:https://sakura.2heng.xin/wp-json/sakura/v1/cache_search/json - * @可在cache_search_json()函数末尾通过设置 HTTP header 控制 json 缓存时间 - */ -function cache_search_json() -{ - global $more; - $vowels = array("[", "{", "]", "}", "<", ">", "\r\n", "\r", "\n", "-", "'", '"', '`', " ", ":", ";", '\\', " ", "toc"); - $regex = <<])*>|begin[\S\s]*\/begin|hermit[\S\s]*\/hermit|img[\S\s]*\/img|{{.*?}}|:.*?:/m -EOS; - $more = 1; - $output = array(); - - $posts = new WP_Query('posts_per_page=-1&post_status=publish&post_type=post'); - while ($posts->have_posts()): $posts->the_post(); - $output[] = array( - "type" => "post", - "link" => get_permalink(), - "title" => get_the_title(), - "comments" => get_comments_number('0', '1', '%'), - "text" => str_replace($vowels, " ", preg_replace($regex, ' ', apply_filters( 'the_content', get_the_content()))) - ); - endwhile; - wp_reset_postdata(); - - $pages = new WP_Query('posts_per_page=-1&post_status=publish&post_type=page'); - while ($pages->have_posts()): $pages->the_post(); - $output[] = array( - "type" => "page", - "link" => get_permalink(), - "title" => get_the_title(), - "comments" => get_comments_number('0', '1', '%'), - "text" => str_replace($vowels, " ", preg_replace($regex, ' ', apply_filters( 'the_content', get_the_content()))) - ); - endwhile; - wp_reset_postdata(); - - $tags = get_tags(); - foreach ($tags as $tag) { - $output[] = array( - "type" => "tag", - "link" => get_term_link($tag), - "title" => $tag->name, - "comments" => "", - "text" => "" - ); - } - - $categories = get_categories(); - foreach ($categories as $category) { - $output[] = array( - "type" => "category", - "link" => get_term_link($category), - "title" => $category->name, - "comments" => "", - "text" => "" - ); - } - if (akina_option('live_search_comment')) { - $comments = get_comments(); - foreach ($comments as $comment) { - $is_private = get_comment_meta($comment->comment_ID, '_private', true); - $output[] = array( - "type" => "comment", - "link" => get_comment_link($comment), - "title" => get_the_title($comment->comment_post_ID), - "comments" => "", - "text" => $is_private ? ($comment->comment_author . ": " . __('The comment is private', 'sakura')) : str_replace($vowels, ' ', preg_replace($regex, ' ', $comment->comment_author . ":" . $comment->comment_content)) - ); - } - } - - $result = new WP_REST_Response($output, 200); - $result->set_headers( - array( - 'Content-Type' => 'application/json', - 'Cache-Control' => 'max-age=3600', // json 缓存控制 - ) - ); - - return $result; -} /* * 随机封面图 rest api * @rest api接口路径:https://sakura.2heng.xin/wp-json/sakura/v1/image/cover */ function cover_gallery() { - if(akina_option('cover_cdn_options')=="type_2"){ - $img_array = glob(get_template_directory() . "/manifest/gallary/*.{gif,jpg,png}",GLOB_BRACE); - $img = array_rand($img_array); - $imgurl = trim($img_array[$img]); - $imgurl = str_replace(get_template_directory(), get_template_directory_uri(), $imgurl); - }elseif(akina_option('cover_cdn_options')=="type_3"){ - $imgurl = akina_option('cover_cdn'); - }else{ - global $sakura_image_array; - $img_array = json_decode($sakura_image_array, true); - $img = array_rand($img_array); - $img_domain = akina_option('cover_cdn') ? akina_option('cover_cdn') : get_template_directory_uri(); - if(strpos($_SERVER['HTTP_ACCEPT'], 'image/webp')) { - $imgurl = $img_domain . "/manifest/" . $img_array[$img]["webp"][0]; - } else { - $imgurl = $img_domain . "/manifest/" . $img_array[$img]["jpeg"][0]; - } - } + $imgurl = Images::cover_gallery(); $data = array('cover image'); $response = new WP_REST_Response($data); $response->set_status(302); @@ -393,122 +128,134 @@ function feature_gallery() { * @rest api接口路径:https://sakura.2heng.xin/wp-json/sakura/v1/database/update */ function update_database() { - if(akina_option('cover_cdn_options')=="type_1"){ - global $wpdb; - $sakura_table_name = $wpdb->base_prefix.'sakura'; - $img_domain = akina_option('cover_cdn') ? akina_option('cover_cdn') : get_template_directory(); - $manifest = file_get_contents($img_domain . "/manifest/manifest.json"); - if($manifest) { - $manifest = array( - "mate_key" => "manifest_json", - "mate_value" => $manifest - ); - $time = array( - "mate_key" => "json_time", - "mate_value" => date("Y-m-d H:i:s",time()) - ); - - $wpdb->query("DELETE FROM $sakura_table_name WHERE `mate_key` ='manifest_json'"); - $wpdb->query("DELETE FROM $sakura_table_name WHERE `mate_key` ='json_time'"); - $wpdb->insert($sakura_table_name,$manifest); - $wpdb->insert($sakura_table_name,$time); - $output = "manifest.json has been stored into database."; - }else{ - $output = "manifest.json not found, please ensure your url ($img_domain) is corrent."; - } + if (akina_option('cover_cdn_options') == "type_1") { + $output = Cache::update_database(); $result = new WP_REST_Response($output, 200); return $result; - }else{ + } else { return new WP_REST_Response("Invalid access", 200); } } +/* + * 定制实时搜索 rest api + * @rest api接口路径:https://sakura.2heng.xin/wp-json/sakura/v1/cache_search/json + * @可在cache_search_json()函数末尾通过设置 HTTP header 控制 json 缓存时间 + */ +function cache_search_json() { + if (!check_ajax_referer('wp_rest', '_wpnonce', false)) { + $output = array( + 'status' => 403, + 'success' => false, + 'message' => 'Unauthorized client.' + ); + $result = new WP_REST_Response($output, 403); + } else { + $output = Cache::search_json(); + $result = new WP_REST_Response($output, 200); + } + $result->set_headers( + array( + 'Content-Type' => 'application/json', + 'Cache-Control' => 'max-age=3600', // json 缓存控制 + ) + ); + return $result; +} + +/** + * QQ info + * https://sakura.2heng.xin/wp-json/sakura/v1/qqinfo/json + */ +function get_qq_info(WP_REST_Request $request) { + if (!check_ajax_referer('wp_rest', '_wpnonce', false)) { + $output = array( + 'status' => 403, + 'success' => false, + 'message' => 'Unauthorized client.' + ); + } elseif ($_GET['qq']) { + $qq = $_GET['qq']; + $output = QQ::get_qq_info($qq); + } else { + $output = array( + 'status' => 400, + 'success' => false, + 'message' => 'Bad Request' + ); + } + + $result = new WP_REST_Response($output, $output['status']); + $result->set_headers(array('Content-Type' => 'application/json')); + return $result; +} + /** * QQ头像链接解密 * https://sakura.2heng.xin/wp-json/sakura/v1/qqinfo/avatar */ -function get_qq_avatar(){ - global $sakura_privkey; - $encrypted=$_GET["qq"]; - if(isset($encrypted)){ - $iv = str_repeat($sakura_privkey, 2); - $encrypted = base64_decode(urldecode($encrypted)); - $qq_number = openssl_decrypt($encrypted, 'aes-128-cbc', $sakura_privkey, 0, $iv); - preg_match('/^\d{3,}$/', $qq_number, $matches); - $imgurl='https://q2.qlogo.cn/headimg_dl?dst_uin='.$matches[0].'&spec=100'; - if(akina_option('qq_avatar_link')=='type_2'){ - $imgdata = file_get_contents($imgurl); +function get_qq_avatar() { + $encrypted = $_GET["qq"]; + $imgurl = QQ::get_qq_avatar($encrypted); + if (akina_option('qq_avatar_link') == 'type_2') { + $imgdata = file_get_contents($imgurl); + $response = new WP_REST_Response(); + $response->set_headers(array( + 'Content-Type' => 'image/jpeg', + 'Cache-Control' => 'max-age=86400' + )); + echo $imgdata; + } else { + $response = new WP_REST_Response(); + $response->set_status(301); + $response->header('Location', $imgurl); + } + return $response; +} + +function bgm_bilibili() { + if (!check_ajax_referer('wp_rest', 'r', false)) { + $output = array( + 'status' => 403, + 'success' => false, + 'message' => 'Unauthorized client.' + ); + $response = new WP_REST_Response($output, 403); + } else { + $page = $_GET["page"] ?: 2; + $bgm = new \Sakura\API\Bilibili(); + $html = preg_replace("/\s+|\n+|\r/", ' ', $bgm->get_bgm_items($page)); + $response = new WP_REST_Response($html, 200); + } + return $response; +} + +function meting_aplayer() { + $type = $_GET['type']; + $id = $_GET['id']; + if (check_ajax_referer('wp_rest', '_wpnonce', false) || !wp_verify_nonce($_GET['meting_pnonce'], $type . '#:' . $id)) { + $Meting_API = new \Sakura\API\Aplayer(); + $data = $Meting_API->get_data($type, $id); + if ($type === 'playlist') { + $response = new WP_REST_Response($data, 200); + $response->set_headers(array('cache-control' => 'max-age=3600')); + } elseif ($type === 'lyric') { $response = new WP_REST_Response(); - $response->set_headers(array( - 'Content-Type' => 'image/jpeg', - 'Cache-Control' => 'max-age=86400' - )); - echo $imgdata; - return $response; - }else{ + $response->set_headers(array('cache-control' => 'max-age=3600')); + echo $data; + } else { + $data = str_replace('http://', 'https://', $data); $response = new WP_REST_Response(); $response->set_status(301); - $response->header('Location', $imgurl); - return $response; + $response->header('Location', $data); } - } -} - - -function get_the_bgm_items($page = 1){ - $cookies = akina_option('bilibili_cookie'); - $url = 'https://api.bilibili.com/x/space/bangumi/follow/list?type=1&pn=' . $page . '&ps=15&follow_status=0&vmid=' . akina_option('bilibili_id'); - $args = array( - 'headers' => array( - 'Cookie' => $cookies, - 'Host' => 'api.bilibili.com', - 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97' - ) - ); - $response = wp_remote_get($url, $args); - $bgmdata = json_decode($response["body"])->data; - return json_encode($bgmdata); -} - -function get_bgm_items($page = 1){ - $bgm = json_decode(get_the_bgm_items($page),true); - $totalpage = $bgm["total"] / 15; - if($totalpage - $page < 0){ - $next = '共追番' . $bgm["total"] .'部,继续加油吧!٩(ˊᗜˋ*)و'; - }else{ - $next = ' NEXT '; + } else { + $output = array( + 'status' => 403, + 'success' => false, + 'message' => 'Unauthorized client.' + ); + $response = new WP_REST_Response($output, 403); } - $lists = $bgm["list"]; - foreach ((array)$lists as $list) { - if(preg_match('/看完/m',$list["progress"], $matches_finish)){ - $percent = 100; - }else{ - preg_match('/第(\d+)./m',$list['progress'], $matches_progress); - preg_match('/第(\d+)./m',$list["new_ep"]['index_show'], $matches_new); - $progress = is_numeric($matches_progress[1]) ? $matches_progress[1] : 0; - $total = is_numeric($matches_new[1]) ? $matches_new[1] : $list['total_count']; - $percent = $progress / $total * 100; - } - $html .= ''; - } - $html .= '

' . $next .'
'; - return $html; -} - -function bgm_bilibili(){ - $page = $_GET["page"] ?: 2; - $html = preg_replace("/\s+|\n+|\r/", ' ', get_bgm_items($page)); - return $response = new WP_REST_Response($html,200); + return $response; } \ No newline at end of file diff --git a/inc/classes/Aplayer.php b/inc/classes/Aplayer.php new file mode 100644 index 0000000..29de769 --- /dev/null +++ b/inc/classes/Aplayer.php @@ -0,0 +1,136 @@ +server = akina_option('aplayer_server'); + $this->playlist_id = akina_option('aplayer_playlistid'); + $this->cookies = akina_option('aplayer_cookie'); + $this->api_url = rest_url('sakura/v1/meting/aplayer'); + require('Meting.php'); + } + + public function get_data($type, $id) { + $server = $this->server; + $cookies = $this->cookies; + $playlist_id = $this->playlist_id; + $api = new \Sakura\API\Meting($server); + if (!empty($cookies) && $server === "netease") $api->cookie($cookies); + switch ($type) { + case 'song': + $data = $api->format(true)->song($id); + $data = json_decode($data, true)["url"]; + break; + // case 'album': + // $data = $api->format(true)->album($id); + // $data=json_decode($data, true)["url"]; + // break; + case 'playlist': + $data = $api->format(true)->playlist($playlist_id); + $data = $this->format_playlist($data); + break; + case 'lyric': + $data = $api->format(true)->lyric($id); + $data = $this->format_lyric($data); + break; + case 'pic': + $data = $api->format(true)->pic($id); + $data = json_decode($data, true)["url"]; + break; + // case 'search': + // $data = $api->format(true)->search($id); + // $data=json_decode($data, true)["url"]; + // break; + default: + $data = $api->format(true)->url($id); + $data = json_decode($data, true)["url"]; + break; + } + return $data; + } + + private function format_playlist($data) { + $server = $this->server; + $api_url = $this->api_url; + $data = json_decode($data); + $playlist = array(); + foreach ((array)$data as $value) { + $name = $value->name; + $artists = implode(" / ", (array)$value->artist); + $mp3_url = "$api_url?server=$server&type=url&id=" . $value->url_id . '&meting_nonce=' . wp_create_nonce('url#:' . $value->url_id); + $cover = "$api_url?server=$server&type=pic&id=" . $value->pic_id . '&meting_nonce=' . wp_create_nonce('pic#:' . $value->url_id); + $lyric = "$api_url?server=$server&type=lyric&id=" . $value->lyric_id . '&meting_nonce=' . wp_create_nonce('lyric#:' . $value->url_id); + $playlist[] = array( + "name" => $name, + "artist" => $artists, + "url" => $mp3_url, + "cover" => $cover, + "lrc" => $lyric + ); + } + return $playlist; + } + + private function format_lyric($data) { + $server = $this->server; + $data = json_decode($data, true); + $data = $this->lrctran($data['lyric'], $data['tlyric']); + if (empty($data)) { + $data = "[00:00.000]此歌曲暂无歌词,请您欣赏"; + } + if ($server === 'tencent') { + $data = html_entity_decode($data, ENT_QUOTES | ENT_HTML5); + } + return $data; + } + + private function lrctran($lyric, $tlyric) { + $lyric = $this->lrctrim($lyric); + $tlyric = $this->lrctrim($tlyric); + $len1 = count($lyric); + $len2 = count($tlyric); + $result = ""; + for ($i = 0, $j = 0; $i < $len1 && $j < $len2; $i++) { + while ($lyric[$i][0] > $tlyric[$j][0] && $j + 1 < $len2) { + $j++; + } + if ($lyric[$i][0] == $tlyric[$j][0]) { + $tlyric[$j][2] = str_replace('/', '', $tlyric[$j][2]); + if (!empty($tlyric[$j][2])) { + $lyric[$i][2] .= " ({$tlyric[$j][2]})"; + } + $j++; + } + } + for ($i = 0; $i < $len1; $i++) { + $t = $lyric[$i][0]; + $result .= sprintf("[%02d:%02d.%03d]%s\n", $t / 60000, $t % 60000 / 1000, $t % 1000, $lyric[$i][2]); + } + return $result; + } + + private function lrctrim($lyrics) { + $lyrics = explode("\n", $lyrics); + $data = array(); + foreach ($lyrics as $key => $lyric) { + preg_match('/\[(\d{2}):(\d{2}[\.:]?\d*)]/', $lyric, $lrcTimes); + $lrcText = preg_replace('/\[(\d{2}):(\d{2}[\.:]?\d*)]/', '', $lyric); + if (empty($lrcTimes)) { + continue; + } + $lrcTimes = intval($lrcTimes[1]) * 60000 + intval(floatval($lrcTimes[2]) * 1000); + $lrcText = preg_replace('/\s\s+/', ' ', $lrcText); + $lrcText = trim($lrcText); + $data[] = array($lrcTimes, $key, $lrcText); + } + sort($data); + return $data; + } +} \ No newline at end of file diff --git a/inc/classes/Bilibili.php b/inc/classes/Bilibili.php new file mode 100644 index 0000000..7cc91c5 --- /dev/null +++ b/inc/classes/Bilibili.php @@ -0,0 +1,68 @@ +uid = akina_option('bilibili_id'); + $this->cookies = akina_option('bilibili_cookie'); + } + + public function get_the_bgm_items($page = 1) { + $uid = $this->uid; + $cookies = $this->cookies; + $url = 'https://api.bilibili.com/x/space/bangumi/follow/list?type=1&pn=' . $page . '&ps=15&follow_status=0&vmid=' . $uid; + $args = array( + 'headers' => array( + 'Cookie' => $cookies, + 'Host' => 'api.bilibili.com', + 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97' + ) + ); + $response = wp_remote_get($url, $args); + $bgmdata = json_decode($response["body"])->data; + return json_encode($bgmdata); + } + + public function get_bgm_items($page = 1) { + $bgm = json_decode($this->get_the_bgm_items($page), true); + $totalpage = $bgm["total"] / 15; + if ($totalpage - $page < 0) { + $next = '共追番' . $bgm["total"] . '部,继续加油吧!٩(ˊᗜˋ*)و'; + } else { + $next = ' NEXT '; + } + $lists = $bgm["list"]; + $html = ""; + foreach ((array)$lists as $list) { + if (preg_match('/看完/m', $list["progress"], $matches_finish)) { + $percent = 100; + } else { + preg_match('/第(\d+)./m', $list['progress'], $matches_progress); + preg_match('/第(\d+)./m', $list["new_ep"]['index_show'], $matches_new); + $progress = is_numeric($matches_progress[1]) ? $matches_progress[1] : 0; + $total = is_numeric($matches_new[1]) ? $matches_new[1] : $list['total_count']; + $percent = $progress / $total * 100; + } + $html .= '
+ + +
+

' . $list['title'] . '

+
' . $list['evaluate'] . '
+
+
+

' . $list['new_ep']['index_show'] . '

+
+
+
+
'; + } + $html .= '
' . $next . '
'; + return $html; + } +} \ No newline at end of file diff --git a/inc/classes/Cache.php b/inc/classes/Cache.php new file mode 100644 index 0000000..59879db --- /dev/null +++ b/inc/classes/Cache.php @@ -0,0 +1,103 @@ +", "\r\n", "\r", "\n", "-", "'", '"', '`', " ", ":", ";", '\\', " ", "toc"); + $regex = <<])*>|begin[\S\s]*\/begin|hermit[\S\s]*\/hermit|img[\S\s]*\/img|{{.*?}}|:.*?:/m +EOS; + $more = 1; + $output = array(); + + $posts = new \WP_Query('posts_per_page=-1&post_status=publish&post_type=post'); + while ($posts->have_posts()): $posts->the_post(); + $output[] = array( + "type" => "post", + "link" => get_permalink(), + "title" => get_the_title(), + "comments" => get_comments_number('0', '1', '%'), + "text" => str_replace($vowels, " ", preg_replace($regex, ' ', apply_filters('the_content', get_the_content()))) + ); + endwhile; + wp_reset_postdata(); + + $pages = new \WP_Query('posts_per_page=-1&post_status=publish&post_type=page'); + while ($pages->have_posts()): $pages->the_post(); + $output[] = array( + "type" => "page", + "link" => get_permalink(), + "title" => get_the_title(), + "comments" => get_comments_number('0', '1', '%'), + "text" => str_replace($vowels, " ", preg_replace($regex, ' ', apply_filters('the_content', get_the_content()))) + ); + endwhile; + wp_reset_postdata(); + + $tags = get_tags(); + foreach ($tags as $tag) { + $output[] = array( + "type" => "tag", + "link" => get_term_link($tag), + "title" => $tag->name, + "comments" => "", + "text" => "" + ); + } + + $categories = get_categories(); + foreach ($categories as $category) { + $output[] = array( + "type" => "category", + "link" => get_term_link($category), + "title" => $category->name, + "comments" => "", + "text" => "" + ); + } + if (akina_option('live_search_comment')) { + $comments = get_comments(); + foreach ($comments as $comment) { + $is_private = get_comment_meta($comment->comment_ID, '_private', true); + $output[] = array( + "type" => "comment", + "link" => get_comment_link($comment), + "title" => get_the_title($comment->comment_post_ID), + "comments" => "", + "text" => $is_private ? ($comment->comment_author . ": " . __('The comment is private', 'sakura')) : str_replace($vowels, ' ', preg_replace($regex, ' ', $comment->comment_author . ":" . $comment->comment_content)) + ); + } + } + return $output; + } + + + public static function update_database() { + global $wpdb; + $sakura_table_name = $wpdb->base_prefix . 'sakura'; + $img_domain = akina_option('cover_cdn') ? akina_option('cover_cdn') : get_template_directory(); + $manifest = file_get_contents($img_domain . "/manifest/manifest.json"); + if ($manifest) { + $manifest = array( + "mate_key" => "manifest_json", + "mate_value" => $manifest + ); + $time = array( + "mate_key" => "json_time", + "mate_value" => date("Y-m-d H:i:s", time()) + ); + + $wpdb->query("DELETE FROM $sakura_table_name WHERE `mate_key` ='manifest_json'"); + $wpdb->query("DELETE FROM $sakura_table_name WHERE `mate_key` ='json_time'"); + $wpdb->insert($sakura_table_name, $manifest); + $wpdb->insert($sakura_table_name, $time); + $output = "manifest.json has been stored into database."; + } else { + $output = "manifest.json not found, please ensure your url ($img_domain) is corrent."; + } + return $output; + } +} \ No newline at end of file diff --git a/inc/classes/Images.php b/inc/classes/Images.php new file mode 100644 index 0000000..f0675f4 --- /dev/null +++ b/inc/classes/Images.php @@ -0,0 +1,165 @@ +chevereto_api_key = akina_option('chevereto_api_key'); + $this->imgur_client_id = akina_option('imgur_client_id'); + $this->smms_client_id = akina_option('smms_client_id'); + } + + + /** + * Chevereto upload interface + */ + public function Chevereto_API($image) { + $upload_url = akina_option('cheverto_url') . '/api/1/upload'; + $args = array( + 'body' => array( + 'source' => base64_encode($image), + 'key' => $this->chevereto_api_key, + ), + ); + + $response = wp_remote_post($upload_url, $args); + $reply = json_decode($response["body"]); + + if ($reply->status_txt == 'OK' && $reply->status_code == 200) { + $status = 200; + $success = true; + $message = "success"; + $link = $reply->image->image->url; + $proxy = akina_option('cmt_image_proxy') . $link; + } else { + $status = $reply->status_code; + $success = false; + $message = $reply->error->message; + $link = 'https://view.moezx.cc/images/2019/10/28/default_d_h_large.gif'; + $proxy = akina_option('cmt_image_proxy') . $link; + } + $output = array( + 'status' => $status, + 'success' => $success, + 'message' => $message, + 'link' => $link, + 'proxy' => $proxy, + ); + return $output; + } + + /** + * Imgur upload interface + */ + public function Imgur_API($image) { + $upload_url = akina_option('imgur_upload_image_proxy'); + $args = array( + 'headers' => array( + 'Authorization' => 'Client-ID ' . $this->imgur_client_id, + ), + 'body' => array( + 'image' => base64_encode($image), + ), + ); + + $response = wp_remote_post($upload_url, $args); + $reply = json_decode($response["body"]); + + if ($reply->success && $reply->status == 200) { + $status = 200; + $success = true; + $message = "success"; + $link = $reply->data->link; + $proxy = akina_option('cmt_image_proxy') . $link; + } else { + $status = $reply->status; + $success = false; + $message = $reply->data->error; + $link = 'https://view.moezx.cc/images/2019/10/28/default_d_h_large.gif'; + $proxy = akina_option('cmt_image_proxy') . $link; + } + $output = array( + 'status' => $status, + 'success' => $success, + 'message' => $message, + 'link' => $link, + 'proxy' => $proxy, + ); + return $output; + } + + /** + * smms upload interface + */ + public function SMMS_API($image) { + $client_id = $this->smms_client_id; + $upload_url = "https://sm.ms/api/v2/upload"; + $filename = $image['cmt_img_file']['name']; + $filedata = $image['cmt_img_file']['tmp_name']; + $Boundary = wp_generate_password(); + $bits = file_get_contents($filedata); + + $args = array( + "headers" => "Content-Type: multipart/form-data; boundary=$Boundary\r\n\r\nAuthorization: Basic $client_id\r\n\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97", + "body" => "--$Boundary\r\nContent-Disposition: form-data; name=\"smfile\"; filename=\"$filename\"\r\n\r\n$bits\r\n\r\n--$Boundary--" + ); + + $response = wp_remote_post($upload_url, $args); + $reply = json_decode($response["body"]); + + if ($reply->success && $reply->code == 'success') { + $status = 200; + $success = true; + $message = $reply->message; + $link = $reply->data->url; + $proxy = akina_option('cmt_image_proxy') . $link; + } else if (preg_match("/Image upload repeated limit/i", $reply->message, $matches)) { + $status = 200; // sm.ms 接口不规范,建议检测到重复的情况下返回标准化的 code,并单独把 url 放进一个字段 + $success = true; + $message = $reply->message; + $link = str_replace('Image upload repeated limit, this image exists at: ', '', $reply->message); + $proxy = akina_option('cmt_image_proxy') . $link; + } else { + $status = 400; + $success = false; + $message = $reply->message; + $link = 'https://view.moezx.cc/images/2019/10/28/default_d_h_large.gif'; + $proxy = akina_option('cmt_image_proxy') . $link; + } + $output = array( + 'status' => $status, + 'success' => $success, + 'message' => $message, + 'link' => $link, + 'proxy' => $proxy, + ); + return $output; + } + + public static function cover_gallery() { + if (akina_option('cover_cdn_options') == "type_2") { + $img_array = glob(get_template_directory() . "/manifest/gallary/*.{gif,jpg,png}", GLOB_BRACE); + $img = array_rand($img_array); + $imgurl = trim($img_array[$img]); + $imgurl = str_replace(get_template_directory(), get_template_directory_uri(), $imgurl); + } elseif (akina_option('cover_cdn_options') == "type_3") { + $imgurl = akina_option('cover_cdn'); + } else { + global $sakura_image_array; + $img_array = json_decode($sakura_image_array, true); + $img = array_rand($img_array); + $img_domain = akina_option('cover_cdn') ? akina_option('cover_cdn') : get_template_directory_uri(); + if (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp')) { + $imgurl = $img_domain . "/manifest/" . $img_array[$img]["webp"][0]; + } else { + $imgurl = $img_domain . "/manifest/" . $img_array[$img]["jpeg"][0]; + } + } + return $imgurl; + } +} \ No newline at end of file diff --git a/inc/classes/Meting.php b/inc/classes/Meting.php new file mode 100755 index 0000000..c274e80 --- /dev/null +++ b/inc/classes/Meting.php @@ -0,0 +1,1365 @@ + + * Released under the MIT license + */ + +namespace Sakura\API; + +class Meting +{ + const VERSION = '1.5.7'; + + public $raw; + public $data; + public $info; + public $error; + public $status; + + public $server; + public $proxy = null; + public $format = false; + public $header; + + public function __construct($value = 'netease') + { + $this->site($value); + } + + public function site($value) + { + $suppose = array('netease', 'tencent', 'xiami', 'kugou', 'baidu'); + $this->server = in_array($value, $suppose) ? $value : 'netease'; + $this->header = $this->curlset(); + + return $this; + } + + public function cookie($value) + { + $this->header['Cookie'] = $value; + + return $this; + } + + public function format($value = true) + { + $this->format = $value; + + return $this; + } + + public function proxy($value) + { + $this->proxy = $value; + + return $this; + } + + private function exec($api) + { + if (isset($api['encode'])) { + $api = call_user_func_array(array($this, $api['encode']), array($api)); + } + if ($api['method'] == 'GET') { + if (isset($api['body'])) { + $api['url'] .= '?'.http_build_query($api['body']); + $api['body'] = null; + } + } + + $this->curl($api['url'], $api['body']); + + if (!$this->format) { + return $this->raw; + } + + $this->data = $this->raw; + + if (isset($api['decode'])) { + $this->data = call_user_func_array(array($this, $api['decode']), array($this->data)); + } + if (isset($api['format'])) { + $this->data = $this->clean($this->data, $api['format']); + } + + return $this->data; + } + + private function curl($url, $payload = null, $headerOnly = 0) + { + $header = array_map(function ($k, $v) { + return $k.': '.$v; + }, array_keys($this->header), $this->header); + $curl = curl_init(); + if (!is_null($payload)) { + curl_setopt($curl, CURLOPT_POST, 1); + curl_setopt($curl, CURLOPT_POSTFIELDS, is_array($payload) ? http_build_query($payload) : $payload); + } + curl_setopt($curl, CURLOPT_HEADER, $headerOnly); + curl_setopt($curl, CURLOPT_TIMEOUT, 20); + curl_setopt($curl, CURLOPT_ENCODING, 'gzip'); + curl_setopt($curl, CURLOPT_IPRESOLVE, 1); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_HTTPHEADER, $header); + if ($this->proxy) { + curl_setopt($curl, CURLOPT_PROXY, $this->proxy); + } + for ($i = 0; $i < 3; $i++) { + $this->raw = curl_exec($curl); + $this->info = curl_getinfo($curl); + $this->error = curl_errno($curl); + $this->status = $this->error ? curl_error($curl) : ''; + if (!$this->error) { + break; + } + } + curl_close($curl); + + return $this; + } + + private function pickup($array, $rule) + { + $t = explode('.', $rule); + foreach ($t as $vo) { + if (!isset($array[$vo])) { + return array(); + } + $array = $array[$vo]; + } + + return $array; + } + + private function clean($raw, $rule) + { + $raw = json_decode($raw, true); + if (!empty($rule)) { + $raw = $this->pickup($raw, $rule); + } + if (!isset($raw[0]) && count($raw)) { + $raw = array($raw); + } + $result = array_map(array($this, 'format_'.$this->server), $raw); + + return json_encode($result); + } + + public function search($keyword, $option = null) + { + switch ($this->server) { + case 'netease': + $api = array( + 'method' => 'POST', + 'url' => 'http://music.163.com/api/cloudsearch/pc', + 'body' => array( + 's' => $keyword, + 'type' => isset($option['type']) ? $option['type'] : 1, + 'limit' => isset($option['limit']) ? $option['limit'] : 30, + 'total' => 'true', + 'offset' => isset($option['page']) && isset($option['limit']) ? ($option['page'] - 1) * $option['limit'] : 0, + ), + 'encode' => 'netease_AESCBC', + 'format' => 'result.songs', + ); + break; + case 'tencent': + $api = array( + 'method' => 'GET', + 'url' => 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp', + 'body' => array( + 'format' => 'json', + 'p' => isset($option['page']) ? $option['page'] : 1, + 'n' => isset($option['limit']) ? $option['limit'] : 30, + 'w' => $keyword, + 'aggr' => 1, + 'lossless' => 1, + 'cr' => 1, + 'new_json' => 1, + ), + 'format' => 'data.song.list', + ); + break; + case 'xiami': + $api = array( + 'method' => 'GET', + 'url' => 'https://acs.m.xiami.com/h5/mtop.alimusic.search.searchservice.searchsongs/1.0/', + 'body' => array( + 'data' => array( + 'key' => $keyword, + 'pagingVO' => array( + 'page' => isset($option['page']) ? $option['page'] : 1, + 'pageSize' => isset($option['limit']) ? $option['limit'] : 30, + ), + ), + 'r' => 'mtop.alimusic.search.searchservice.searchsongs', + ), + 'encode' => 'xiami_sign', + 'format' => 'data.data.songs', + ); + break; + case 'kugou': + $api = array( + 'method' => 'GET', + 'url' => 'http://mobilecdn.kugou.com/api/v3/search/song', + 'body' => array( + 'api_ver' => 1, + 'area_code' => 1, + 'correct' => 1, + 'pagesize' => isset($option['limit']) ? $option['limit'] : 30, + 'plat' => 2, + 'tag' => 1, + 'sver' => 5, + 'showtype' => 10, + 'page' => isset($option['page']) ? $option['page'] : 1, + 'keyword' => $keyword, + 'version' => 8990, + ), + 'format' => 'data.info', + ); + break; + case 'baidu': + $api = array( + 'method' => 'GET', + 'url' => 'http://musicapi.taihe.com/v1/restserver/ting', + 'body' => array( + 'from' => 'qianqianmini', + 'method' => 'baidu.ting.search.merge', + 'isNew' => 1, + 'platform' => 'darwin', + 'page_no' => isset($option['page']) ? $option['page'] : 1, + 'query' => $keyword, + 'version' => '11.2.1', + 'page_size' => isset($option['limit']) ? $option['limit'] : 30, + ), + 'format' => 'result.song_info.song_list', + ); + break; + } + + return $this->exec($api); + } + + public function song($id) + { + switch ($this->server) { + case 'netease': + $api = array( + 'method' => 'POST', + 'url' => 'http://music.163.com/api/v3/song/detail/', + 'body' => array( + 'c' => '[{"id":'.$id.',"v":0}]', + ), + 'encode' => 'netease_AESCBC', + 'format' => 'songs', + ); + break; + case 'tencent': + $api = array( + 'method' => 'GET', + 'url' => 'https://c.y.qq.com/v8/fcg-bin/fcg_play_single_song.fcg', + 'body' => array( + 'songmid' => $id, + 'platform' => 'yqq', + 'format' => 'json', + ), + 'format' => 'data', + ); + break; + case 'xiami': + $api = array( + 'method' => 'GET', + 'url' => 'https://acs.m.xiami.com/h5/mtop.alimusic.music.songservice.getsongdetail/1.0/', + 'body' => array( + 'data' => array( + 'songId' => $id, + ), + 'r' => 'mtop.alimusic.music.songservice.getsongdetail', + ), + 'encode' => 'xiami_sign', + 'format' => 'data.data.songDetail', + ); + break; + case 'kugou': + $api = array( + 'method' => 'POST', + 'url' => 'http://m.kugou.com/app/i/getSongInfo.php', + 'body' => array( + 'cmd' => 'playInfo', + 'hash' => $id, + 'from' => 'mkugou', + ), + 'format' => '', + ); + break; + case 'baidu': + $api = array( + 'method' => 'GET', + 'url' => 'http://musicapi.taihe.com/v1/restserver/ting', + 'body' => array( + 'from' => 'qianqianmini', + 'method' => 'baidu.ting.song.getInfos', + 'songid' => $id, + 'res' => 1, + 'platform' => 'darwin', + 'version' => '1.0.0', + ), + 'encode' => 'baidu_AESCBC', + 'format' => 'songinfo', + ); + break; + } + + return $this->exec($api); + } + + public function album($id) + { + switch ($this->server) { + case 'netease': + $api = array( + 'method' => 'POST', + 'url' => 'http://music.163.com/api/v1/album/'.$id, + 'body' => array( + 'total' => 'true', + 'offset' => '0', + 'id' => $id, + 'limit' => '1000', + 'ext' => 'true', + 'private_cloud' => 'true', + ), + 'encode' => 'netease_AESCBC', + 'format' => 'songs', + ); + break; + case 'tencent': + $api = array( + 'method' => 'GET', + 'url' => 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_album_detail_cp.fcg', + 'body' => array( + 'albummid' => $id, + 'platform' => 'mac', + 'format' => 'json', + 'newsong' => 1, + ), + 'format' => 'data.getSongInfo', + ); + break; + case 'xiami': + $api = array( + 'method' => 'GET', + 'url' => 'https://acs.m.xiami.com/h5/mtop.alimusic.music.albumservice.getalbumdetail/1.0/', + 'body' => array( + 'data' => array( + 'albumId' => $id, + ), + 'r' => 'mtop.alimusic.music.albumservice.getalbumdetail', + ), + 'encode' => 'xiami_sign', + 'format' => 'data.data.albumDetail.songs', + ); + break; + case 'kugou': + $api = array( + 'method' => 'GET', + 'url' => 'http://mobilecdn.kugou.com/api/v3/album/song', + 'body' => array( + 'albumid' => $id, + 'area_code' => 1, + 'plat' => 2, + 'page' => 1, + 'pagesize' => -1, + 'version' => 8990, + ), + 'format' => 'data.info', + ); + break; + case 'baidu': + $api = array( + 'method' => 'GET', + 'url' => 'http://musicapi.taihe.com/v1/restserver/ting', + 'body' => array( + 'from' => 'qianqianmini', + 'method' => 'baidu.ting.album.getAlbumInfo', + 'album_id' => $id, + 'platform' => 'darwin', + 'version' => '11.2.1', + ), + 'format' => 'songlist', + ); + break; + } + + return $this->exec($api); + } + + public function artist($id, $limit = 50) + { + switch ($this->server) { + case 'netease': + $api = array( + 'method' => 'POST', + 'url' => 'http://music.163.com/api/v1/artist/'.$id, + 'body' => array( + 'ext' => 'true', + 'private_cloud' => 'true', + 'ext' => 'true', + 'top' => $limit, + 'id' => $id, + ), + 'encode' => 'netease_AESCBC', + 'format' => 'hotSongs', + ); + break; + case 'tencent': + $api = array( + 'method' => 'GET', + 'url' => 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg', + 'body' => array( + 'singermid' => $id, + 'begin' => 0, + 'num' => $limit, + 'order' => 'listen', + 'platform' => 'mac', + 'newsong' => 1, + ), + 'format' => 'data.list', + ); + break; + case 'xiami': + $api = array( + 'method' => 'GET', + 'url' => 'https://acs.m.xiami.com/h5/mtop.alimusic.music.songservice.getartistsongs/1.0/', + 'body' => array( + 'data' => array( + 'artistId' => $id, + 'pagingVO' => array( + 'page' => 1, + 'pageSize' => $limit, + ), + ), + 'r' => 'mtop.alimusic.music.songservice.getartistsongs', + ), + 'encode' => 'xiami_sign', + 'format' => 'data.data.songs', + ); + break; + case 'kugou': + $api = array( + 'method' => 'GET', + 'url' => 'http://mobilecdn.kugou.com/api/v3/singer/song', + 'body' => array( + 'singerid' => $id, + 'area_code' => 1, + 'page' => 1, + 'plat' => 0, + 'pagesize' => $limit, + 'version' => 8990, + ), + 'format' => 'data.info', + ); + break; + case 'baidu': + $api = array( + 'method' => 'GET', + 'url' => 'http://musicapi.taihe.com/v1/restserver/ting', + 'body' => array( + 'from' => 'qianqianmini', + 'method' => 'baidu.ting.artist.getSongList', + 'artistid' => $id, + 'limits' => $limit, + 'platform' => 'darwin', + 'offset' => 0, + 'tinguid' => 0, + 'version' => '11.2.1', + ), + 'format' => 'songlist', + ); + break; + } + + return $this->exec($api); + } + + public function playlist($id) + { + switch ($this->server) { + case 'netease': + $api = array( + 'method' => 'POST', + 'url' => 'http://music.163.com/api/v3/playlist/detail', + 'body' => array( + 's' => '0', + 'id' => $id, + 'n' => '1000', + 't' => '0', + ), + 'encode' => 'netease_AESCBC', + 'format' => 'playlist.tracks', + ); + break; + case 'tencent': + $api = array( + 'method' => 'GET', + 'url' => 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_playlist_cp.fcg', + 'body' => array( + 'id' => $id, + 'format' => 'json', + 'newsong' => 1, + 'platform' => 'jqspaframe.json', + ), + 'format' => 'data.cdlist.0.songlist', + ); + break; + case 'xiami': + $api = array( + 'method' => 'GET', + 'url' => 'https://acs.m.xiami.com/h5/mtop.alimusic.music.list.collectservice.getcollectdetail/1.0/', + 'body' => array( + 'data' => array( + 'listId' => $id, + 'isFullTags' => false, + 'pagingVO' => array( + 'page' => 1, + 'pageSize' => 1000, + ), + ), + 'r' => 'mtop.alimusic.music.list.collectservice.getcollectdetail', + ), + 'encode' => 'xiami_sign', + 'format' => 'data.data.collectDetail.songs', + ); + break; + case 'kugou': + $api = array( + 'method' => 'GET', + 'url' => 'http://mobilecdn.kugou.com/api/v3/special/song', + 'body' => array( + 'specialid' => $id, + 'area_code' => 1, + 'page' => 1, + 'plat' => 2, + 'pagesize' => -1, + 'version' => 8990, + ), + 'format' => 'data.info', + ); + break; + case 'baidu': + $api = array( + 'method' => 'GET', + 'url' => 'http://musicapi.taihe.com/v1/restserver/ting', + 'body' => array( + 'from' => 'qianqianmini', + 'method' => 'baidu.ting.diy.gedanInfo', + 'listid' => $id, + 'platform' => 'darwin', + 'version' => '11.2.1', + ), + 'format' => 'content', + ); + break; + } + + return $this->exec($api); + } + + public function url($id, $br = 320) + { + switch ($this->server) { + case 'netease': + $api = array( + 'method' => 'POST', + 'url' => 'http://music.163.com/api/song/enhance/player/url', + 'body' => array( + 'ids' => array($id), + 'br' => $br * 1000, + ), + 'encode' => 'netease_AESCBC', + 'decode' => 'netease_url', + ); + break; + case 'tencent': + $api = array( + 'method' => 'GET', + 'url' => 'https://c.y.qq.com/v8/fcg-bin/fcg_play_single_song.fcg', + 'body' => array( + 'songmid' => $id, + 'platform' => 'yqq', + 'format' => 'json', + ), + 'decode' => 'tencent_url', + ); + break; + case 'xiami': + $api = array( + 'method' => 'GET', + 'url' => 'https://acs.m.xiami.com/h5/mtop.alimusic.music.songservice.getsongs/1.0/', + 'body' => array( + 'data' => array( + 'songIds' => array( + $id, + ), + ), + 'r' => 'mtop.alimusic.music.songservice.getsongs', + ), + 'encode' => 'xiami_sign', + 'decode' => 'xiami_url', + ); + break; + case 'kugou': + $api = array( + 'method' => 'POST', + 'url' => 'http://media.store.kugou.com/v1/get_res_privilege', + 'body' => json_encode( + array( + 'relate' => 1, + 'userid' => '0', + 'vip' => 0, + 'appid' => 1000, + 'token' => '', + 'behavior' => 'download', + 'area_code' => '1', + 'clientver' => '8990', + 'resource' => array(array( + 'id' => 0, + 'type' => 'audio', + 'hash' => $id, + )), ) + ), + 'decode' => 'kugou_url', + ); + break; + case 'baidu': + $api = array( + 'method' => 'GET', + 'url' => 'http://musicapi.taihe.com/v1/restserver/ting', + 'body' => array( + 'from' => 'qianqianmini', + 'method' => 'baidu.ting.song.getInfos', + 'songid' => $id, + 'res' => 1, + 'platform' => 'darwin', + 'version' => '1.0.0', + ), + 'encode' => 'baidu_AESCBC', + 'decode' => 'baidu_url', + ); + break; + } + $this->temp['br'] = $br; + + return $this->exec($api); + } + + public function lyric($id) + { + switch ($this->server) { + case 'netease': + $api = array( + 'method' => 'POST', + 'url' => 'http://music.163.com/api/song/lyric', + 'body' => array( + 'id' => $id, + 'os' => 'linux', + 'lv' => -1, + 'kv' => -1, + 'tv' => -1, + ), + 'encode' => 'netease_AESCBC', + 'decode' => 'netease_lyric', + ); + break; + case 'tencent': + $api = array( + 'method' => 'GET', + 'url' => 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg', + 'body' => array( + 'songmid' => $id, + 'g_tk' => '5381', + ), + 'decode' => 'tencent_lyric', + ); + break; + case 'xiami': + $api = array( + 'method' => 'GET', + 'url' => 'https://acs.m.xiami.com/h5/mtop.alimusic.music.lyricservice.getsonglyrics/1.0/', + 'body' => array( + 'data' => array( + 'songId' => $id, + ), + 'r' => 'mtop.alimusic.music.lyricservice.getsonglyrics', + ), + 'encode' => 'xiami_sign', + 'decode' => 'xiami_lyric', + ); + break; + case 'kugou': + $api = array( + 'method' => 'GET', + 'url' => 'http://krcs.kugou.com/search', + 'body' => array( + 'keyword' => '%20-%20', + 'ver' => 1, + 'hash' => $id, + 'client' => 'mobi', + 'man' => 'yes', + ), + 'decode' => 'kugou_lyric', + ); + break; + case 'baidu': + $api = array( + 'method' => 'GET', + 'url' => 'http://musicapi.taihe.com/v1/restserver/ting', + 'body' => array( + 'from' => 'qianqianmini', + 'method' => 'baidu.ting.song.lry', + 'songid' => $id, + 'platform' => 'darwin', + 'version' => '1.0.0', + ), + 'decode' => 'baidu_lyric', + ); + break; + } + + return $this->exec($api); + } + + public function pic($id, $size = 300) + { + switch ($this->server) { + case 'netease': + $url = 'https://p3.music.126.net/'.$this->netease_encryptId($id).'/'.$id.'.jpg?param='.$size.'y'.$size; + break; + case 'tencent': + $url = 'https://y.gtimg.cn/music/photo_new/T002R'.$size.'x'.$size.'M000'.$id.'.jpg?max_age=2592000'; + break; + case 'xiami': + $format = $this->format; + $data = $this->format(false)->song($id); + $this->format = $format; + $data = json_decode($data, true); + $url = $data['data']['data']['songDetail']['albumLogo']; + $url = str_replace('http:', 'https:', $url).'@1e_1c_100Q_'.$size.'h_'.$size.'w'; + break; + case 'kugou': + $format = $this->format; + $data = $this->format(false)->song($id); + $this->format = $format; + $data = json_decode($data, true); + $url = $data['imgUrl']; + $url = str_replace('{size}', '400', $url); + break; + case 'baidu': + $format = $this->format; + $data = $this->format(false)->song($id); + $this->format = $format; + $data = json_decode($data, true); + $url = isset($data['songinfo']['pic_radio']) ? $data['songinfo']['pic_radio'] : $data['songinfo']['pic_small']; + break; + } + + return json_encode(array('url' => $url)); + } + + private function curlset() + { + switch ($this->server) { + case 'netease': + return array( + 'Referer' => 'https://music.163.com/', + 'Cookie' => 'appver=1.5.9; os=osx; __remember_me=true; osver=%E7%89%88%E6%9C%AC%2010.13.5%EF%BC%88%E7%89%88%E5%8F%B7%2017F77%EF%BC%89;', + 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/605.1.15 (KHTML, like Gecko)', + 'X-Real-IP' => long2ip(mt_rand(1884815360, 1884890111)), + 'Accept' => '*/*', + 'Accept-Language' => 'zh-CN,zh;q=0.8,gl;q=0.6,zh-TW;q=0.4', + 'Connection' => 'keep-alive', + 'Content-Type' => 'application/x-www-form-urlencoded', + ); + case 'tencent': + return array( + 'Referer' => 'http://y.qq.com', + 'Cookie' => 'pgv_pvi=22038528; pgv_si=s3156287488; pgv_pvid=5535248600; yplayer_open=1; ts_last=y.qq.com/portal/player.html; ts_uid=4847550686; yq_index=0; qqmusic_fromtag=66; player_exist=1', + 'User-Agent' => 'QQ%E9%9F%B3%E4%B9%90/54409 CFNetwork/901.1 Darwin/17.6.0 (x86_64)', + 'Accept' => '*/*', + 'Accept-Language' => 'zh-CN,zh;q=0.8,gl;q=0.6,zh-TW;q=0.4', + 'Connection' => 'keep-alive', + 'Content-Type' => 'application/x-www-form-urlencoded', + ); + case 'xiami': + return array( + 'Cookie' => '_m_h5_tk=15d3402511a022796d88b249f83fb968_1511163656929; _m_h5_tk_enc=b6b3e64d81dae577fc314b5c5692df3c', + 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) XIAMI-MUSIC/3.1.1 Chrome/56.0.2924.87 Electron/1.6.11 Safari/537.36', + 'Accept' => 'application/json', + 'Content-type' => 'application/x-www-form-urlencoded', + 'Accept-Language' => 'zh-CN', + ); + case 'kugou': + return array( + 'User-Agent' => 'IPhone-8990-searchSong', + 'UNI-UserAgent' => 'iOS11.4-Phone8990-1009-0-WiFi', + ); + case 'baidu': + return array( + 'Cookie' => 'BAIDUID='.$this->getRandomHex(32).':FG=1', + 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) baidu-music/1.2.1 Chrome/66.0.3359.181 Electron/3.0.5 Safari/537.36', + 'Accept' => '*/*', + 'Content-type' => 'application/json;charset=UTF-8', + 'Accept-Language' => 'zh-CN', + ); + } + } + + private function getRandomHex($length) + { + if (function_exists('random_bytes')) { + return bin2hex(random_bytes($length / 2)); + } + if (function_exists('mcrypt_create_iv')) { + return bin2hex(mcrypt_create_iv($length / 2, MCRYPT_DEV_URANDOM)); + } + if (function_exists('openssl_random_pseudo_bytes')) { + return bin2hex(openssl_random_pseudo_bytes($length / 2)); + } + } + + private function bchexdec($hex) + { + $dec = 0; + $len = strlen($hex); + for ($i = 1; $i <= $len; $i++) { + $dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i)))); + } + + return $dec; + } + + private function bcdechex($dec) + { + $hex = ''; + do { + $last = bcmod($dec, 16); + $hex = dechex($last).$hex; + $dec = bcdiv(bcsub($dec, $last), 16); + } while ($dec > 0); + + return $hex; + } + + private function str2hex($string) + { + $hex = ''; + for ($i = 0; $i < strlen($string); $i++) { + $ord = ord($string[$i]); + $hexCode = dechex($ord); + $hex .= substr('0'.$hexCode, -2); + } + + return $hex; + } + + private function netease_AESCBC($api) + { + $modulus = '157794750267131502212476817800345498121872783333389747424011531025366277535262539913701806290766479189477533597854989606803194253978660329941980786072432806427833685472618792592200595694346872951301770580765135349259590167490536138082469680638514416594216629258349130257685001248172188325316586707301643237607'; + $pubkey = '65537'; + $nonce = '0CoJUm6Qyw8W8jud'; + $vi = '0102030405060708'; + + if (extension_loaded('bcmath')) { + $skey = $this->getRandomHex(16); + } else { + $skey = 'B3v3kH4vRPWRJFfH'; + } + + $body = json_encode($api['body']); + + if (function_exists('openssl_encrypt')) { + $body = openssl_encrypt($body, 'aes-128-cbc', $nonce, false, $vi); + $body = openssl_encrypt($body, 'aes-128-cbc', $skey, false, $vi); + } else { + $pad = 16 - (strlen($body) % 16); + $body = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $nonce, $body.str_repeat(chr($pad), $pad), MCRYPT_MODE_CBC, $vi)); + $pad = 16 - (strlen($body) % 16); + $body = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $skey, $body.str_repeat(chr($pad), $pad), MCRYPT_MODE_CBC, $vi)); + } + + if (extension_loaded('bcmath')) { + $skey = strrev(utf8_encode($skey)); + $skey = $this->bchexdec($this->str2hex($skey)); + $skey = bcpowmod($skey, $pubkey, $modulus); + $skey = $this->bcdechex($skey); + $skey = str_pad($skey, 256, '0', STR_PAD_LEFT); + } else { + $skey = '85302b818aea19b68db899c25dac229412d9bba9b3fcfe4f714dc016bc1686fc446a08844b1f8327fd9cb623cc189be00c5a365ac835e93d4858ee66f43fdc59e32aaed3ef24f0675d70172ef688d376a4807228c55583fe5bac647d10ecef15220feef61477c28cae8406f6f9896ed329d6db9f88757e31848a6c2ce2f94308'; + } + + $api['url'] = str_replace('/api/', '/weapi/', $api['url']); + $api['body'] = array( + 'params' => $body, + 'encSecKey' => $skey, + ); + + return $api; + } + + private function baidu_AESCBC($api) + { + $key = 'DBEECF8C50FD160E'; + $vi = '1231021386755796'; + + $data = 'songid='.$api['body']['songid'].'&ts='.intval(microtime(true) * 1000); + + if (function_exists('openssl_encrypt')) { + $data = openssl_encrypt($data, 'aes-128-cbc', $key, false, $vi); + } else { + $pad = 16 - (strlen($data) % 16); + $data = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data.str_repeat(chr($pad), $pad), MCRYPT_MODE_CBC, $vi)); + } + + $api['body']['e'] = $data; + + return $api; + } + + private function xiami_sign($api) + { + $data = $this->curl('https://acs.m.xiami.com/h5/mtop.alimusic.recommend.songservice.getdailysongs/1.0/?appKey=12574478&t=1560663823000&dataType=json&data=%7B%22requestStr%22%3A%22%7B%5C%22header%5C%22%3A%7B%5C%22platformId%5C%22%3A%5C%22mac%5C%22%7D%2C%5C%22model%5C%22%3A%5B%5D%7D%22%7D&api=mtop.alimusic.recommend.songservice.getdailysongs&v=1.0&type=originaljson&sign=22ad1377ee193f3e2772c17c6192b17c', null, 1); + preg_match_all('/_m_h5[^;]+/', $data->raw, $match); + $this->header['Cookie'] = $match[0][0].'; '.$match[0][1]; + $data = json_encode(array( + 'requestStr' => json_encode(array( + 'header' => array( + 'platformId' => 'mac', + ), + 'model' => $api['body']['data'], + )), + )); + $appkey = '12574478'; + $cookie = $this->header['Cookie']; + preg_match('/_m_h5_tk=([^_]+)/', $cookie, $match); + $token = $match[1]; + $t = time() * 1000; + $sign = md5(sprintf('%s&%s&%s&%s', $token, $t, $appkey, $data)); + $api['body'] = array( + 'appKey' => $appkey, + 't' => $t, + 'dataType' => 'json', + 'data' => $data, + 'api' => $api['body']['r'], + 'v' => '1.0', + 'type' => 'originaljson', + 'sign' => $sign, + ); + + return $api; + } + + private function netease_encryptId($id) + { + $magic = str_split('3go8&$8*3*3h0k(2)2'); + $song_id = str_split($id); + for ($i = 0; $i < count($song_id); $i++) { + $song_id[$i] = chr(ord($song_id[$i]) ^ ord($magic[$i % count($magic)])); + } + $result = base64_encode(md5(implode('', $song_id), 1)); + $result = str_replace(array('/', '+'), array('_', '-'), $result); + + return $result; + } + + private function netease_url($result) + { + $data = json_decode($result, true); + if (isset($data['data'][0]['uf']['url'])) { + $data['data'][0]['url'] = $data['data'][0]['uf']['url']; + } + if (isset($data['data'][0]['url'])) { + $url = array( + 'url' => $data['data'][0]['url'], + 'size' => $data['data'][0]['size'], + 'br' => $data['data'][0]['br'] / 1000, + ); + } else { + $url = array( + 'url' => '', + 'size' => 0, + 'br' => -1, + ); + } + + return json_encode($url); + } + + private function tencent_url($result) + { + $data = json_decode($result, true); + $guid = mt_rand() % 10000000000; + + $type = array( + array('size_320mp3', 320, 'M800', 'mp3'), + array('size_192aac', 192, 'C600', 'm4a'), + array('size_128mp3', 128, 'M500', 'mp3'), + array('size_96aac', 96, 'C400', 'm4a'), + array('size_48aac', 48, 'C200', 'm4a'), + array('size_24aac', 24, 'C100', 'm4a'), + ); + + $payload = array( + 'req_0' => array( + 'module' => 'vkey.GetVkeyServer', + 'method' => 'CgiGetVkey', + 'param' => array( + 'guid' => (string) $guid, + 'songmid' => array(), + 'filename' => array(), + 'songtype' => array(), + 'uin' => '0', + 'loginflag' => 1, + 'platform' => '20', + ), + ), + ); + + foreach ($type as $vo) { + $payload['req_0']['param']['songmid'][] = $data['data'][0]['mid']; + $payload['req_0']['param']['filename'][] = $vo[2].$data['data'][0]['file']['media_mid'].'.'.$vo[3]; + $payload['req_0']['param']['songtype'][] = $data['data'][0]['type']; + } + + $api = array( + 'method' => 'GET', + 'url' => 'https://u.y.qq.com/cgi-bin/musicu.fcg', + 'body' => array( + 'format' => 'json', + 'platform' => 'yqq.json', + 'needNewCode' => 0, + 'data' => json_encode($payload), + ), + ); + $response = json_decode($this->exec($api), true); + $vkeys = $response['req_0']['data']['midurlinfo']; + + foreach ($type as $index => $vo) { + if ($data['data'][0]['file'][$vo[0]] && $vo[1] <= $this->temp['br']) { + if (!empty($vkeys[$index]['vkey'])) { + $url = array( + 'url' => $response['req_0']['data']['sip'][0].$vkeys[$index]['purl'], + 'size' => $data['data'][0]['file'][$vo[0]], + 'br' => $vo[1], + ); + break; + } + } + } + if (!isset($url['url'])) { + $url = array( + 'url' => '', + 'size' => 0, + 'br' => -1, + ); + } + + return json_encode($url); + } + + private function xiami_url($result) + { + $data = json_decode($result, true); + + $type = array( + 's' => 740, + 'h' => 320, + 'l' => 128, + 'f' => 64, + 'e' => 32, + ); + $max = 0; + $url = array(); + foreach ($data['data']['data']['songs'][0]['listenFiles'] as $vo) { + if ($type[$vo['quality']] <= $this->temp['br'] && $type[$vo['quality']] > $max) { + $max = $type[$vo['quality']]; + $url = array( + 'url' => $vo['listenFile'], + 'size' => $vo['fileSize'], + 'br' => $type[$vo['quality']], + ); + } + } + if (!isset($url['url'])) { + $url = array( + 'url' => '', + 'size' => 0, + 'br' => -1, + ); + } + + return json_encode($url); + } + + private function kugou_url($result) + { + $data = json_decode($result, true); + + $max = 0; + $url = array(); + foreach ($data['data'][0]['relate_goods'] as $vo) { + if ($vo['info']['bitrate'] <= $this->temp['br'] && $vo['info']['bitrate'] > $max) { + $api = array( + 'method' => 'GET', + 'url' => 'http://trackercdn.kugou.com/i/v2/', + 'body' => array( + 'hash' => $vo['hash'], + 'key' => md5($vo['hash'].'kgcloudv2'), + 'pid' => 3, + 'behavior' => 'play', + 'cmd' => '25', + 'version' => 8990, + ), + ); + $t = json_decode($this->exec($api), true); + if (isset($t['url'])) { + $max = $t['bitRate'] / 1000; + $url = array( + 'url' => reset($t['url']), + 'size' => $t['fileSize'], + 'br' => $t['bitRate'] / 1000, + ); + } + } + } + if (!isset($url['url'])) { + $url = array( + 'url' => '', + 'size' => 0, + 'br' => -1, + ); + } + + return json_encode($url); + } + + private function baidu_url($result) + { + $data = json_decode($result, true); + + $max = 0; + $url = array(); + foreach ($data['songurl']['url'] as $vo) { + if ($vo['file_bitrate'] <= $this->temp['br'] && $vo['file_bitrate'] > $max) { + $url = array( + 'url' => $vo['file_link'], + 'br' => $vo['file_bitrate'], + ); + } + } + if (!isset($url['url'])) { + $url = array( + 'url' => '', + 'br' => -1, + ); + } + + return json_encode($url); + } + + private function netease_lyric($result) + { + $result = json_decode($result, true); + $data = array( + 'lyric' => isset($result['lrc']['lyric']) ? $result['lrc']['lyric'] : '', + 'tlyric' => isset($result['tlyric']['lyric']) ? $result['tlyric']['lyric'] : '', + ); + + return json_encode($data); + } + + private function tencent_lyric($result) + { + $result = substr($result, 18, -1); + $result = json_decode($result, true); + $data = array( + 'lyric' => isset($result['lyric']) ? base64_decode($result['lyric']) : '', + 'tlyric' => isset($result['trans']) ? base64_decode($result['trans']) : '', + ); + + return json_encode($data); + } + + private function xiami_lyric($result) + { + $result = json_decode($result, true); + + if (count($result['data']['data']['lyrics'])) { + $data = $result['data']['data']['lyrics'][0]['content']; + $data = preg_replace('/<[^>]+>/', '', $data); + preg_match_all('/\[([\d:\.]+)\](.*)\s\[x-trans\](.*)/i', $data, $match); + if (count($match[0])) { + for ($i = 0; $i < count($match[0]); $i++) { + $A[] = '['.$match[1][$i].']'.$match[2][$i]; + $B[] = '['.$match[1][$i].']'.$match[3][$i]; + } + $arr = array( + 'lyric' => str_replace($match[0], $A, $data), + 'tlyric' => str_replace($match[0], $B, $data), + ); + } else { + $arr = array( + 'lyric' => $data, + 'tlyric' => '', + ); + } + } else { + $arr = array( + 'lyric' => '', + 'tlyric' => '', + ); + } + + return json_encode($arr); + } + + private function kugou_lyric($result) + { + $result = json_decode($result, true); + $api = array( + 'method' => 'GET', + 'url' => 'http://lyrics.kugou.com/download', + 'body' => array( + 'charset' => 'utf8', + 'accesskey' => $result['candidates'][0]['accesskey'], + 'id' => $result['candidates'][0]['id'], + 'client' => 'mobi', + 'fmt' => 'lrc', + 'ver' => 1, + ), + ); + $data = json_decode($this->exec($api), true); + $arr = array( + 'lyric' => base64_decode($data['content']), + 'tlyric' => '', + ); + + return json_encode($arr); + } + + private function baidu_lyric($result) + { + $result = json_decode($result, true); + $data = array( + 'lyric' => isset($result['lrcContent']) ? $result['lrcContent'] : '', + 'tlyric' => '', + ); + + return json_encode($data); + } + + private function format_netease($data) + { + $result = array( + 'id' => $data['id'], + 'name' => $data['name'], + 'artist' => array(), + 'album' => $data['al']['name'], + 'pic_id' => isset($data['al']['pic_str']) ? $data['al']['pic_str'] : $data['al']['pic'], + 'url_id' => $data['id'], + 'lyric_id' => $data['id'], + 'source' => 'netease', + ); + if (isset($data['al']['picUrl'])) { + preg_match('/\/(\d+)\./', $data['al']['picUrl'], $match); + $result['pic_id'] = $match[1]; + } + foreach ($data['ar'] as $vo) { + $result['artist'][] = $vo['name']; + } + + return $result; + } + + private function format_tencent($data) + { + if (isset($data['musicData'])) { + $data = $data['musicData']; + } + $result = array( + 'id' => $data['mid'], + 'name' => $data['name'], + 'artist' => array(), + 'album' => trim($data['album']['title']), + 'pic_id' => $data['album']['mid'], + 'url_id' => $data['mid'], + 'lyric_id' => $data['mid'], + 'source' => 'tencent', + ); + foreach ($data['singer'] as $vo) { + $result['artist'][] = $vo['name']; + } + + return $result; + } + + private function format_xiami($data) + { + $result = array( + 'id' => $data['songId'], + 'name' => $data['songName'], + 'artist' => array(), + 'album' => $data['albumName'], + 'pic_id' => $data['songId'], + 'url_id' => $data['songId'], + 'lyric_id' => $data['songId'], + 'source' => 'xiami', + ); + foreach ($data['singerVOs'] as $vo) { + $result['artist'][] = $vo['artistName']; + } + + return $result; + } + + private function format_kugou($data) + { + $result = array( + 'id' => $data['hash'], + 'name' => isset($data['filename']) ? $data['filename'] : $data['fileName'], + 'artist' => array(), + 'album' => isset($data['album_name']) ? $data['album_name'] : '', + 'url_id' => $data['hash'], + 'pic_id' => $data['hash'], + 'lyric_id' => $data['hash'], + 'source' => 'kugou', + ); + list($result['artist'], $result['name']) = explode(' - ', $result['name'], 2); + $result['artist'] = explode('、', $result['artist']); + + return $result; + } + + private function format_baidu($data) + { + $result = array( + 'id' => $data['song_id'], + 'name' => $data['title'], + 'artist' => explode(',', $data['author']), + 'album' => $data['album_title'], + 'pic_id' => $data['song_id'], + 'url_id' => $data['song_id'], + 'lyric_id' => $data['song_id'], + 'source' => 'baidu', + ); + + return $result; + } +} diff --git a/inc/classes/QQ.php b/inc/classes/QQ.php new file mode 100644 index 0000000..5e31ade --- /dev/null +++ b/inc/classes/QQ.php @@ -0,0 +1,40 @@ + 200, + 'success' => true, + 'message' => 'success', + 'avatar' => 'https://q.qlogo.cn/headimg_dl?dst_uin=' . $qq . '&spec=100', + 'name' => $name[$qq][6], + ); + } else { + $output = array( + 'status' => 404, + 'success' => false, + 'message' => 'QQ number not exist.' + ); + } + return $output; + } + + public static function get_qq_avatar($encrypted) { + global $sakura_privkey; + if (isset($encrypted)) { + $iv = str_repeat($sakura_privkey, 2); + $encrypted = base64_decode(urldecode($encrypted)); + $qq_number = openssl_decrypt($encrypted, 'aes-128-cbc', $sakura_privkey, 0, $iv); + preg_match('/^\d{3,}$/', $qq_number, $matches); + $imgurl = 'https://q2.qlogo.cn/headimg_dl?dst_uin=' . $matches[0] . '&spec=100'; + return $imgurl; + } + } +} \ No newline at end of file diff --git a/inc/swicher.php b/inc/swicher.php index ad8c560..01378ab 100644 --- a/inc/swicher.php +++ b/inc/swicher.php @@ -67,8 +67,9 @@ mashiro_option.jsdelivr_css_src = "/cd mashiro_option.jsdelivr_css_src = "https://cdn.jsdelivr.net/gh/mashirozx/Sakura@/cdn/css/lib.min.css"; - + mashiro_option.float_player_on = true; +mashiro_option.meting_api_url = ""; mashiro_option.cover_api = ""; diff --git a/js/sakura-app.js b/js/sakura-app.js index eb4c6cb..74c6f00 100644 --- a/js/sakura-app.js +++ b/js/sakura-app.js @@ -819,7 +819,7 @@ if (mashiro_option.float_player_on) { } }); } - var b = 'https://api.i-meto.com/meting/api?server=:server&type=:type&id=:id&r=:r'; + var b = mashiro_option.meting_api_url + '?server=:server&type=:type&id=:id&_wpnonce=' + Poi.nonce; 'undefined' != typeof meting_api && (b = meting_api); for (var f = 0; f < aplayers.length; f++) try { aplayers[f].destroy() @@ -832,7 +832,7 @@ if (mashiro_option.float_player_on) { f = d.dataset.id; if (f) { var g = d.dataset.api || b; - g = g.replace(':server', d.dataset.server), g = g.replace(':type', d.dataset.type), g = g.replace(':id', d.dataset.id), g = g.replace(':auth', d.dataset.auth), g = g.replace(':r', Math.random()); + g = g.replace(':server', d.dataset.server), g = g.replace(':type', d.dataset.type), g = g.replace(':id', d.dataset.id); var h = new XMLHttpRequest; h.onreadystatechange = function () { if (4 === h.readyState && (200 <= h.status && 300 > h.status || 304 === h.status)) { @@ -997,7 +997,7 @@ function load_bangumi() { $('body').on('click', '#bangumi-pagination a', function () { $("#bangumi-pagination a").addClass("loading").text(""); var xhr = new XMLHttpRequest(); - xhr.open('POST', this.href, true); + xhr.open('POST', this.href + "&_wpnonce=" + Poi.nonce, true); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { var html = JSON.parse(xhr.responseText); @@ -1396,7 +1396,7 @@ var home = location.href, $('html').css('overflow-y', 'hidden'); if (mashiro_option.live_search) { var QueryStorage = []; - search_a(Poi.api + "sakura/v1/cache_search/json"); + search_a(Poi.api + "sakura/v1/cache_search/json?_wpnonce=" + Poi.nonce); var otxt = addComment.I("search-input"), list = addComment.I("PostlistBox"), diff --git a/languages/en_US.mo b/languages/en_US.mo index 2bb981d..8f737cb 100644 Binary files a/languages/en_US.mo and b/languages/en_US.mo differ diff --git a/languages/en_US.po b/languages/en_US.po index 1b5dbbb..7a28f35 100644 --- a/languages/en_US.po +++ b/languages/en_US.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: Sakura\n" -"POT-Creation-Date: 2020-04-05 11:52+0800\n" -"PO-Revision-Date: 2020-04-05 11:52+0800\n" +"POT-Creation-Date: 2020-04-06 17:56+0800\n" +"PO-Revision-Date: 2020-04-06 17:56+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: en_US\n" @@ -222,10 +222,6 @@ msgstr "" msgid "page %s " msgstr "" -#: inc/api.php:337 inc/theme_plus.php:727 -msgid "The comment is private" -msgstr "" - #: inc/categories-images.php:45 inc/categories-images.php:66 msgid "category/tag image" msgstr "" @@ -247,6 +243,10 @@ msgstr "" msgid "no image" msgstr "" +#: inc/classes/Cache.php:70 inc/theme_plus.php:727 +msgid "The comment is private" +msgstr "" + #: inc/options-framework.php:182 inc/options-framework.php:183 #: inc/options-framework.php:412 msgid "Sakura Options" @@ -923,7 +923,7 @@ msgstr "" msgid "Whether to turn on the top-feature" msgstr "" -#: options.php:446 options.php:1104 +#: options.php:446 options.php:1126 msgid "Default on" msgstr "" @@ -1380,198 +1380,239 @@ msgid "Footer float music player" msgstr "" #: options.php:926 -msgid "" -"If you don't need the player just leave it blank.Fill in the \"song list\" " -"ID of Netease Cloud Music, eg: https://music.163.com/#/playlist?" -"id=2288037900 The ID is 2288037900" +msgid "Choose which platform you'll use." +msgstr "" + +#: options.php:931 +msgid "Netease Cloud Music (default)" msgstr "" #: options.php:932 -msgid "Version Control" +msgid "Xiami Music" msgstr "" #: options.php:933 +msgid "KuGou Music" +msgstr "" + +#: options.php:934 +msgid "Baidu Music" +msgstr "" + +#: options.php:935 +msgid "QQ Music (may fail) " +msgstr "" + +#: options.php:936 +msgid "Off" +msgstr "" + +#: options.php:940 +msgid "Song list ID" +msgstr "" + +#: options.php:941 +msgid "" +"Fill in the \"song list\" ID, eg: https://music.163.com/#/playlist?" +"id=2288037900 The ID is 2288037900" +msgstr "" + +#: options.php:947 +msgid "Netease Cloud Music cookie" +msgstr "" + +#: options.php:948 +msgid "" +"For Netease Cloud Music, fill in your vip account's cookies if you want to " +"play special tracks.If you don't know what does mean, left it blank." +msgstr "" + +#: options.php:954 +msgid "Version Control" +msgstr "" + +#: options.php:955 msgid "" "Used to update frontend cookies and browser caches, any string can be used" msgstr "" -#: options.php:939 +#: options.php:961 msgid "Enable PJAX (recommand on)" msgstr "" -#: options.php:940 +#: options.php:962 msgid "The principle is the same as Ajax" msgstr "" -#: options.php:946 +#: options.php:968 msgid "Enable NProgress progress bar" msgstr "" -#: options.php:947 options.php:954 options.php:961 +#: options.php:969 options.php:976 options.php:983 msgid "Default off, check on" msgstr "" -#: options.php:953 +#: options.php:975 msgid "Enable sidebar widget" msgstr "" -#: options.php:960 +#: options.php:982 msgid "Enable Announcement" msgstr "" -#: options.php:967 +#: options.php:989 msgid "Announcement content" msgstr "" -#: options.php:968 +#: options.php:990 msgid "" "Announcement content, the text exceeds 142 bytes will be scrolled display " "(mobile device is invalid)" msgstr "" -#: options.php:973 +#: options.php:995 msgid "Bilibili UID" msgstr "" -#: options.php:974 +#: options.php:996 msgid "" "Fill in your UID, eg.https://space.bilibili.com/13972644/, only fill in with " "the number part." msgstr "" -#: options.php:980 +#: options.php:1002 msgid "Bilibili Cookie" msgstr "" -#: options.php:981 +#: options.php:1003 msgid "" "Fill in your Cookies, go to your bilibili homepage, you can get cookies in " "brownser network pannel with pressing F12. If left this blank, you'll not " "get the progress." msgstr "" -#: options.php:986 +#: options.php:1008 msgid "The categories of articles that don't not show on homepage" msgstr "" -#: options.php:987 options.php:994 +#: options.php:1009 options.php:1016 msgid "Fill in category ID, multiple IDs are divided by a comma \",\"" msgstr "" -#: options.php:993 +#: options.php:1015 msgid "Images category" msgstr "" -#: options.php:1000 +#: options.php:1022 msgid "Statistics Interface" msgstr "" -#: options.php:1005 +#: options.php:1027 msgid "" "WP-Statistics plugin (Professional statistics, can exclude invalid access)" msgstr "" -#: options.php:1006 +#: options.php:1028 msgid "Theme built-in (simple statistics, calculate each page access request)" msgstr "" -#: options.php:1010 +#: options.php:1032 msgid "Statistical data display format" msgstr "" -#: options.php:1015 +#: options.php:1037 msgid "23333 Views (default)" msgstr "" -#: options.php:1016 +#: options.php:1038 msgid "23,333 Views (britain)" msgstr "" -#: options.php:1017 +#: options.php:1039 msgid "23 333 Views (french)" msgstr "" -#: options.php:1018 +#: options.php:1040 msgid "23k Views (chinese)" msgstr "" -#: options.php:1022 +#: options.php:1044 msgid "Gravatar avatar proxy" msgstr "" -#: options.php:1023 +#: options.php:1045 msgid "" "A front-ed proxy for Gravatar, eg. gravatar.2heng.xin/avatar . Leave it " "blank if you do not need." msgstr "" -#: options.php:1029 +#: options.php:1051 msgid "Comment image upload API" msgstr "" -#: options.php:1034 +#: options.php:1056 msgid "Imgur (https://imgur.com)" msgstr "" -#: options.php:1035 +#: options.php:1057 msgid "SM.MS (https://sm.ms)" msgstr "" -#: options.php:1036 +#: options.php:1058 msgid "Chevereto (https://chevereto.com)" msgstr "" -#: options.php:1040 +#: options.php:1062 msgid "Imgur Client ID" msgstr "" -#: options.php:1041 +#: options.php:1063 msgid "" "Register your application here, note we only need the Client ID here." msgstr "" -#: options.php:1047 +#: options.php:1069 msgid "SM.MS Secret Token" msgstr "" -#: options.php:1048 +#: options.php:1070 msgid "" "Register your application here." msgstr "" -#: options.php:1054 +#: options.php:1076 msgid "Chevereto API v1 key" msgstr "" -#: options.php:1055 +#: options.php:1077 msgid "Get your API key here: " msgstr "" -#: options.php:1061 +#: options.php:1083 msgid "Chevereto URL" msgstr "" -#: options.php:1062 +#: options.php:1084 msgid "" "Your Chevereto homepage url, no slash in the end, eg. https://your.cherverto." "com" msgstr "" -#: options.php:1068 +#: options.php:1090 msgid "Comment images proxy" msgstr "" -#: options.php:1069 +#: options.php:1091 msgid "" "A front-ed proxy for the uploaded images. Leave it blank if you do not need." msgstr "" -#: options.php:1075 +#: options.php:1097 msgid "Imgur upload proxy" msgstr "" -#: options.php:1076 +#: options.php:1098 msgid "" "A back-ed proxy to upload images. You may set a self hosted proxy with " "Nginx, following my 】" msgstr "" -#: options.php:1082 +#: options.php:1104 msgid "Enable live search" msgstr "" -#: options.php:1083 +#: options.php:1105 msgid "" "Real-time search in the foreground, call the Rest API to update the cache " "every hour, you can manually set the cache time in api.php" msgstr "" -#: options.php:1089 +#: options.php:1111 msgid "Include comments in live search" msgstr "" -#: options.php:1090 +#: options.php:1112 msgid "" "Search for comments in real-time search (not recommended if there are too " "many comments on the site)" msgstr "" -#: options.php:1096 +#: options.php:1118 msgid "Enable baguetteBox" msgstr "" -#: options.php:1097 +#: options.php:1119 msgid "" "Default off,please read wiki" msgstr "" -#: options.php:1103 +#: options.php:1125 msgid "Enable lazyload in posts" msgstr "" -#: options.php:1110 +#: options.php:1132 msgid "lazyload spinner" msgstr "" -#: options.php:1111 +#: options.php:1133 msgid "The placeholder to display when the image loads, fill in the image url" msgstr "" -#: options.php:1117 +#: options.php:1139 msgid "Whether to enable the clipboard copyright" msgstr "" -#: options.php:1118 +#: options.php:1140 msgid "" "Automatically add a copyright to the clipboard when copying more than 30 " "bytes, which is enabled by default." msgstr "" -#: options.php:1124 +#: options.php:1146 msgid "Email address prefix" msgstr "" -#: options.php:1125 +#: options.php:1147 msgid "" "For sending system mail, the sender address displayed in the user's mailbox, " "do not use Chinese, the default system email address is bibi@your_domain_name" msgstr "" -#: options.php:1131 +#: options.php:1153 msgid "Comments reply notification" msgstr "" -#: options.php:1132 +#: options.php:1154 msgid "" "WordPress will use email to notify users when their comments receive a reply " "by default. Tick this item allows users to set their own comments reply " "notification" msgstr "" -#: options.php:1138 +#: options.php:1160 msgid "Administrator comment notification" msgstr "" -#: options.php:1139 +#: options.php:1161 msgid "" "Whether to use email notification when the administrator's comments receive " "a reply" msgstr "" -#: options.php:1145 +#: options.php:1167 msgid "Enable private comment" msgstr "" -#: options.php:1146 +#: options.php:1168 msgid "Allow users to set their own comments to be invisible to others" msgstr "" -#: options.php:1152 +#: options.php:1174 msgid "Human verification" msgstr "" -#: options.php:1153 +#: options.php:1175 msgid "Enable human verification" msgstr "" -#: options.php:1159 +#: options.php:1181 msgid "QQ avatar link encryption" msgstr "" -#: options.php:1160 +#: options.php:1182 msgid "Do not display the user's qq avatar links directly." msgstr "" -#: options.php:1165 +#: options.php:1187 msgid "Off (default)" msgstr "" -#: options.php:1166 +#: options.php:1188 msgid "use redirect (general security)" msgstr "" -#: options.php:1167 +#: options.php:1189 msgid "fetch data at backend (high security)" msgstr "" -#: options.php:1168 +#: options.php:1190 msgid "fetch data at backend (high security,slow)" msgstr "" -#: options.php:1172 +#: options.php:1194 msgid "Comment UA infomation" msgstr "" -#: options.php:1173 +#: options.php:1195 msgid "" "Check to enable, display the user's browser, operating system information" msgstr "" -#: options.php:1179 +#: options.php:1201 msgid "Enable disqus" msgstr "" -#: options.php:1180 +#: options.php:1202 msgid "Enable disqus for comment" msgstr "" -#: options.php:1186 +#: options.php:1208 msgid "Time Zone adjustment" msgstr "" -#: options.php:1187 +#: options.php:1209 msgid "" "If the comment has a time difference problem adjust here, fill in an " "integer, the calculation method: actual_time = display_error_time - " @@ -1784,7 +1825,7 @@ msgstr "" msgid "Attribution-NonCommercial-ShareAlike 4.0 International" msgstr "" -#: user/page-bangumi.php:27 +#: user/page-bangumi.php:30 msgid "Please fill in the Bilibili UID in Sakura Options." msgstr "" diff --git a/languages/sakura.pot b/languages/sakura.pot index 76785fa..8137f77 100644 --- a/languages/sakura.pot +++ b/languages/sakura.pot @@ -3,7 +3,7 @@ msgid "" msgstr "" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" "Project-Id-Version: Sakura\n" -"POT-Creation-Date: 2020-04-05 11:50+0800\n" +"POT-Creation-Date: 2020-04-06 17:55+0800\n" "PO-Revision-Date: 2019-11-01 14:27+0800\n" "Last-Translator: \n" "Language-Team: \n" @@ -220,10 +220,6 @@ msgstr "" msgid "page %s " msgstr "" -#: inc/api.php:337 inc/theme_plus.php:727 -msgid "The comment is private" -msgstr "" - #: inc/categories-images.php:45 inc/categories-images.php:66 msgid "category/tag image" msgstr "" @@ -244,6 +240,10 @@ msgstr "" msgid "no image" msgstr "" +#: inc/classes/Cache.php:70 inc/theme_plus.php:727 +msgid "The comment is private" +msgstr "" + #: inc/options-framework.php:182 inc/options-framework.php:183 inc/options-framework.php:412 msgid "Sakura Options" msgstr "" @@ -911,7 +911,7 @@ msgstr "" msgid "Whether to turn on the top-feature" msgstr "" -#: options.php:446 options.php:1104 +#: options.php:446 options.php:1126 msgid "Default on" msgstr "" @@ -1359,189 +1359,231 @@ msgid "Footer float music player" msgstr "" #: options.php:926 -msgid "" -"If you don't need the player just leave it blank.Fill in the \"song list\" ID of Netease Cloud " -"Music, eg: https://music.163.com/#/playlist?id=2288037900 The ID is 2288037900" +msgid "Choose which platform you'll use." +msgstr "" + +#: options.php:931 +msgid "Netease Cloud Music (default)" msgstr "" #: options.php:932 -msgid "Version Control" +msgid "Xiami Music" msgstr "" #: options.php:933 -msgid "Used to update frontend cookies and browser caches, any string can be used" +msgid "KuGou Music" msgstr "" -#: options.php:939 -msgid "Enable PJAX (recommand on)" +#: options.php:934 +msgid "Baidu Music" +msgstr "" + +#: options.php:935 +msgid "QQ Music (may fail) " +msgstr "" + +#: options.php:936 +msgid "Off" msgstr "" #: options.php:940 +msgid "Song list ID" +msgstr "" + +#: options.php:941 +msgid "" +"Fill in the \"song list\" ID, eg: https://music.163.com/#/playlist?id=2288037900 The ID is " +"2288037900" +msgstr "" + +#: options.php:947 +msgid "Netease Cloud Music cookie" +msgstr "" + +#: options.php:948 +msgid "" +"For Netease Cloud Music, fill in your vip account's cookies if you want to play special tracks." +"If you don't know what does mean, left it blank." +msgstr "" + +#: options.php:954 +msgid "Version Control" +msgstr "" + +#: options.php:955 +msgid "Used to update frontend cookies and browser caches, any string can be used" +msgstr "" + +#: options.php:961 +msgid "Enable PJAX (recommand on)" +msgstr "" + +#: options.php:962 msgid "The principle is the same as Ajax" msgstr "" -#: options.php:946 +#: options.php:968 msgid "Enable NProgress progress bar" msgstr "" -#: options.php:947 options.php:954 options.php:961 +#: options.php:969 options.php:976 options.php:983 msgid "Default off, check on" msgstr "" -#: options.php:953 +#: options.php:975 msgid "Enable sidebar widget" msgstr "" -#: options.php:960 +#: options.php:982 msgid "Enable Announcement" msgstr "" -#: options.php:967 +#: options.php:989 msgid "Announcement content" msgstr "" -#: options.php:968 +#: options.php:990 msgid "" "Announcement content, the text exceeds 142 bytes will be scrolled display (mobile device is " "invalid)" msgstr "" -#: options.php:973 +#: options.php:995 msgid "Bilibili UID" msgstr "" -#: options.php:974 +#: options.php:996 msgid "" "Fill in your UID, eg.https://space.bilibili.com/13972644/, only fill in with the number part." msgstr "" -#: options.php:980 +#: options.php:1002 msgid "Bilibili Cookie" msgstr "" -#: options.php:981 +#: options.php:1003 msgid "" "Fill in your Cookies, go to your bilibili homepage, you can get cookies in brownser network " "pannel with pressing F12. If left this blank, you'll not get the progress." msgstr "" -#: options.php:986 +#: options.php:1008 msgid "The categories of articles that don't not show on homepage" msgstr "" -#: options.php:987 options.php:994 +#: options.php:1009 options.php:1016 msgid "Fill in category ID, multiple IDs are divided by a comma \",\"" msgstr "" -#: options.php:993 +#: options.php:1015 msgid "Images category" msgstr "" -#: options.php:1000 +#: options.php:1022 msgid "Statistics Interface" msgstr "" -#: options.php:1005 +#: options.php:1027 msgid "WP-Statistics plugin (Professional statistics, can exclude invalid access)" msgstr "" -#: options.php:1006 +#: options.php:1028 msgid "Theme built-in (simple statistics, calculate each page access request)" msgstr "" -#: options.php:1010 +#: options.php:1032 msgid "Statistical data display format" msgstr "" -#: options.php:1015 +#: options.php:1037 msgid "23333 Views (default)" msgstr "" -#: options.php:1016 +#: options.php:1038 msgid "23,333 Views (britain)" msgstr "" -#: options.php:1017 +#: options.php:1039 msgid "23 333 Views (french)" msgstr "" -#: options.php:1018 +#: options.php:1040 msgid "23k Views (chinese)" msgstr "" -#: options.php:1022 +#: options.php:1044 msgid "Gravatar avatar proxy" msgstr "" -#: options.php:1023 +#: options.php:1045 msgid "" "A front-ed proxy for Gravatar, eg. gravatar.2heng.xin/avatar . Leave it blank if you do not " "need." msgstr "" -#: options.php:1029 +#: options.php:1051 msgid "Comment image upload API" msgstr "" -#: options.php:1034 +#: options.php:1056 msgid "Imgur (https://imgur.com)" msgstr "" -#: options.php:1035 +#: options.php:1057 msgid "SM.MS (https://sm.ms)" msgstr "" -#: options.php:1036 +#: options.php:1058 msgid "Chevereto (https://chevereto.com)" msgstr "" -#: options.php:1040 +#: options.php:1062 msgid "Imgur Client ID" msgstr "" -#: options.php:1041 +#: options.php:1063 msgid "" "Register your application here, note we " "only need the Client ID here." msgstr "" -#: options.php:1047 +#: options.php:1069 msgid "SM.MS Secret Token" msgstr "" -#: options.php:1048 +#: options.php:1070 msgid "Register your application here." msgstr "" -#: options.php:1054 +#: options.php:1076 msgid "Chevereto API v1 key" msgstr "" -#: options.php:1055 +#: options.php:1077 msgid "Get your API key here: " msgstr "" -#: options.php:1061 +#: options.php:1083 msgid "Chevereto URL" msgstr "" -#: options.php:1062 +#: options.php:1084 msgid "Your Chevereto homepage url, no slash in the end, eg. https://your.cherverto.com" msgstr "" -#: options.php:1068 +#: options.php:1090 msgid "Comment images proxy" msgstr "" -#: options.php:1069 +#: options.php:1091 msgid "A front-ed proxy for the uploaded images. Leave it blank if you do not need." msgstr "" -#: options.php:1075 +#: options.php:1097 msgid "Imgur upload proxy" msgstr "" -#: options.php:1076 +#: options.php:1098 msgid "" "A back-ed proxy to upload images. You may set a self hosted proxy with Nginx, following my turtal. " @@ -1550,146 +1592,146 @@ msgid "" "】" msgstr "" -#: options.php:1082 +#: options.php:1104 msgid "Enable live search" msgstr "" -#: options.php:1083 +#: options.php:1105 msgid "" "Real-time search in the foreground, call the Rest API to update the cache every hour, you can " "manually set the cache time in api.php" msgstr "" -#: options.php:1089 +#: options.php:1111 msgid "Include comments in live search" msgstr "" -#: options.php:1090 +#: options.php:1112 msgid "" "Search for comments in real-time search (not recommended if there are too many comments on the " "site)" msgstr "" -#: options.php:1096 +#: options.php:1118 msgid "Enable baguetteBox" msgstr "" -#: options.php:1097 +#: options.php:1119 msgid "" "Default off,please read wiki" msgstr "" -#: options.php:1103 +#: options.php:1125 msgid "Enable lazyload in posts" msgstr "" -#: options.php:1110 +#: options.php:1132 msgid "lazyload spinner" msgstr "" -#: options.php:1111 +#: options.php:1133 msgid "The placeholder to display when the image loads, fill in the image url" msgstr "" -#: options.php:1117 +#: options.php:1139 msgid "Whether to enable the clipboard copyright" msgstr "" -#: options.php:1118 +#: options.php:1140 msgid "" "Automatically add a copyright to the clipboard when copying more than 30 bytes, which is " "enabled by default." msgstr "" -#: options.php:1124 +#: options.php:1146 msgid "Email address prefix" msgstr "" -#: options.php:1125 +#: options.php:1147 msgid "" "For sending system mail, the sender address displayed in the user's mailbox, do not use " "Chinese, the default system email address is bibi@your_domain_name" msgstr "" -#: options.php:1131 +#: options.php:1153 msgid "Comments reply notification" msgstr "" -#: options.php:1132 +#: options.php:1154 msgid "" "WordPress will use email to notify users when their comments receive a reply by default. Tick " "this item allows users to set their own comments reply notification" msgstr "" -#: options.php:1138 +#: options.php:1160 msgid "Administrator comment notification" msgstr "" -#: options.php:1139 +#: options.php:1161 msgid "Whether to use email notification when the administrator's comments receive a reply" msgstr "" -#: options.php:1145 +#: options.php:1167 msgid "Enable private comment" msgstr "" -#: options.php:1146 +#: options.php:1168 msgid "Allow users to set their own comments to be invisible to others" msgstr "" -#: options.php:1152 +#: options.php:1174 msgid "Human verification" msgstr "" -#: options.php:1153 +#: options.php:1175 msgid "Enable human verification" msgstr "" -#: options.php:1159 +#: options.php:1181 msgid "QQ avatar link encryption" msgstr "" -#: options.php:1160 +#: options.php:1182 msgid "Do not display the user's qq avatar links directly." msgstr "" -#: options.php:1165 +#: options.php:1187 msgid "Off (default)" msgstr "" -#: options.php:1166 +#: options.php:1188 msgid "use redirect (general security)" msgstr "" -#: options.php:1167 +#: options.php:1189 msgid "fetch data at backend (high security)" msgstr "" -#: options.php:1168 +#: options.php:1190 msgid "fetch data at backend (high security,slow)" msgstr "" -#: options.php:1172 +#: options.php:1194 msgid "Comment UA infomation" msgstr "" -#: options.php:1173 +#: options.php:1195 msgid "Check to enable, display the user's browser, operating system information" msgstr "" -#: options.php:1179 +#: options.php:1201 msgid "Enable disqus" msgstr "" -#: options.php:1180 +#: options.php:1202 msgid "Enable disqus for comment" msgstr "" -#: options.php:1186 +#: options.php:1208 msgid "Time Zone adjustment" msgstr "" -#: options.php:1187 +#: options.php:1209 msgid "" "If the comment has a time difference problem adjust here, fill in an integer, the calculation " "method: actual_time = display_error_time - the_integer_you_entered (unit: hour)" @@ -1743,7 +1785,7 @@ msgstr "" msgid "Attribution-NonCommercial-ShareAlike 4.0 International" msgstr "" -#: user/page-bangumi.php:27 +#: user/page-bangumi.php:30 msgid "Please fill in the Bilibili UID in Sakura Options." msgstr "" diff --git a/languages/zh_CN.mo b/languages/zh_CN.mo index 5ed8c74..cb60c6c 100644 Binary files a/languages/zh_CN.mo and b/languages/zh_CN.mo differ diff --git a/languages/zh_CN.po b/languages/zh_CN.po index 00c3ef7..9e9ae71 100644 --- a/languages/zh_CN.po +++ b/languages/zh_CN.po @@ -1,8 +1,8 @@ msgid "" msgstr "" "Project-Id-Version: Sakura\n" -"POT-Creation-Date: 2020-04-05 11:52+0800\n" -"PO-Revision-Date: 2020-04-05 11:52+0800\n" +"POT-Creation-Date: 2020-04-06 17:55+0800\n" +"PO-Revision-Date: 2020-04-06 17:56+0800\n" "Last-Translator: \n" "Language-Team: \n" "Language: zh_CN\n" @@ -227,10 +227,6 @@ msgstr "" msgid "page %s " msgstr "第 %s 页 " -#: inc/api.php:337 inc/theme_plus.php:727 -msgid "The comment is private" -msgstr "该评论为私密评论" - #: inc/categories-images.php:45 inc/categories-images.php:66 msgid "category/tag image" msgstr "分类/标签图像" @@ -252,6 +248,10 @@ msgstr "图像" msgid "no image" msgstr "暂无" +#: inc/classes/Cache.php:70 inc/theme_plus.php:727 +msgid "The comment is private" +msgstr "该评论为私密评论" + #: inc/options-framework.php:182 inc/options-framework.php:183 #: inc/options-framework.php:412 msgid "Sakura Options" @@ -938,7 +938,7 @@ msgstr "点点" msgid "Whether to turn on the top-feature" msgstr "是否开启聚焦" -#: options.php:446 options.php:1104 +#: options.php:446 options.php:1126 msgid "Default on" msgstr "默认开启" @@ -1412,52 +1412,95 @@ msgid "Footer float music player" msgstr "页脚悬浮播放器" #: options.php:926 -msgid "" -"If you don't need the player just leave it blank.Fill in the \"song list\" " -"ID of Netease Cloud Music, eg: https://music.163.com/#/playlist?" -"id=2288037900 The ID is 2288037900" -msgstr "" -"如果不需要播放器留空即可。填写网易云音乐的「歌单」ID,eg:https://music.163." -"com/#/playlist?id=2288037900的ID是2288037900" +msgid "Choose which platform you'll use." +msgstr "选择你要使用的平台。" + +#: options.php:931 +msgid "Netease Cloud Music (default)" +msgstr "网易云音乐(默认)" #: options.php:932 +msgid "Xiami Music" +msgstr "虾米音乐" + +#: options.php:933 +msgid "KuGou Music" +msgstr "酷狗音乐" + +#: options.php:934 +msgid "Baidu Music" +msgstr "百度音乐" + +#: options.php:935 +msgid "QQ Music (may fail) " +msgstr "QQ音乐(可能解析失败) " + +#: options.php:936 +msgid "Off" +msgstr "关闭" + +#: options.php:940 +msgid "Song list ID" +msgstr "「歌单」ID" + +#: options.php:941 +msgid "" +"Fill in the \"song list\" ID, eg: https://music.163.com/#/playlist?" +"id=2288037900 The ID is 2288037900" +msgstr "" +"填写「歌单」ID,eg:https://music.163.com/#/playlist?id=2288037900的ID是" +"2288037900" + +#: options.php:947 +msgid "Netease Cloud Music cookie" +msgstr "网易云音乐 Cookies" + +#: options.php:948 +msgid "" +"For Netease Cloud Music, fill in your vip account's cookies if you want to " +"play special tracks.If you don't know what does mean, left it blank." +msgstr "" +"针对网易云音乐,如果你想播放特殊曲目,填入你的vip帐号Cookies。如果不知道这" +"是什么意思,忽略即可。" + +#: options.php:954 msgid "Version Control" msgstr "版本控制" -#: options.php:933 +#: options.php:955 msgid "" "Used to update frontend cookies and browser caches, any string can be used" msgstr "用于更新前端 cookie 及浏览器缓存,可使用任意字符串" -#: options.php:939 +#: options.php:961 msgid "Enable PJAX (recommand on)" msgstr "开启PJAX局部刷新(建议开启)" -#: options.php:940 +#: options.php:962 msgid "The principle is the same as Ajax" msgstr "原理与Ajax相同" -#: options.php:946 +#: options.php:968 msgid "Enable NProgress progress bar" msgstr "开启NProgress加载进度条" -#: options.php:947 options.php:954 options.php:961 +#: options.php:969 options.php:976 options.php:983 msgid "Default off, check on" msgstr "默认不开启,勾选开启" -#: options.php:953 +#: options.php:975 msgid "Enable sidebar widget" msgstr "支持侧栏小部件" -#: options.php:960 +#: options.php:982 msgid "Enable Announcement" msgstr "开启公告" -#: options.php:967 +#: options.php:989 msgid "Announcement content" msgstr "公告内容" -#: options.php:968 +#: options.php:990 msgid "" "Announcement content, the text exceeds 142 bytes will be scrolled display " "(mobile device is invalid)" @@ -1465,22 +1508,22 @@ msgstr "" "公告内容,文字超出142个字节将会被滚动显示(移动端无效),一个汉字 = 3字节,一" "个字母 = 1字节,自己计算吧" -#: options.php:973 +#: options.php:995 msgid "Bilibili UID" msgstr "" -#: options.php:974 +#: options.php:996 msgid "" "Fill in your UID, eg.https://space.bilibili.com/13972644/, only fill in with " "the number part." msgstr "" "填写你的UID,,例如:https://space.bilibili.com/13972644/,只需填写数字部分。" -#: options.php:980 +#: options.php:1002 msgid "Bilibili Cookie" msgstr "" -#: options.php:981 +#: options.php:1003 msgid "" "Fill in your Cookies, go to your bilibili homepage, you can get cookies in " "brownser network pannel with pressing F12. If left this blank, you'll not " @@ -1489,56 +1532,56 @@ msgstr "" "填写你的帐号Cookies。F12打开浏览器网络面板,前往你的B站主页获取Cookies。如果" "留空,将不会显示追番进度。" -#: options.php:986 +#: options.php:1008 msgid "The categories of articles that don't not show on homepage" msgstr "首页不显示的分类文章" -#: options.php:987 options.php:994 +#: options.php:1009 options.php:1016 msgid "Fill in category ID, multiple IDs are divided by a comma \",\"" msgstr "填写分类ID,多个用英文“ , ”分开" -#: options.php:993 +#: options.php:1015 msgid "Images category" msgstr "图片展示分类" -#: options.php:1000 +#: options.php:1022 msgid "Statistics Interface" msgstr "统计接口" -#: options.php:1005 +#: options.php:1027 msgid "" "WP-Statistics plugin (Professional statistics, can exclude invalid access)" msgstr "WP-Statistics 插件(专业性统计,可排除无效访问)" -#: options.php:1006 +#: options.php:1028 msgid "Theme built-in (simple statistics, calculate each page access request)" msgstr "主题内建(简单的统计,计算每一次页面访问请求)" -#: options.php:1010 +#: options.php:1032 msgid "Statistical data display format" msgstr "统计数据显示格式" -#: options.php:1015 +#: options.php:1037 msgid "23333 Views (default)" msgstr "23333 次访问(默认)" -#: options.php:1016 +#: options.php:1038 msgid "23,333 Views (britain)" msgstr "23,333 次访问(英式)" -#: options.php:1017 +#: options.php:1039 msgid "23 333 Views (french)" msgstr "23 333 次访问(法式)" -#: options.php:1018 +#: options.php:1040 msgid "23k Views (chinese)" msgstr "23k 次访问(中式)" -#: options.php:1022 +#: options.php:1044 msgid "Gravatar avatar proxy" msgstr "Gravatar头像代理" -#: options.php:1023 +#: options.php:1045 msgid "" "A front-ed proxy for Gravatar, eg. gravatar.2heng.xin/avatar . Leave it " "blank if you do not need." @@ -1546,27 +1589,27 @@ msgstr "" "填写Gravatar头像的代理地址,例如:gravatar.2heng.xin/avatar。留空则不使用代" "理。" -#: options.php:1029 +#: options.php:1051 msgid "Comment image upload API" msgstr "评论上传图片接口" -#: options.php:1034 +#: options.php:1056 msgid "Imgur (https://imgur.com)" msgstr "" -#: options.php:1035 +#: options.php:1057 msgid "SM.MS (https://sm.ms)" msgstr "" -#: options.php:1036 +#: options.php:1058 msgid "Chevereto (https://chevereto.com)" msgstr "" -#: options.php:1040 +#: options.php:1062 msgid "Imgur Client ID" msgstr "" -#: options.php:1041 +#: options.php:1063 msgid "" "Register your application here, note we only need the Client ID here." @@ -1574,48 +1617,48 @@ msgstr "" "在这里注册你的 " "application , 注意此处只需要填写 Client ID." -#: options.php:1047 +#: options.php:1069 msgid "SM.MS Secret Token" msgstr "" -#: options.php:1048 +#: options.php:1070 msgid "" "Register your application here." msgstr "在这里获取 key." -#: options.php:1054 +#: options.php:1076 msgid "Chevereto API v1 key" msgstr "" -#: options.php:1055 +#: options.php:1077 msgid "Get your API key here: " msgstr "在这里获取你的 API key: " -#: options.php:1061 +#: options.php:1083 msgid "Chevereto URL" msgstr "" -#: options.php:1062 +#: options.php:1084 msgid "" "Your Chevereto homepage url, no slash in the end, eg. https://your.cherverto." "com" msgstr "" "你的 Chevereto 首页 url, 注意结尾没有 /, 例如:https://your.cherverto.com" -#: options.php:1068 +#: options.php:1090 msgid "Comment images proxy" msgstr "评论图片代理" -#: options.php:1069 +#: options.php:1091 msgid "" "A front-ed proxy for the uploaded images. Leave it blank if you do not need." msgstr "前端显示的图片的代理。" -#: options.php:1075 +#: options.php:1097 msgid "Imgur upload proxy" msgstr "Imgur 上传代理" -#: options.php:1076 +#: options.php:1098 msgid "" "A back-ed proxy to upload images. You may set a self hosted proxy with " "Nginx, following my https://api.imgur.com/3/image/】" -#: options.php:1082 +#: options.php:1104 msgid "Enable live search" msgstr "启用实时搜索" -#: options.php:1083 +#: options.php:1105 msgid "" "Real-time search in the foreground, call the Rest API to update the cache " "every hour, you can manually set the cache time in api.php" @@ -1642,21 +1685,21 @@ msgstr "" "前台实现实时搜索,调用 Rest API 每小时更新一次缓存,可在 api.php 里手动设置缓" "存时间" -#: options.php:1089 +#: options.php:1111 msgid "Include comments in live search" msgstr "实时搜索包含评论" -#: options.php:1090 +#: options.php:1112 msgid "" "Search for comments in real-time search (not recommended if there are too " "many comments on the site)" msgstr "在实时搜索中搜索评论(如果网站评论数量太多不建议开启)" -#: options.php:1096 +#: options.php:1118 msgid "Enable baguetteBox" msgstr "启用 baguetteBox" -#: options.php:1097 +#: options.php:1119 msgid "" "Default off,please read wiki" @@ -1664,33 +1707,33 @@ msgstr "" "默认禁用,请阅" "读说明" -#: options.php:1103 +#: options.php:1125 msgid "Enable lazyload in posts" msgstr "文章内图片启用 lazyload" -#: options.php:1110 +#: options.php:1132 msgid "lazyload spinner" msgstr "lazyload 占位图" -#: options.php:1111 +#: options.php:1133 msgid "The placeholder to display when the image loads, fill in the image url" msgstr "图片加载时要显示的占位图,填写图片 url" -#: options.php:1117 +#: options.php:1139 msgid "Whether to enable the clipboard copyright" msgstr "是否开启剪贴板版权标识" -#: options.php:1118 +#: options.php:1140 msgid "" "Automatically add a copyright to the clipboard when copying more than 30 " "bytes, which is enabled by default." msgstr "复制超过30个字节时自动向剪贴板添加版权标识,默认开启。" -#: options.php:1124 +#: options.php:1146 msgid "Email address prefix" msgstr "发件地址前缀" -#: options.php:1125 +#: options.php:1147 msgid "" "For sending system mail, the sender address displayed in the user's mailbox, " "do not use Chinese, the default system email address is bibi@your_domain_name" @@ -1698,11 +1741,11 @@ msgstr "" "用于发送系统邮件,在用户的邮箱中显示的发件人地址,不要使用中文,默认系统邮件" "地址为 bibi@你的域名" -#: options.php:1131 +#: options.php:1153 msgid "Comments reply notification" msgstr "邮件回复通知" -#: options.php:1132 +#: options.php:1154 msgid "" "WordPress will use email to notify users when their comments receive a reply " "by default. Tick this item allows users to set their own comments reply " @@ -1711,78 +1754,78 @@ msgstr "" "WordPress默认会使用邮件通知用户评论收到回复,开启此项允许用户设置自己的评论收" "到回复时是否使用邮件通知" -#: options.php:1138 +#: options.php:1160 msgid "Administrator comment notification" msgstr "邮件回复通知管理员" -#: options.php:1139 +#: options.php:1161 msgid "" "Whether to use email notification when the administrator's comments receive " "a reply" msgstr "当管理员评论收到回复时是否使用邮件通知" -#: options.php:1145 +#: options.php:1167 msgid "Enable private comment" msgstr "允许私密评论" -#: options.php:1146 +#: options.php:1168 msgid "Allow users to set their own comments to be invisible to others" msgstr "允许用户设置自己的评论对其他人不可见" -#: options.php:1152 +#: options.php:1174 msgid "Human verification" msgstr "机器人验证" -#: options.php:1153 +#: options.php:1175 msgid "Enable human verification" msgstr "开启机器人验证" -#: options.php:1159 +#: options.php:1181 msgid "QQ avatar link encryption" msgstr "QQ头像链接加密" -#: options.php:1160 +#: options.php:1182 msgid "Do not display the user's qq avatar links directly." -msgstr "不直接暴露用户QQ头像链接" +msgstr "不直接暴露用户QQ头像链接。" -#: options.php:1165 +#: options.php:1187 msgid "Off (default)" msgstr "关闭(默认)" -#: options.php:1166 +#: options.php:1188 msgid "use redirect (general security)" msgstr "使用重定向(安全性低)" -#: options.php:1167 +#: options.php:1189 msgid "fetch data at backend (high security)" msgstr "后端获取头像数据(安全性高)" -#: options.php:1168 +#: options.php:1190 msgid "fetch data at backend (high security,slow)" msgstr "后端解析QQ头像接口(安全性高,慢)" -#: options.php:1172 +#: options.php:1194 msgid "Comment UA infomation" msgstr "评论UA信息" -#: options.php:1173 +#: options.php:1195 msgid "" "Check to enable, display the user's browser, operating system information" msgstr "勾选开启,显示用户的浏览器,操作系统信息" -#: options.php:1179 +#: options.php:1201 msgid "Enable disqus" msgstr "开启多说插件支持" -#: options.php:1180 +#: options.php:1202 msgid "Enable disqus for comment" msgstr "多说已经凉了~~" -#: options.php:1186 +#: options.php:1208 msgid "Time Zone adjustment" msgstr "时区调整" -#: options.php:1187 +#: options.php:1209 msgid "" "If the comment has a time difference problem adjust here, fill in an " "integer, the calculation method: actual_time = display_error_time - " @@ -1842,7 +1885,7 @@ msgstr "" msgid "Attribution-NonCommercial-ShareAlike 4.0 International" msgstr "知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议" -#: user/page-bangumi.php:27 +#: user/page-bangumi.php:30 msgid "Please fill in the Bilibili UID in Sakura Options." msgstr "请在后台设置填写 Bilibili UID 后继续。" diff --git a/options.php b/options.php index b1cde48..8624ac3 100644 --- a/options.php +++ b/options.php @@ -923,11 +923,33 @@ function optionsframework_options() $options[] = array( 'name' => __('Footer float music player', 'sakura'), /*页脚悬浮播放器*/ - 'desc' => __('If you don\'t need the player just leave it blank.Fill in the "song list" ID of Netease Cloud Music, eg: https://music.163.com/#/playlist?id=2288037900 The ID is 2288037900', 'sakura'), /*如果不需要播放器留空即可。填写网易云音乐的「歌单」ID,eg:https://music.163.com/#/playlist?id=2288037900的ID是2288037900*/ - 'id' => 'playlist_id', + 'desc' => __('Choose which platform you\'ll use.', 'sakura'), + 'id' => 'aplayer_server', + 'std' => "netease", + 'type' => "select", + 'options' => array( + 'netease' => __('Netease Cloud Music (default)', 'sakura'), + 'xiami' => __('Xiami Music', 'sakura'), + 'kugou' => __('KuGou Music', 'sakura'), + 'baidu' => __('Baidu Music', 'sakura'), + 'tencent' => __('QQ Music (may fail) ', 'sakura'), + 'off' => __('Off', 'sakura'), + )); + + $options[] = array( + 'name' => __('Song list ID', 'sakura'), + 'desc' => __('Fill in the "song list" ID, eg: https://music.163.com/#/playlist?id=2288037900 The ID is 2288037900', 'sakura'), + 'id' => 'aplayer_playlistid', 'std' => '2288037900', 'type' => 'text'); + $options[] = array( + 'name' => __('Netease Cloud Music cookie', 'sakura'), + 'desc' => __('For Netease Cloud Music, fill in your vip account\'s cookies if you want to play special tracks.If you don\'t know what does mean, left it blank.', 'sakura'), + 'id' => 'aplayer_cookie', + 'std' => '', + 'type' => 'textarea'); + $options[] = array( 'name' => __('Version Control', 'sakura'), /*版本控制*/ 'desc' => __('Used to update frontend cookies and browser caches, any string can be used', 'sakura'), /*用于更新前端 cookie 及浏览器缓存,可使用任意字符串*/ diff --git a/style.css b/style.css index 46cb702..3839ddc 100644 --- a/style.css +++ b/style.css @@ -5,7 +5,7 @@ Theme URI: https://github.com/mashirozx/Sakura/ Author: Mashiro, Spirit, Louie, Fuzzz Author URI: http://2heng.xin Description: A wonderful branch of theme Akina -Version: 3.3.7 +Version: 3.3.8 License: GNU General Public License v2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Text Domain: sakura @@ -8721,8 +8721,11 @@ h1[id*=toc-head]::before,h2[id*=toc-head]::before,h3[id*=toc-head]::before,h4[id max-width: 33.3333%; flex: 0 0 33.3333%; } + .bangumi-title { + height: 30%; + } .bangumi-item .bangumi-info{ - height: 50%; + height: 45%; transform: translateY(140%); } } diff --git a/user/page-bangumi.php b/user/page-bangumi.php index cecc06f..bd2b35a 100644 --- a/user/page-bangumi.php +++ b/user/page-bangumi.php @@ -21,7 +21,10 @@ get_header();
- + get_bgm_items(); + ?>