分离搜图与随机图(随机图需要cgo而搜图不用)

This commit is contained in:
fumiama
2021-06-04 13:45:50 +08:00
parent 6e3f395f07
commit 33dc16956d
10 changed files with 82 additions and 70 deletions

73
api/pixiv/download.go Normal file
View File

@@ -0,0 +1,73 @@
package pixiv
import (
"crypto/md5"
"crypto/tls"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
"strings"
)
// urlCache 缓存并返回缓存路径
func (this *Illust) PixivPicDown(path string) (savePath string, err error) {
url := this.ImageUrls
pid := this.Pid
url = strings.ReplaceAll(url, "img-original", "img-master")
url = strings.ReplaceAll(url, "_p0", "_p0_master1200")
url = strings.ReplaceAll(url, ".png", ".jpg")
// 文件名为url的hash值
savePath = path + Int2Str(pid) + ".jpg"
// 文件存在或文件大小大于10kb
if PathExists(savePath) && FileSize(savePath) > 10240 {
return savePath, nil
}
// 模拟QQ客户端请求
client := &http.Client{
Transport: &http.Transport{
DisableKeepAlives: true,
// 绕过sni审查
TLSClientConfig: &tls.Config{
ServerName: "-",
InsecureSkipVerify: true,
},
// 更改dns
Dial: func(network, addr string) (net.Conn, error) {
return net.Dial("tcp", "210.140.92.142:443")
},
},
}
reqest, _ := http.NewRequest("GET", url, nil)
reqest.Header.Set("Referer", "https://www.pixiv.net/")
reqest.Header.Set("Host", "i.pximg.net")
reqest.Header.Set("User-Agent", "QQ/8.2.0.1296 CFNetwork/1126")
resp, err := client.Do(reqest)
if err != nil {
return "", err
}
if resp.StatusCode != 200 {
return "", errors.New(fmt.Sprintf("Download failed, code %d", resp.StatusCode))
}
defer resp.Body.Close()
// 写入文件
data, _ := ioutil.ReadAll(resp.Body)
f, _ := os.OpenFile(savePath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
defer f.Close()
f.Write(data)
return savePath, err
}
// PicHash 返回图片的 md5 值
func PicHash(path string) string {
data, err := ioutil.ReadFile(path)
if err != nil {
return ""
}
return strings.ToUpper(fmt.Sprintf("%x", md5.Sum(data)))
}

137
api/pixiv/pixiv_api.go Normal file
View File

@@ -0,0 +1,137 @@
package pixiv
import (
"crypto/tls"
"errors"
"fmt"
"io/ioutil"
"net"
"net/http"
"strings"
"github.com/tidwall/gjson"
)
// Illust 插画信息
type Illust struct {
Pid int64 `db:"pid"`
Title string `db:"title"`
Caption string `db:"caption"`
Tags string `db:"tags"`
ImageUrls string `db:"image_urls"`
AgeLimit string `db:"age_limit"`
CreatedTime string `db:"created_time"`
UserId int64 `db:"user_id"`
UserName string `db:"user_name"`
}
// IllustInfo 根据p站插画id返回插画信息Illust
func (this *Illust) IllustInfo(id int64) (err error) {
api := fmt.Sprintf("https://pixiv.net/ajax/illust/%d", id)
transport := http.Transport{
DisableKeepAlives: true,
// 绕过sni审查
TLSClientConfig: &tls.Config{
ServerName: "-",
InsecureSkipVerify: true,
},
// 更改dns
Dial: func(network, addr string) (net.Conn, error) {
return net.Dial("tcp", "210.140.131.223:443")
},
}
client := &http.Client{
Transport: &transport,
}
// 网络请求
req, err := http.NewRequest("GET", api, nil)
if err != nil {
return err
}
req.Header.Set("Host", "pixiv.net")
req.Header.Set("Referer", "pixiv.net")
req.Header.Set("Accept", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0")
resp, err := client.Do(req)
if err != nil {
return err
}
if code := resp.StatusCode; code != 200 {
return errors.New(fmt.Sprintf("Search illust's info failed, status %d", code))
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
json := gjson.ParseBytes(body).Get("body")
// 如果有"R-18"tag则判断为R-18暂时
var ageLimit = "all-age"
for _, tag := range json.Get("tags.tags.#.tag").Array() {
if tag.Str == "R-18" {
ageLimit = "r18"
break
}
}
// 解决json返回带html格式
var caption = strings.ReplaceAll(json.Get("illustComment").Str, "<br />", "\n")
if index := strings.Index(caption, "<"); index != -1 {
caption = caption[:index]
}
// 解析返回插画信息
this.Pid = json.Get("illustId").Int()
this.Title = json.Get("illustTitle").Str
this.Caption = caption
this.Tags = fmt.Sprintln(json.Get("tags.tags.#.tag").Array())
this.ImageUrls = json.Get("urls.original").Str
this.AgeLimit = ageLimit
this.CreatedTime = json.Get("createDate").Str
this.UserId = json.Get("userId").Int()
this.UserName = json.Get("userName").Str
return nil
}
// BigPic 返回一张XML大图CQ码
func (i *Illust) BigPic(file string) string {
var hash = PicHash(file)
return fmt.Sprintf(`[CQ:xml,data=<?xml version='1.0'
encoding='UTF-8' standalone='yes' ?><msg serviceID="5"
templateID="12345" action="" brief="不够涩!"
sourceMsgId="0" url="" flag="0" adverSign="0" multiMsgFlag="0">
<item layout="0" advertiser_id="0" aid="0"><image uuid="%s.jpg" md5="%s"
GroupFiledid="2235033681" filesize="81322" local_path="%s.jpg"
minWidth="200" minHeight="200" maxWidth="500" maxHeight="1000" />
</item><source name="%s⭐(id:%d author:%s)" icon=""
action="" appid="-1" /></msg>]`,
hash,
hash,
hash,
i.Title,
i.Pid,
i.UserName,
)
}
// NormalPic 返回一张普通图CQ码
func (i *Illust) NormalPic(file string) string {
return fmt.Sprintf(`[CQ:image,file=file:///%s]`, file)
}
// DetailPic 返回一张带详细信息的图片CQ码
func (i *Illust) DetailPic(file string) string {
return fmt.Sprintf(`[SetuTime] %s
标题:%s
插画ID%d
画师:%s
画师ID%d
直链https://pixivel.moe/detail?id=%d`,
i.NormalPic(file),
i.Title,
i.Pid,
i.UserName,
i.UserId,
i.Pid,
)
}

73
api/pixiv/utils.go Normal file
View File

@@ -0,0 +1,73 @@
package pixiv
import (
"os"
"strconv"
"strings"
)
// Str2Int string --> int64
func Str2Int(str string) int64 {
val, _ := strconv.Atoi(str)
return int64(val)
}
// Int2Str int64 --> string
func Int2Str(val int64) string {
str := strconv.FormatInt(val, 10)
return str
}
// PathExecute 返回当前运行目录
func PathExecute() string {
dir, err := os.Getwd()
if err != nil {
panic(err)
}
return dir + "/"
}
// CreatePath 生成路径或文件所对应的目录
func CreatePath(path string) {
length := len(path)
switch {
case path[length:] != "/":
path = path[:strings.LastIndex(path, "/")]
case path[length:] != "\\":
path = path[:strings.LastIndex(path, "\\")]
default:
//
}
if !PathExists(path) {
err := os.MkdirAll(path, 0755)
if err != nil {
panic(err)
}
}
}
// PathExists 判断路径或文件是否存在
func PathExists(path string) bool {
_, err := os.Stat(path)
return err == nil || os.IsExist(err)
}
// FileSize 获取文件大小
func FileSize(file string) int64 {
if fi, err := os.Stat(file); err == nil {
return fi.Size()
}
return 0
}
// Min 返回两数最小值
func Min(a, b int) int {
switch {
default:
return a
case a > b:
return b
case a < b:
return a
}
}