2021-09-29 23:57:09 +00:00
|
|
|
package controller
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2021-10-22 02:24:39 +00:00
|
|
|
"pikapi/main/database/comic_center"
|
|
|
|
utils2 "pikapi/main/utils"
|
2021-09-29 23:57:09 +00:00
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 使用协程进行后台下载
|
|
|
|
// downloadRunning 如果为false则停止下载
|
|
|
|
// downloadRestart 为true则取消从新启动下载功能
|
|
|
|
|
2021-09-29 23:57:09 +00:00
|
|
|
var downloadRunning = false
|
|
|
|
var downloadRestart = false
|
|
|
|
|
|
|
|
var downloadingComic *comic_center.ComicDownload
|
|
|
|
var downloadingEp *comic_center.ComicDownloadEp
|
|
|
|
var downloadingPicture *comic_center.ComicDownloadPicture
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
var dlFlag = true
|
|
|
|
|
|
|
|
// 程序启动后仅调用一次, 启动后台线程
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadBackground() {
|
|
|
|
println("后台线程启动")
|
2021-10-19 10:26:12 +00:00
|
|
|
if dlFlag {
|
|
|
|
dlFlag = false
|
|
|
|
go downloadBegin()
|
|
|
|
}
|
2021-09-29 23:57:09 +00:00
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 下载启动/重新启动会暂停三秒
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadBegin() {
|
|
|
|
time.Sleep(time.Second * 3)
|
|
|
|
go downloadLoadComic()
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 下载周期中, 每个下载单元会调用此方法, 如果返回true应该停止当前动作
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadHasStop() bool {
|
|
|
|
if !downloadRunning {
|
|
|
|
go downloadBegin()
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if downloadRestart {
|
|
|
|
downloadRestart = false
|
|
|
|
go downloadBegin()
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 删除下载任务, 当用户要删除下载的时候, 他会被加入删除队列, 而不是直接被删除, 以减少出错
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadDelete() bool {
|
|
|
|
c, e := comic_center.DeletingComic()
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
if c != nil {
|
|
|
|
os.RemoveAll(downloadPath(c.ID))
|
|
|
|
e = comic_center.TrueDelete(c.ID)
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 加载第一个需要下载的漫画
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadLoadComic() {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 每次下载完一个漫画, 或者启动的时候, 首先进行删除任务
|
2021-09-29 23:57:09 +00:00
|
|
|
for downloadDelete() {
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 检测是否需要停止
|
2021-09-29 23:57:09 +00:00
|
|
|
if downloadHasStop() {
|
|
|
|
return
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 找到第一个要下载的漫画, 查库有错误就停止, 因为这些错误很少出现, 一旦出现必然是严重的, 例如数据库文件突然被删除
|
2021-09-29 23:57:09 +00:00
|
|
|
var err error
|
|
|
|
downloadingComic, err = comic_center.LoadFirstNeedDownload()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 处理找到的下载任务
|
2021-09-29 23:57:09 +00:00
|
|
|
go downloadInitComic()
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 初始化找到的下载任务
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadInitComic() {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 检测是否需要停止
|
2021-09-29 23:57:09 +00:00
|
|
|
if downloadHasStop() {
|
|
|
|
return
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 若没有漫画要下载则重新启动
|
2021-09-29 23:57:09 +00:00
|
|
|
if downloadingComic == nil {
|
|
|
|
println("没有找到要下载的漫画")
|
|
|
|
go downloadBegin()
|
|
|
|
return
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 打印日志, 并向前端的eventChannel发送下载信息
|
2021-09-29 23:57:09 +00:00
|
|
|
println("正在下载漫画 " + downloadingComic.Title)
|
|
|
|
downloadComicEventSend(downloadingComic)
|
|
|
|
eps, err := comic_center.ListDownloadEpByComicId(downloadingComic.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 找到这个漫画需要下载的EP, 并搜索获取图片地址
|
2021-09-29 23:57:09 +00:00
|
|
|
for _, ep := range eps {
|
2021-10-19 10:26:12 +00:00
|
|
|
// FetchedPictures字段标志着这个章节的图片地址有没有获取过, 如果没有获取过就重新获取
|
2021-09-29 23:57:09 +00:00
|
|
|
if !ep.FetchedPictures {
|
|
|
|
println("正在获取章节的图片 " + downloadingComic.Title + " " + ep.Title)
|
2021-10-19 10:26:12 +00:00
|
|
|
// 搜索图片地址, 如果五次没有请求成功, 就不在请求
|
2021-09-29 23:57:09 +00:00
|
|
|
for i := 0; i < 5; i++ {
|
|
|
|
if client.Token == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
err := downloadFetchPictures(&ep)
|
|
|
|
if err != nil {
|
|
|
|
println(err.Error())
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
ep.FetchedPictures = true
|
|
|
|
break
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 如果未能获取图片地址, 则直接置为失败
|
2021-09-29 23:57:09 +00:00
|
|
|
if !ep.FetchedPictures {
|
|
|
|
println("章节的图片获取失败 " + downloadingComic.Title + " " + ep.Title)
|
|
|
|
err = comic_center.EpFailed(ep.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
println("章节的图片获取成功 " + downloadingComic.Title + " " + ep.Title)
|
|
|
|
downloadingComic.SelectedPictureCount = downloadingComic.SelectedPictureCount + ep.SelectedPictureCount
|
|
|
|
downloadComicEventSend(downloadingComic)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 获取图片地址结束, 去初始化下载的章节
|
2021-09-29 23:57:09 +00:00
|
|
|
go downloadLoadEp()
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 获取图片地址
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadFetchPictures(downloadEp *comic_center.ComicDownloadEp) error {
|
|
|
|
var list []comic_center.ComicDownloadPicture
|
2021-10-19 10:26:12 +00:00
|
|
|
// 官方的图片只能分页获取, 从第1页开始获取, 每页最多40张图片
|
2021-09-29 23:57:09 +00:00
|
|
|
page := 1
|
|
|
|
for true {
|
|
|
|
rsp, err := client.ComicPicturePage(downloadingComic.ID, int(downloadEp.EpOrder), page)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, doc := range rsp.Docs {
|
|
|
|
list = append(list, comic_center.ComicDownloadPicture{
|
|
|
|
ID: doc.Id,
|
|
|
|
ComicId: downloadEp.ComicId,
|
|
|
|
EpId: downloadEp.ID,
|
|
|
|
EpOrder: downloadEp.EpOrder,
|
|
|
|
OriginalName: doc.Media.OriginalName,
|
|
|
|
FileServer: doc.Media.FileServer,
|
|
|
|
Path: doc.Media.Path,
|
|
|
|
})
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 如果不是最后一页, 页码加1, 获取下一页
|
2021-09-29 23:57:09 +00:00
|
|
|
if rsp.Page.Page < rsp.Page.Pages {
|
|
|
|
page++
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
break
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 保存获取到的图片
|
2021-09-29 23:57:09 +00:00
|
|
|
err := comic_center.FetchPictures(downloadEp.ComicId, downloadEp.ID, &list)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
downloadEp.SelectedPictureCount = int32(len(list))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 初始化下载
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadLoadEp() {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 周期停止检测
|
2021-09-29 23:57:09 +00:00
|
|
|
if downloadHasStop() {
|
|
|
|
return
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 找到第一个需要下载的章节并去处理 (未下载失败的, 且未完成下载的)
|
2021-09-29 23:57:09 +00:00
|
|
|
var err error
|
|
|
|
downloadingEp, err = comic_center.LoadFirstNeedDownloadEp(downloadingComic.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
go downloadInitEp()
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 处理需要下载的EP
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadInitEp() {
|
|
|
|
if downloadingEp == nil {
|
|
|
|
// 所有Ep都下完了, 汇总Download下载情况
|
|
|
|
go downloadSummaryDownload()
|
|
|
|
return
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 没有下载完则去下载图片
|
2021-09-29 23:57:09 +00:00
|
|
|
println("正在下载章节 " + downloadingEp.Title)
|
|
|
|
go downloadLoadPicture()
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// EP下载汇总
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadSummaryDownload() {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 暂停检测
|
2021-09-29 23:57:09 +00:00
|
|
|
if downloadHasStop() {
|
|
|
|
return
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 加载这个漫画的所有EP
|
2021-09-29 23:57:09 +00:00
|
|
|
list, err := comic_center.ListDownloadEpByComicId(downloadingComic.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 判断所有章节是否下载完成
|
2021-09-29 23:57:09 +00:00
|
|
|
over := true
|
|
|
|
for _, downloadEp := range list {
|
|
|
|
over = over && downloadEp.DownloadFinished
|
|
|
|
}
|
|
|
|
if over {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 如果所有章节下载完成则下载成功
|
2021-09-29 23:57:09 +00:00
|
|
|
err = comic_center.DownloadSuccess(downloadingComic.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
downloadingComic.DownloadFinished = true
|
|
|
|
downloadingComic.DownloadFinishedTime = time.Now()
|
|
|
|
} else {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 否则下载失败
|
2021-09-29 23:57:09 +00:00
|
|
|
err = comic_center.DownloadFailed(downloadingComic.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
downloadingComic.DownloadFailed = true
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 向前端发送下载状态
|
2021-09-29 23:57:09 +00:00
|
|
|
downloadComicEventSend(downloadingComic)
|
2021-10-19 10:26:12 +00:00
|
|
|
// 去下载下一个漫画
|
2021-09-29 23:57:09 +00:00
|
|
|
go downloadLoadComic()
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 加载需要下载的图片
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadLoadPicture() {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 暂停检测
|
2021-09-29 23:57:09 +00:00
|
|
|
if downloadHasStop() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
var err error
|
|
|
|
downloadingPicture, err = comic_center.LoadFirstNeedDownloadPicture(downloadingEp.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
go downloadInitPicture()
|
|
|
|
}
|
|
|
|
|
|
|
|
func downloadInitPicture() {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 暂停检测
|
2021-09-29 23:57:09 +00:00
|
|
|
if downloadHasStop() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if downloadingPicture == nil {
|
|
|
|
// 所有图片都下完了, 汇总EP下载情况
|
|
|
|
go downloadSummaryEp()
|
|
|
|
return
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 下载图片, 最多重试5次
|
2021-09-29 23:57:09 +00:00
|
|
|
println("正在下载图片 " + fmt.Sprintf("%d", downloadingPicture.RankInEp))
|
|
|
|
for i := 0; i < 5; i++ {
|
|
|
|
err := downloadThePicture(downloadingPicture)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 对下载的漫画临时变量热更新并通知前端
|
2021-09-29 23:57:09 +00:00
|
|
|
downloadingPicture.DownloadFinished = true
|
|
|
|
downloadingEp.DownloadPictureCount = downloadingEp.DownloadPictureCount + 1
|
|
|
|
downloadingComic.DownloadPictureCount = downloadingComic.DownloadPictureCount + 1
|
|
|
|
downloadComicEventSend(downloadingComic)
|
|
|
|
break
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 没能下载成功, 图片置为下载失败
|
2021-09-29 23:57:09 +00:00
|
|
|
if !downloadingPicture.DownloadFinished {
|
|
|
|
err := comic_center.PictureFailed(downloadingPicture.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 加载下一张需要下载的图片
|
2021-09-29 23:57:09 +00:00
|
|
|
go downloadLoadPicture()
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// 下载指定图片
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadThePicture(picturePoint *comic_center.ComicDownloadPicture) error {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 为了不和页面前端浏览的数据冲突, 使用url做hash锁
|
2021-09-29 23:57:09 +00:00
|
|
|
lock := utils2.HashLock(fmt.Sprintf("%s$%s", picturePoint.FileServer, picturePoint.Path))
|
|
|
|
lock.Lock()
|
|
|
|
defer lock.Unlock()
|
2021-10-19 10:26:12 +00:00
|
|
|
// 图片保存位置使用相对路径储存, 使用绝对路径操作
|
2021-09-29 23:57:09 +00:00
|
|
|
picturePath := fmt.Sprintf("%s/%d/%d", picturePoint.ComicId, picturePoint.EpOrder, picturePoint.RankInEp)
|
|
|
|
realPath := downloadPath(picturePath)
|
2021-10-19 10:26:12 +00:00
|
|
|
// 从缓存获取图片
|
2021-09-29 23:57:09 +00:00
|
|
|
buff, img, format, err := decodeFromCache(picturePoint.FileServer, picturePoint.Path)
|
|
|
|
if err != nil {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 若缓存不存在, 则从网络获取
|
2021-09-29 23:57:09 +00:00
|
|
|
buff, img, format, err = decodeFromUrl(picturePoint.FileServer, picturePoint.Path)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 将图片保存到文件
|
2021-09-29 23:57:09 +00:00
|
|
|
dir := filepath.Dir(realPath)
|
|
|
|
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
2021-10-22 02:24:39 +00:00
|
|
|
os.Mkdir(dir, utils2.CreateDirMode)
|
2021-09-29 23:57:09 +00:00
|
|
|
}
|
2021-10-22 02:24:39 +00:00
|
|
|
err = ioutil.WriteFile(downloadPath(picturePath), buff, utils2.CreateFileMode)
|
2021-09-29 23:57:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 存入数据库
|
2021-09-29 23:57:09 +00:00
|
|
|
return comic_center.PictureSuccess(
|
|
|
|
picturePoint.ComicId,
|
|
|
|
picturePoint.EpId,
|
|
|
|
picturePoint.ID,
|
|
|
|
int64(len(buff)),
|
|
|
|
format,
|
|
|
|
int32(img.Bounds().Dx()),
|
|
|
|
int32(img.Bounds().Dy()),
|
|
|
|
picturePath,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2021-10-19 10:26:12 +00:00
|
|
|
// EP 下载内容汇总
|
2021-09-29 23:57:09 +00:00
|
|
|
func downloadSummaryEp() {
|
2021-10-19 10:26:12 +00:00
|
|
|
// 暂停检测
|
2021-09-29 23:57:09 +00:00
|
|
|
if downloadHasStop() {
|
|
|
|
return
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 找到所有下载的图片
|
2021-09-29 23:57:09 +00:00
|
|
|
list, err := comic_center.ListDownloadPictureByEpId(downloadingEp.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 全部下载完成置为成功, 否则置为失败
|
2021-09-29 23:57:09 +00:00
|
|
|
over := true
|
|
|
|
for _, downloadPicture := range list {
|
|
|
|
over = over && downloadPicture.DownloadFinished
|
|
|
|
}
|
|
|
|
if over {
|
|
|
|
err = comic_center.EpSuccess(downloadingEp.ComicId, downloadingEp.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
err = comic_center.EpFailed(downloadingEp.ID)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
2021-10-19 10:26:12 +00:00
|
|
|
// 去加载下一个EP
|
2021-09-29 23:57:09 +00:00
|
|
|
go downloadLoadEp()
|
|
|
|
}
|