Files
pansou/plugin/jikepan/jikepan.go

209 lines
4.8 KiB
Go
Raw Normal View History

2025-07-12 19:53:44 +08:00
package jikepan
import (
"bytes"
"fmt"
2025-07-15 00:03:02 +08:00
"io"
2025-07-12 19:53:44 +08:00
"net/http"
"strings"
"time"
"pansou/model"
"pansou/plugin"
2025-07-15 00:03:02 +08:00
"pansou/util/json"
2025-07-12 19:53:44 +08:00
)
// 在init函数中注册插件
func init() {
2025-07-15 00:03:02 +08:00
// 注册插件
plugin.RegisterGlobalPlugin(NewJikepanAsyncV2Plugin())
2025-07-12 19:53:44 +08:00
}
const (
2025-07-15 00:03:02 +08:00
// JikepanAPIURL 即刻盘API地址
2025-07-12 19:53:44 +08:00
JikepanAPIURL = "https://api.jikepan.xyz/search"
)
2025-07-15 00:03:02 +08:00
// JikepanAsyncV2Plugin 即刻盘搜索异步V2插件
type JikepanAsyncV2Plugin struct {
*plugin.BaseAsyncPlugin
2025-07-12 19:53:44 +08:00
}
2025-07-15 00:03:02 +08:00
// NewJikepanAsyncV2Plugin 创建新的即刻盘搜索异步V2插件
func NewJikepanAsyncV2Plugin() *JikepanAsyncV2Plugin {
return &JikepanAsyncV2Plugin{
BaseAsyncPlugin: plugin.NewBaseAsyncPlugin("jikepan", 3),
2025-07-12 19:53:44 +08:00
}
}
2025-07-15 00:03:02 +08:00
// Search 执行搜索并返回结果
func (p *JikepanAsyncV2Plugin) Search(keyword string) ([]model.SearchResult, error) {
// 生成缓存键
cacheKey := keyword
// 使用异步搜索基础方法
return p.AsyncSearch(keyword, cacheKey, p.doSearch)
2025-07-12 19:53:44 +08:00
}
2025-07-15 00:03:02 +08:00
// doSearch 实际的搜索实现
func (p *JikepanAsyncV2Plugin) doSearch(client *http.Client, keyword string) ([]model.SearchResult, error) {
2025-07-12 19:53:44 +08:00
// 构建请求
reqBody := map[string]interface{}{
"name": keyword,
"is_all": false,
}
jsonData, err := json.Marshal(reqBody)
if err != nil {
return nil, fmt.Errorf("marshal request failed: %w", err)
}
req, err := http.NewRequest("POST", JikepanAPIURL, bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("create request failed: %w", err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("referer", "https://jikepan.xyz/")
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")
// 发送请求
2025-07-15 00:03:02 +08:00
resp, err := client.Do(req)
2025-07-12 19:53:44 +08:00
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
// 解析响应
var apiResp JikepanResponse
2025-07-15 00:03:02 +08:00
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("read response body failed: %w", err)
}
if err := json.Unmarshal(bodyBytes, &apiResp); err != nil {
2025-07-12 19:53:44 +08:00
return nil, fmt.Errorf("decode response failed: %w", err)
}
// 检查响应状态
if apiResp.Msg != "success" {
return nil, fmt.Errorf("API returned error: %s", apiResp.Msg)
}
// 转换结果格式
2025-07-15 00:03:02 +08:00
results := p.convertResults(apiResp.List)
return results, nil
2025-07-12 19:53:44 +08:00
}
// convertResults 将API响应转换为标准SearchResult格式
2025-07-15 00:03:02 +08:00
func (p *JikepanAsyncV2Plugin) convertResults(items []JikepanItem) []model.SearchResult {
2025-07-12 19:53:44 +08:00
results := make([]model.SearchResult, 0, len(items))
for i, item := range items {
// 跳过没有链接的结果
if len(item.Links) == 0 {
continue
}
// 创建链接列表
links := make([]model.Link, 0, len(item.Links))
for _, link := range item.Links {
linkType := p.convertLinkType(link.Service)
// 特殊处理other类型检查链接URL
if linkType == "others" && strings.Contains(strings.ToLower(link.Link), "drive.uc.cn") {
linkType = "uc"
}
// 跳过未知类型的链接linkType为空
if linkType == "" {
continue
}
// 创建链接
links = append(links, model.Link{
URL: link.Link,
Type: linkType,
Password: link.Pwd,
})
}
// 创建唯一ID插件名-索引
uniqueID := fmt.Sprintf("jikepan-%d", i)
// 创建搜索结果
result := model.SearchResult{
UniqueID: uniqueID,
Title: item.Name,
2025-07-15 00:03:02 +08:00
Datetime: time.Time{}, // 使用零值而不是nil
2025-07-12 19:53:44 +08:00
Links: links,
}
results = append(results, result)
}
return results
}
// convertLinkType 将API的服务类型转换为标准链接类型
2025-07-15 00:03:02 +08:00
func (p *JikepanAsyncV2Plugin) convertLinkType(service string) string {
2025-07-12 19:53:44 +08:00
service = strings.ToLower(service)
switch service {
case "baidu":
return "baidu"
case "aliyun":
return "aliyun"
case "xunlei":
return "xunlei"
case "quark":
return "quark"
case "189cloud":
return "tianyi"
case "115":
return "115"
case "123":
return "123"
case "weiyun":
return "weiyun"
case "pikpak":
return "pikpak"
case "lanzou":
return "lanzou"
case "jianguoyun":
return "jianguoyun"
case "caiyun":
return "mobile"
case "chengtong":
return "chengtong"
case "ed2k":
return "ed2k"
case "magnet":
return "magnet"
case "unknown":
// 对于未知类型,返回空字符串,以便在后续处理中跳过
return ""
default:
return "others"
}
}
// JikepanResponse API响应结构
type JikepanResponse struct {
2025-07-15 00:03:02 +08:00
Msg string `json:"msg"`
2025-07-12 19:53:44 +08:00
List []JikepanItem `json:"list"`
}
// JikepanItem API响应中的单个结果项
type JikepanItem struct {
Name string `json:"name"`
Links []JikepanLink `json:"links"`
}
2025-07-15 00:03:02 +08:00
// JikepanLink API响应中的链接信息
2025-07-12 19:53:44 +08:00
type JikepanLink struct {
Service string `json:"service"`
Link string `json:"link"`
Pwd string `json:"pwd,omitempty"`
}