pikapika/go/pikapi/controller/download.go

308 lines
6.9 KiB
Go

package controller
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"pgo/pikapi/const_value"
"pgo/pikapi/database/comic_center"
utils2 "pgo/pikapi/utils"
"time"
)
var downloadRunning = false
var downloadRestart = false
var downloadingComic *comic_center.ComicDownload
var downloadingEp *comic_center.ComicDownloadEp
var downloadingPicture *comic_center.ComicDownloadPicture
func downloadBackground() {
println("后台线程启动")
go downloadBegin()
}
func downloadBegin() {
time.Sleep(time.Second * 3)
go downloadLoadComic()
}
func downloadHasStop() bool {
if !downloadRunning {
go downloadBegin()
return true
}
if downloadRestart {
downloadRestart = false
go downloadBegin()
return true
}
return false
}
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
}
func downloadLoadComic() {
for downloadDelete() {
}
if downloadHasStop() {
return
}
var err error
downloadingComic, err = comic_center.LoadFirstNeedDownload()
// 查库有错误就停止
if err != nil {
panic(err)
}
go downloadInitComic()
}
func downloadInitComic() {
if downloadHasStop() {
return
}
if downloadingComic == nil {
println("没有找到要下载的漫画")
go downloadBegin()
return
}
println("正在下载漫画 " + downloadingComic.Title)
downloadComicEventSend(downloadingComic)
eps, err := comic_center.ListDownloadEpByComicId(downloadingComic.ID)
if err != nil {
panic(err)
}
for _, ep := range eps {
if !ep.FetchedPictures {
println("正在获取章节的图片 " + downloadingComic.Title + " " + ep.Title)
for i := 0; i < 5; i++ {
if client.Token == "" {
continue
}
err := downloadFetchPictures(&ep)
if err != nil {
println(err.Error())
continue
}
ep.FetchedPictures = true
break
}
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)
}
}
}
go downloadLoadEp()
}
func downloadFetchPictures(downloadEp *comic_center.ComicDownloadEp) error {
var list []comic_center.ComicDownloadPicture
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,
})
}
if rsp.Page.Page < rsp.Page.Pages {
page++
continue
}
break
}
err := comic_center.FetchPictures(downloadEp.ComicId, downloadEp.ID, &list)
if err != nil {
panic(err)
}
downloadEp.SelectedPictureCount = int32(len(list))
return err
}
func downloadLoadEp() {
if downloadHasStop() {
return
}
var err error
downloadingEp, err = comic_center.LoadFirstNeedDownloadEp(downloadingComic.ID)
if err != nil {
panic(err)
}
go downloadInitEp()
}
func downloadInitEp() {
if downloadingEp == nil {
// 所有Ep都下完了, 汇总Download下载情况
go downloadSummaryDownload()
return
}
println("正在下载章节 " + downloadingEp.Title)
go downloadLoadPicture()
}
func downloadSummaryDownload() {
if downloadHasStop() {
return
}
list, err := comic_center.ListDownloadEpByComicId(downloadingComic.ID)
if err != nil {
panic(err)
}
over := true
for _, downloadEp := range list {
over = over && downloadEp.DownloadFinished
}
if over {
err = comic_center.DownloadSuccess(downloadingComic.ID)
if err != nil {
panic(err)
}
downloadingComic.DownloadFinished = true
downloadingComic.DownloadFinishedTime = time.Now()
} else {
err = comic_center.DownloadFailed(downloadingComic.ID)
if err != nil {
panic(err)
}
downloadingComic.DownloadFailed = true
}
downloadComicEventSend(downloadingComic)
go downloadLoadComic()
}
func downloadLoadPicture() {
if downloadHasStop() {
return
}
var err error
downloadingPicture, err = comic_center.LoadFirstNeedDownloadPicture(downloadingEp.ID)
if err != nil {
panic(err)
}
go downloadInitPicture()
}
func downloadInitPicture() {
if downloadHasStop() {
return
}
if downloadingPicture == nil {
// 所有图片都下完了, 汇总EP下载情况
go downloadSummaryEp()
return
}
println("正在下载图片 " + fmt.Sprintf("%d", downloadingPicture.RankInEp))
for i := 0; i < 5; i++ {
err := downloadThePicture(downloadingPicture)
if err != nil {
continue
}
downloadingPicture.DownloadFinished = true
downloadingEp.DownloadPictureCount = downloadingEp.DownloadPictureCount + 1
downloadingComic.DownloadPictureCount = downloadingComic.DownloadPictureCount + 1
downloadComicEventSend(downloadingComic)
break
}
if !downloadingPicture.DownloadFinished {
err := comic_center.PictureFailed(downloadingPicture.ID)
if err != nil {
panic(err)
}
}
go downloadLoadPicture()
}
func downloadThePicture(picturePoint *comic_center.ComicDownloadPicture) error {
lock := utils2.HashLock(fmt.Sprintf("%s$%s", picturePoint.FileServer, picturePoint.Path))
lock.Lock()
defer lock.Unlock()
picturePath := fmt.Sprintf("%s/%d/%d", picturePoint.ComicId, picturePoint.EpOrder, picturePoint.RankInEp)
realPath := downloadPath(picturePath)
// 从缓存
buff, img, format, err := decodeFromCache(picturePoint.FileServer, picturePoint.Path)
if err != nil {
// 从网络
buff, img, format, err = decodeFromUrl(picturePoint.FileServer, picturePoint.Path)
}
if err != nil {
return err
}
dir := filepath.Dir(realPath)
if _, err := os.Stat(dir); os.IsNotExist(err) {
os.Mkdir(dir, const_value.CreateDirMode)
}
err = ioutil.WriteFile(downloadPath(picturePath), buff, const_value.CreateFileMode)
if err != nil {
return err
}
return comic_center.PictureSuccess(
picturePoint.ComicId,
picturePoint.EpId,
picturePoint.ID,
int64(len(buff)),
format,
int32(img.Bounds().Dx()),
int32(img.Bounds().Dy()),
picturePath,
)
}
func downloadSummaryEp() {
if downloadHasStop() {
return
}
list, err := comic_center.ListDownloadPictureByEpId(downloadingEp.ID)
if err != nil {
panic(err)
}
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)
}
}
go downloadLoadEp()
}