├── Action.php ├── Plugin.php ├── README.md ├── css └── css.css └── js └── js.js /Action.php: -------------------------------------------------------------------------------- 1 | userName = $_userName; 51 | $this->passWord = $_passWord; 52 | //登陆api 53 | $this->loginApi = BangumiAPI::$apiUrl . "/auth?source=" . BangumiAPI::$appName; 54 | //用户id为空或auth为空 55 | if ($this->userID == "" || $this->authEncode == ""){ 56 | //登陆post字符串 57 | $postData = array('username' => $this->userName , 'password' => $this->passWord); 58 | //获取登陆返回json 59 | $userContent = BangumiAPI::curl_post_contents($this->loginApi,$postData); 60 | //json to object 61 | $userData = json_decode($userContent); 62 | //存在error属性 63 | if (property_exists($userData, "error")) { 64 | //输出错误信息 65 | echo "登陆错误:" . $userData->error; 66 | //程序返回 67 | return; 68 | } 69 | //初始化 70 | $this->userID = $userData->id; 71 | $this->auth = $userData ->auth; 72 | $this->authEncode = $userData ->auth_encode; 73 | } 74 | //初始化收藏字符串 75 | $this->collectionApi = BangumiAPI::$apiUrl . "/user/" . $this->userID ."/collection?cat=playing"; 76 | } 77 | //获取收藏json 78 | public function GetCollection() 79 | { 80 | if ($this->userID == "" || $this->collectionApi == "") { 81 | return null; 82 | } 83 | return BangumiAPI::curl_get_contents($this->collectionApi); 84 | } 85 | //格式化收藏 86 | public function ParseCollection() 87 | { 88 | $content = $this->GetCollection(); 89 | if ($content == null || $content == "") { 90 | echo "获取失败"; 91 | return; 92 | } 93 | //返回不是json 94 | if (strpos($content, "[{") != false && $content != "") { 95 | echo "用户不存在!"; 96 | return; 97 | } 98 | $collData = json_decode($content); 99 | if (sizeof($collData) == 0 || $collData == null) { 100 | //echo "还没有记录哦~"; 101 | return; 102 | } 103 | $index = 0; 104 | foreach ($collData as $value) { 105 | $name = $value->name; 106 | $name_cn = $value->subject->name_cn; 107 | $theurl = $value->subject->url; 108 | $img_grid =$value->subject->images->grid; 109 | $this->myCollection[$index++] = $value; 110 | } 111 | } 112 | //获取详细进度 113 | public function GetProgress($_subjectID) 114 | { 115 | if ($this->authEncode == "" || $this->userID == "") { 116 | return null; 117 | } 118 | $progressApi = BangumiAPI::$apiUrl . "/user/" . $this->userID . "/progress?subject_id=". $_subjectID . "&source=" . self::$appName . "&auth=" . authEncode; 119 | $content = BangumiAPI::curl_get_contents($progressApi); 120 | //print_r($content); 121 | return $content; 122 | } 123 | public function ParseProgress($_subjectID) 124 | { 125 | $content = $this->GetProgress($_subjectID); 126 | //不在收藏或没看过 127 | if ($content == "null") { 128 | return 0; 129 | } 130 | //在收藏中,没看过 131 | if ($content == "") { 132 | return 0; 133 | } 134 | $progressValue = json_decode($content); 135 | //返回剧集观看详细进度 136 | return $progressValue; 137 | } 138 | //打印收藏 139 | public function PrintCollecion($flag = true) 140 | { 141 | if ($this->myCollection == null) { 142 | $this->ParseCollection(); 143 | } 144 | switch ($flag) { 145 | case true: 146 | if (sizeof($this->myCollection) == 0 || $this->myCollection == null) { 147 | echo "还没有记录哦~"; 148 | return; 149 | } 150 | echo " 151 | 224 | "; 225 | foreach ($this->myCollection as $value) { 226 | //print_r($value); 227 | //$id = $value->subject->id; 228 | $epsNum = '未知'; 229 | if(@$value->subject->eps){ 230 | $epsNum = $value->subject->eps; 231 | } 232 | $progressNum = $value->ep_status; 233 | $myProgress = $progressNum . "/" . $epsNum; 234 | $name = $value->name; 235 | $name_cn = $value->subject->name_cn; 236 | if(@!$name_cn){ 237 | $name_cn = $name; 238 | } 239 | $air_date = $value->subject->air_date; 240 | $theurl = $value->subject->url; 241 | $img_grid =str_replace("http://", "https://", $value->subject->images->common); 242 | $progressWidth = 0; 243 | if($epsNum=='未知'){ 244 | $progressWidth = 100; 245 | }else{ 246 | $progressWidth = $progressNum / $epsNum * 100; 247 | if($progressWidth>100){ 248 | $progressWidth = 100; 249 | } 250 | } 251 | echo " 252 | 253 | 254 |
$name_cn
255 | $name
256 | 首播日期:$air_date
257 |
258 |
进度:$myProgress
259 |
260 |
261 |
262 |
263 |
"; 264 | //echo print_r($value); 265 | } 266 | break; 267 | case false: 268 | echo $myCollection; 269 | break; 270 | default: 271 | break; 272 | } 273 | } 274 | //get获取内容 275 | private static function curl_get_contents($_url) 276 | { 277 | //echo "The GET Url You Request is " . $_url . "
"; 278 | $myCurl = curl_init($_url); 279 | //不验证证书 280 | curl_setopt($myCurl, CURLOPT_SSL_VERIFYPEER, false); 281 | curl_setopt($myCurl, CURLOPT_SSL_VERIFYHOST, false); 282 | curl_setopt($myCurl, CURLOPT_RETURNTRANSFER, true); 283 | curl_setopt($myCurl, CURLOPT_HEADER, false); 284 | //获取 285 | $content = curl_exec($myCurl); 286 | //关闭 287 | curl_close($myCurl); 288 | return $content; 289 | } 290 | //post获取内容 291 | private static function curl_post_contents($_url,$_postdata) 292 | { 293 | //echo "The POST Url You Request is " . $_url . "
"; 294 | $myCurl = curl_init($_url); 295 | //不验证证书 296 | curl_setopt($myCurl, CURLOPT_SSL_VERIFYPEER, false); 297 | curl_setopt($myCurl, CURLOPT_SSL_VERIFYHOST, false); 298 | curl_setopt($myCurl, CURLOPT_RETURNTRANSFER, true); 299 | curl_setopt($myCurl, CURLOPT_POST, 1); 300 | curl_setopt($myCurl, CURLOPT_POSTFIELDS, $_postdata); 301 | $output = curl_exec($myCurl); 302 | curl_close($myCurl); 303 | return $output; 304 | } 305 | } 306 | 307 | class WikimoeBangumi_Action extends Widget_Abstract_Contents implements Widget_Interface_Do 308 | { 309 | 310 | public function action() 311 | { 312 | $options = Helper::options(); 313 | $userID = $options->plugin('WikimoeBangumi')->userID; 314 | $password = $options->plugin('WikimoeBangumi')->password; 315 | 316 | $bangum = BangumiAPI::GetInstance(); 317 | $bangum->init($userID,$password); 318 | $bangum->ParseCollection(); 319 | $bangum->PrintCollecion(true); 320 | } 321 | } -------------------------------------------------------------------------------- /Plugin.php: -------------------------------------------------------------------------------- 1 | header = array('WikimoeBangumi_Plugin', 'header'); 22 | //Typecho_Plugin::factory('Widget_Archive')->footer = array('WikimoeBangumi_Plugin', 'footer'); 23 | Helper::addRoute("route_WikimoeBangumi","/WikimoeBangumi","WikimoeBangumi_Action",'action'); 24 | //Typecho_Plugin::factory('Widget_Abstract_Contents')->contentEx = array('WikimoeBangumi_Plugin', 'setak'); 25 | //Typecho_Plugin::factory('Widget_Abstract_Contents')->excerptEx = array('WikimoeBangumi_Plugin', 'setak'); 26 | } 27 | 28 | /** 29 | * 禁用插件方法,如果禁用失败,直接抛出异常 30 | * 31 | * @static 32 | * @access public 33 | * @return void 34 | * @throws Typecho_Plugin_Exception 35 | */ 36 | public static function deactivate(){ 37 | Helper::removeRoute("route_WikimoeBangumi"); 38 | } 39 | 40 | /** 41 | * 获取插件配置面板 42 | * 43 | * @access public 44 | * @param Typecho_Widget_Helper_Form $form 配置面板 45 | * @return void 46 | */ 47 | public static function config(Typecho_Widget_Helper_Form $form) 48 | { 49 | /**表单设置 */ 50 | $userID = new Typecho_Widget_Helper_Form_Element_Text('userID', NULL, NULL, _t('输入Bangumi账号')); 51 | $form->addInput($userID); 52 | $password = new Typecho_Widget_Helper_Form_Element_Password('password', NULL, NULL, _t('输入Bangumi密码(推荐设置成不是常用的密码)')); 53 | $form->addInput($password); 54 | } 55 | 56 | /** 57 | * 个人用户的配置面板 58 | * 59 | * @access public 60 | * @param Typecho_Widget_Helper_Form $form 61 | * @return void 62 | */ 63 | 64 | /** 65 | * 页头输出CSS 66 | * 67 | * @access public 68 | * @param unknown header 69 | * @return unknown 70 | */ 71 | public static function header() { 72 | $Path = Helper::options()->pluginUrl . '/WikimoeBangumi/'; 73 | echo ''; 74 | } 75 | 76 | public static function footer() { 77 | $Path = Helper::options()->pluginUrl . '/WikimoeBangumi/'; 78 | echo ''; 79 | } 80 | 81 | public static function personalConfig(Typecho_Widget_Helper_Form $form){} 82 | 83 | public static function output() 84 | { 85 | $Path = Helper::options()->pluginUrl . '/WikimoeBangumi/'; 86 | echo ''; 87 | echo '
88 |
89 |
90 |
91 |
92 |
93 |
94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 |
107 |
追番数据加载中...
108 |
109 |
110 | 111 | 112 |
113 | 114 |
'; 115 | echo " 116 | 131 | 132 | "; 133 | } 134 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Typecho追番插件 2 | 3 | #### 项目介绍 4 | 本插件为通过Bangumi的API来获取追番信息。适用于Typecho! 5 | 具体使用方法相见:[https://www.wikimoe.com/?post=136](https://www.wikimoe.com/?post=136) 6 | -------------------------------------------------------------------------------- /css/css.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | /* CSS Document */ 3 | 4 | .bangumi_loading{ 5 | padding:100px 0; 6 | } 7 | .bangumi_loading_text{ 8 | text-align:center; 9 | padding:10px 0; 10 | } 11 | .loading-overlay { 12 | position: absolute; 13 | top: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 100%; 17 | background-color: rgba(255, 255, 255, 0); 18 | transition: background-color .2s ease-out; 19 | } 20 | 21 | .loading-anim { 22 | position: relative; 23 | width: 200px; 24 | height: 200px; 25 | margin: auto; 26 | perspective: 800px; 27 | transform-style: preserve-3d; 28 | transform: translateZ(-100px) rotateY(-90deg) rotateX(90deg) rotateZ(90deg) scale(0.5); 29 | opacity: 0; 30 | transition: all .2s ease-out; 31 | } 32 | .loading-anim .circle { 33 | width: 100%; 34 | height: 100%; 35 | animation: spin 5s linear infinite; 36 | } 37 | .loading-anim .border { 38 | position: absolute; 39 | border-radius: 50%; 40 | border: 3px solid #e34981; 41 | } 42 | .loading-anim .out { 43 | top: 15%; 44 | left: 15%; 45 | width: 70%; 46 | height: 70%; 47 | border-left-color: transparent; 48 | border-right-color: transparent; 49 | animation: spin 2s linear reverse infinite; 50 | } 51 | .loading-anim .in { 52 | top: 18%; 53 | left: 18%; 54 | width: 64%; 55 | height: 64%; 56 | border-top-color: transparent; 57 | border-bottom-color: transparent; 58 | animation: spin 2s linear infinite; 59 | } 60 | .loading-anim .mid { 61 | top: 40%; 62 | left: 40%; 63 | width: 20%; 64 | height: 20%; 65 | border-left-color: transparent; 66 | border-right-color: transparent; 67 | animation: spin 1s linear infinite; 68 | } 69 | 70 | .loading-anim { 71 | transform: translateZ(0) rotateY(0deg) rotateX(0deg) rotateZ(0deg) scale(1); 72 | opacity: 1; 73 | } 74 | 75 | .loading-overlay { 76 | background: rgba(255, 255, 255, 0.5); 77 | } 78 | 79 | .dot { 80 | position: absolute; 81 | display: block; 82 | width: 20px; 83 | height: 20px; 84 | border-radius: 50%; 85 | background-color: #e34981; 86 | animation: jitter 5s ease-in-out infinite, fade-in-out 5s linear infinite; 87 | } 88 | 89 | .dot:nth-child(1) { 90 | top: 90px; 91 | left: 180px; 92 | animation-delay: 0s; 93 | } 94 | 95 | .dot:nth-child(2) { 96 | top: 135px; 97 | left: 168px; 98 | animation-delay: 0.41667s; 99 | } 100 | 101 | .dot:nth-child(3) { 102 | top: 168px; 103 | left: 135px; 104 | animation-delay: 0.83333s; 105 | } 106 | 107 | .dot:nth-child(4) { 108 | top: 180px; 109 | left: 90px; 110 | animation-delay: 1.25s; 111 | } 112 | 113 | .dot:nth-child(5) { 114 | top: 168px; 115 | left: 45px; 116 | animation-delay: 1.66667s; 117 | } 118 | 119 | .dot:nth-child(6) { 120 | top: 135px; 121 | left: 12px; 122 | animation-delay: 2.08333s; 123 | } 124 | 125 | .dot:nth-child(7) { 126 | top: 90px; 127 | left: 0px; 128 | animation-delay: 2.5s; 129 | } 130 | 131 | .dot:nth-child(8) { 132 | top: 45px; 133 | left: 12px; 134 | animation-delay: 2.91667s; 135 | } 136 | 137 | .dot:nth-child(9) { 138 | top: 12px; 139 | left: 45px; 140 | animation-delay: 3.33333s; 141 | } 142 | 143 | .dot:nth-child(10) { 144 | top: 0px; 145 | left: 90px; 146 | animation-delay: 3.75s; 147 | } 148 | 149 | .dot:nth-child(11) { 150 | top: 12px; 151 | left: 135px; 152 | animation-delay: 4.16667s; 153 | } 154 | 155 | .dot:nth-child(12) { 156 | top: 45px; 157 | left: 168px; 158 | animation-delay: 4.58333s; 159 | } 160 | 161 | @keyframes spin { 162 | from { 163 | transform: rotate(0deg); 164 | } 165 | to { 166 | transform: rotate(360deg); 167 | } 168 | } 169 | @keyframes jitter { 170 | 0% { 171 | transform: scale(1, 1); 172 | } 173 | 25% { 174 | transform: scale(0.7, 0.7); 175 | } 176 | 50% { 177 | transform: scale(1, 1); 178 | } 179 | 75% { 180 | transform: scale(1.3, 1.3); 181 | } 182 | 100% { 183 | transform: scale(1, 1); 184 | } 185 | } 186 | @keyframes fade-in-out { 187 | 0% { 188 | opacity: 0.8; 189 | } 190 | 25% { 191 | opacity: 0.2; 192 | } 193 | 75% { 194 | opacity: 1; 195 | } 196 | 100% { 197 | opacity: 0.8; 198 | } 199 | } -------------------------------------------------------------------------------- /js/js.js: -------------------------------------------------------------------------------- 1 | // JavaScript Document 2 | jQuery.ajax({ 3 | type: 'GET', 4 | url: './bangumiAPI.php', 5 | success: function(res) { 6 | $('#bangumiBody').empty().append(res); 7 | 8 | }, 9 | error:function(){ 10 | $('#bangumiBody').empty().text('加载失败'); 11 | } 12 | }); --------------------------------------------------------------------------------