Browse Source

完成 ask for upload 接口

Signed-off-by: allan716 <[email protected]>
allan716 3 years ago
parent
commit
6ccdd4e94b

+ 83 - 4
internal/logic/cron_helper/cron_helper.go

@@ -1,6 +1,9 @@
 package cron_helper
 
 import (
+	"fmt"
+	"github.com/allanpk716/ChineseSubFinder/internal/dao"
+	"github.com/allanpk716/ChineseSubFinder/internal/models"
 	"sync"
 	"time"
 
@@ -31,6 +34,7 @@ type CronHelper struct {
 	entryIDSupplierCheck          cron.EntryID
 	entryIDQueueDownloader        cron.EntryID
 	entryIDScanPlayedVideoSubInfo cron.EntryID
+	entryIDUploadPlayedVideoSub   cron.EntryID
 }
 
 func NewCronHelper(fileDownloader *file_downloader.FileDownloader) *CronHelper {
@@ -110,23 +114,32 @@ func (ch *CronHelper) Start(runImmediately bool) {
 	// 这个暂时无法被取消执行
 	ch.entryIDScanVideoProcess, err = ch.c.AddFunc(ch.Settings.CommonSettings.ScanInterval, ch.scanVideoProcessAdd2DownloadQueue)
 	if err != nil {
-		ch.log.Panicln("CronHelper scanVideoProcessAdd2DownloadQueue, Cron entryID:", ch.entryIDScanVideoProcess, "Error:", err)
+		ch.log.Panicln("CronHelper scanVideoProcessAdd2DownloadQueue, scanVideoProcessAdd2DownloadQueue Cron entryID:", ch.entryIDScanVideoProcess, "Error:", err)
 	}
 	// 这个可以由 ch.Downloader.Cancel() 取消执行
 	ch.entryIDSupplierCheck, err = ch.c.AddFunc("@every 1h", ch.Downloader.SupplierCheck)
 	if err != nil {
-		ch.log.Panicln("CronHelper SupplierCheck, Cron entryID:", ch.entryIDSupplierCheck, "Error:", err)
+		ch.log.Panicln("CronHelper SupplierCheck, SupplierCheck Cron entryID:", ch.entryIDSupplierCheck, "Error:", err)
 	}
 	// 这个可以由 ch.Downloader.Cancel() 取消执行
 	ch.entryIDQueueDownloader, err = ch.c.AddFunc("@every 15s", ch.Downloader.QueueDownloader)
 	if err != nil {
-		ch.log.Panicln("CronHelper QueueDownloader, Cron entryID:", ch.entryIDQueueDownloader, "Error:", err)
+		ch.log.Panicln("CronHelper QueueDownloader, QueueDownloader Cron entryID:", ch.entryIDQueueDownloader, "Error:", err)
 	}
 	// 这个可以由 ch.scanPlayedVideoSubInfo.Cancel() 取消执行
 	ch.entryIDScanPlayedVideoSubInfo, err = ch.c.AddFunc("@every 24h", ch.scanPlayedVideoSub)
 	if err != nil {
-		ch.log.Panicln("CronHelper QueueDownloader, Cron entryID:", ch.entryIDScanPlayedVideoSubInfo, "Error:", err)
+		ch.log.Panicln("CronHelper QueueDownloader, scanPlayedVideoSub Cron entryID:", ch.entryIDScanPlayedVideoSubInfo, "Error:", err)
 	}
+	// 字幕的上传逻辑
+	if ch.Settings.ExperimentalFunction.ShareSubSettings.ShareSubEnabled == true {
+
+		ch.entryIDUploadPlayedVideoSub, err = ch.c.AddFunc("@every 5m", ch.uploadPlayedVideoSub)
+		if err != nil {
+			ch.log.Panicln("CronHelper QueueDownloader, uploadPlayedVideoSub Cron entryID:", ch.entryIDUploadPlayedVideoSub, "Error:", err)
+		}
+	}
+
 	// ----------------------------------------------
 	if runImmediately == true {
 		// 是否在定时器开启前先执行一次视频扫描任务
@@ -231,6 +244,72 @@ func (ch *CronHelper) scanPlayedVideoSub() {
 	}
 }
 
+// uploadPlayedVideoSub  上传字幕的定时器
+func (ch *CronHelper) uploadPlayedVideoSub() {
+
+	// 找出没有上传过的字幕列表
+	var notUploadedVideoSubInfos []models.VideoSubInfo
+	dao.GetDb().Where("is_send = ?", false).Limit(1).Find(&notUploadedVideoSubInfos)
+
+	if len(notUploadedVideoSubInfos) < 1 {
+		ch.log.Debugln("No notUploadedVideoSubInfos")
+		return
+	}
+	// 问询这个字幕是否上传过了,如果没有就需要进入上传的队列
+	askForUploadReply, err := ch.FileDownloader.SubtitleBestApi.AskFroUpload(notUploadedVideoSubInfos[0].SHA256)
+	if err != nil {
+		ch.log.Errorln(fmt.Errorf("AskFroUpload err: %v", err))
+		return
+	}
+	if askForUploadReply.Status == 3 {
+		// 上传过了,直接标记本地的 is_send 字段为 true
+		notUploadedVideoSubInfos[0].IsSend = true
+		dao.GetDb().Save(&notUploadedVideoSubInfos[0])
+		ch.log.Infoln("Subtitle has been uploaded, so will not upload again")
+		return
+	} else if askForUploadReply.Status == 4 {
+		// 上传队列满了,等待下次定时器触发
+		ch.log.Infoln("Subtitle upload queue is full, will try ask upload again")
+		return
+	} else if askForUploadReply.Status == 2 {
+		// 这个上传任务已经在队列中了,也许有其他人也需要上传这个字幕,或者本机排队的时候故障了,重启也可能遇到这个故障
+		ch.log.Infoln("Subtitle is int the queue")
+		return
+	} else if askForUploadReply.Status == 1 {
+		// 正确放入了队列,然后需要按规划的时间进行上传操作
+		// 这里可能需要执行耗时操作来等待到安排的时间点进行字幕的上传,不能直接长时间的 Sleep 操作
+		// 每次 Sleep 1s 然后就判断一次定时器是否还允许允许,如果不运行了,那么也就需要退出循环
+
+		// 得到目标时间与当前时间的差值,单位是s
+		waitTime := askForUploadReply.ScheduledUnixTime - time.Now().Unix()
+		if waitTime <= 0 {
+			waitTime = 5
+		}
+		var sleepCounter int64
+		sleepCounter = 0
+		normalStatus := false
+		for ch.cronHelperRunning == true {
+			if sleepCounter > waitTime {
+				normalStatus = true
+				break
+			}
+			time.Sleep(1 * time.Second)
+			sleepCounter++
+		}
+		if normalStatus == false || ch.cronHelperRunning == false {
+			// 说明不是正常跳出来的,是结束定时器来执行的
+			ch.log.Infoln("uploadPlayedVideoSub early termination")
+			return
+		}
+		// 发送字幕
+
+	} else {
+		// 不是预期的返回值,需要报警
+		ch.log.Errorln(fmt.Errorf("AskFroUpload Not the expected return value, Status: %d, Message: %v", askForUploadReply.Status, askForUploadReply.Message))
+		return
+	}
+}
+
 func (ch *CronHelper) CronHelperRunning() bool {
 
 	defer func() {

+ 54 - 0
internal/pkg/subtitle_best_api/media_info.go

@@ -0,0 +1,54 @@
+package subtitle_best_api
+
+/*
+	{
+		"id": "tt7278862",
+		"source": "imdb",
+		"video_type": "series"
+	}
+
+	{
+		"id": "503235",
+		"source": "tmdb",
+		"video_type": "movie"
+	}
+*/
+type MediaInfoReq struct {
+	Id        string `json:"id"`
+	Source    string `json:"source"`     // options=imdb|tmdb
+	VideoType string `json:"video_type"` // ,options=movie|series
+}
+
+/*
+	{
+		"status": 1,
+		"message": "",
+		"tmdb_id": "503235",
+		"original_title": "邪不压正",
+		"original_language": "zh",
+		"title_en": "Hidden Man",
+		"title_cn": "邪不压正",
+		"year": "2018-07-13"
+	}
+
+	{
+		"status": 1,
+		"message": "",
+		"tmdb_id": "78154",
+		"original_title": "L'amica geniale",
+		"original_language": "it",
+		"title_en": "My Brilliant Friend",
+		"title_cn": "我的天才女友",
+		"year": "2018-11-18"
+	}
+*/
+type MediaInfoReply struct {
+	Status           int    `json:"status"` // 0 失败,1 成功,2 在队列中等待查询
+	Message          string `json:"message"`
+	TMDBId           string `json:"tmdb_id,omitempty"`
+	OriginalTitle    string `json:"original_title,omitempty"`
+	OriginalLanguage string `json:"original_language,omitempty"`
+	TitleEN          string `json:"title_en,omitempty"`
+	TitleCN          string `json:"title_cn,omitempty"`
+	Year             string `json:"year,omitempty"`
+}

+ 25 - 46
internal/pkg/subtitle_best_api/subtitle_best_api.go

@@ -33,7 +33,7 @@ func (s *SubtitleBestApi) GetMediaInfo(id, source, videoType string, _proxySetti
 		return nil, errors.New(fmt.Sprintf("AESIv16 is not set, %s", s.authKey.AESIv16))
 	}
 
-	const postUrl = "https://api.subtitle.best/v1/media-info"
+	const postUrl = webUrlBase + "/v1/media-info"
 	httpClient, err := my_util.NewHttpClient(_proxySettings...)
 	if err != nil {
 		return nil, err
@@ -61,55 +61,34 @@ func (s *SubtitleBestApi) GetMediaInfo(id, source, videoType string, _proxySetti
 	return &mediaInfoReply, nil
 }
 
-/*
-	{
-		"id": "tt7278862",
-		"source": "imdb",
-		"video_type": "series"
-	}
+func (s SubtitleBestApi) AskFroUpload(subSha256 string, _proxySettings ...*settings.ProxySettings) (*AskForUploadReply, error) {
 
-	{
-		"id": "503235",
-		"source": "tmdb",
-		"video_type": "movie"
+	const postUrl = webUrlBase + "/v1/media-info"
+	httpClient, err := my_util.NewHttpClient(_proxySettings...)
+	if err != nil {
+		return nil, err
 	}
-*/
-type MediaInfoReq struct {
-	Id        string `json:"id"`
-	Source    string `json:"source"`     // options=imdb|tmdb
-	VideoType string `json:"video_type"` // ,options=movie|series
-}
 
-/*
-	{
-		"status": 1,
-		"message": "",
-		"tmdb_id": "503235",
-		"original_title": "邪不压正",
-		"original_language": "zh",
-		"title_en": "Hidden Man",
-		"title_cn": "邪不压正",
-		"year": "2018-07-13"
+	authKey, err := s.randomAuthKey.GetAuthKey()
+	if err != nil {
+		return nil, err
 	}
 
-	{
-		"status": 1,
-		"message": "",
-		"tmdb_id": "78154",
-		"original_title": "L'amica geniale",
-		"original_language": "it",
-		"title_en": "My Brilliant Friend",
-		"title_cn": "我的天才女友",
-		"year": "2018-11-18"
+	var askForUploadReply AskForUploadReply
+	_, err = httpClient.R().
+		SetHeader("Authorization", "beer "+authKey).
+		SetBody(AskForUploadReq{
+			SubSha256: subSha256,
+		}).
+		SetResult(&askForUploadReply).
+		Post(postUrl)
+	if err != nil {
+		return nil, err
 	}
-*/
-type MediaInfoReply struct {
-	Status           int    `json:"status"` // 0 失败,1 成功,2 在队列中等待查询
-	Message          string `json:"message"`
-	TMDBId           string `json:"tmdb_id,omitempty"`
-	OriginalTitle    string `json:"original_title,omitempty"`
-	OriginalLanguage string `json:"original_language,omitempty"`
-	TitleEN          string `json:"title_en,omitempty"`
-	TitleCN          string `json:"title_cn,omitempty"`
-	Year             string `json:"year,omitempty"`
+
+	return &askForUploadReply, nil
 }
+
+const (
+	webUrlBase = "https://api.subtitle.best"
+)

+ 11 - 0
internal/pkg/subtitle_best_api/upload_hub.go

@@ -0,0 +1,11 @@
+package subtitle_best_api
+
+type AskForUploadReq struct {
+	SubSha256 string `json:"sub_sha256"`
+}
+
+type AskForUploadReply struct {
+	Status            int    `json:"status"` // 0 失败,1 成功,2 放入了队列,根据返回的时间再上传,3 已经存在,无需上传,本地标记上传了,4 上传队列满了,需要等待
+	Message           string `json:"message"`
+	ScheduledUnixTime int64  `json:"scheduled_unix_time,omitempty"`
+}