Explorar o código

保存进度,还没测试完

Signed-off-by: allan716 <[email protected]>
allan716 %!s(int64=3) %!d(string=hai) anos
pai
achega
9bb5220745

+ 45 - 23
internal/logic/emby_helper/embyhelper.go

@@ -25,7 +25,7 @@ import (
 )
 
 type EmbyHelper struct {
-	embyApi  *embyHelper.EmbyApi
+	EmbyApi  *embyHelper.EmbyApi
 	log      *logrus.Logger
 	settings *settings.Settings
 	timeOut  time.Duration
@@ -34,7 +34,7 @@ type EmbyHelper struct {
 
 func NewEmbyHelper(_log *logrus.Logger, _settings *settings.Settings) *EmbyHelper {
 	em := EmbyHelper{log: _log, settings: _settings}
-	em.embyApi = embyHelper.NewEmbyApi(_log, _settings.EmbySettings)
+	em.EmbyApi = embyHelper.NewEmbyApi(_log, _settings.EmbySettings)
 	em.timeOut = 60 * time.Second
 	return &em
 }
@@ -118,7 +118,7 @@ func (em *EmbyHelper) GetRecentlyAddVideoListWithNoChineseSubtitle(needForcedSca
 // GetRecentlyAddVideoList 获取最近新添加的视频
 func (em *EmbyHelper) GetRecentlyAddVideoList() ([]emby.EmbyMixInfo, []emby.EmbyMixInfo, error) {
 	// 获取最近的影片列表
-	items, err := em.embyApi.GetRecentlyItems()
+	items, err := em.EmbyApi.GetRecentlyItems()
 	if err != nil {
 		return nil, nil, err
 	}
@@ -174,14 +174,14 @@ func (em *EmbyHelper) GetVideoIDPlayedMap() map[string]bool {
 	videoIDPlayedMap := make(map[string]bool)
 	// 获取有那些用户
 	var userIds emby.EmbyUsers
-	userIds, err := em.embyApi.GetUserIdList()
+	userIds, err := em.EmbyApi.GetUserIdList()
 	if err != nil {
 		em.log.Errorln("IsVideoIDPlayed - GetUserIdList error:", err)
 		return videoIDPlayedMap
 	}
 	// 所有用户观看过的视频有那些
 	for _, item := range userIds.Items {
-		tmpRecItems, err := em.embyApi.GetRecentItemsByUserID(item.Id)
+		tmpRecItems, err := em.EmbyApi.GetRecentItemsByUserID(item.Id)
 		if err != nil {
 			em.log.Errorln("IsVideoIDPlayed - GetRecentItemsByUserID, UserID:", item.Id, "error:", err)
 			return videoIDPlayedMap
@@ -205,13 +205,13 @@ func (em *EmbyHelper) GetPlayedItemsSubtitle() (map[string]string, map[string]st
 	var userPlayedItemsList = make([]emby.UserPlayedItems, 0)
 	// 获取有那些用户
 	var userIds emby.EmbyUsers
-	userIds, err := em.embyApi.GetUserIdList()
+	userIds, err := em.EmbyApi.GetUserIdList()
 	if err != nil {
 		return nil, nil, err
 	}
 	// 所有用户观看过的视频有那些,需要分用户统计出来
 	for _, item := range userIds.Items {
-		tmpRecItems, err := em.embyApi.GetRecentItemsByUserID(item.Id)
+		tmpRecItems, err := em.EmbyApi.GetRecentItemsByUserID(item.Id)
 		if err != nil {
 			return nil, nil, err
 		}
@@ -240,12 +240,12 @@ func (em *EmbyHelper) GetPlayedItemsSubtitle() (map[string]string, map[string]st
 
 		for _, item := range playedItems.Items {
 
-			videoInfoByUserId, err := em.embyApi.GetItemVideoInfoByUserId(playedItems.UserID, item.Id)
+			videoInfoByUserId, err := em.EmbyApi.GetItemVideoInfoByUserId(playedItems.UserID, item.Id)
 			if err != nil {
 				return nil, nil, err
 			}
 
-			videoInfo, err := em.embyApi.GetItemVideoInfo(item.Id)
+			videoInfo, err := em.EmbyApi.GetItemVideoInfo(item.Id)
 			if err != nil {
 				return nil, nil, err
 			}
@@ -300,16 +300,38 @@ func (em *EmbyHelper) GetPlayedItemsSubtitle() (map[string]string, map[string]st
 
 // RefreshEmbySubList 字幕下载完毕一次,就可以触发一次这个。并发 6 线程去刷新
 func (em *EmbyHelper) RefreshEmbySubList() (bool, error) {
-	if em.embyApi == nil {
+	if em.EmbyApi == nil {
 		return false, nil
 	}
-	err := em.embyApi.RefreshRecentlyVideoInfo()
+	err := em.EmbyApi.RefreshRecentlyVideoInfo()
 	if err != nil {
 		return false, err
 	}
 	return true, nil
 }
 
+func (em *EmbyHelper) IsVideoPlayed(videoID string) (bool, error) {
+
+	// 获取有那些用户
+	var userIds emby.EmbyUsers
+	userIds, err := em.EmbyApi.GetUserIdList()
+	if err != nil {
+		return false, err
+	}
+	// 所有用户观看过的视频有那些,需要分用户统计出来
+	for _, item := range userIds.Items {
+		videoInfo, err := em.EmbyApi.GetItemVideoInfoByUserId(item.Id, videoID)
+		if err != nil {
+			return false, err
+		}
+		if videoInfo.UserData.Played == true {
+			return true, nil
+		}
+	}
+
+	return false, nil
+}
+
 // findMappingPath 从 Emby 内置路径匹配到物理路径,返回,需要替换的前缀,以及替换到的前缀
 // X:\电影    - /mnt/share1/电影
 // X:\连续剧  - /mnt/share1/连续剧
@@ -372,12 +394,12 @@ func (em *EmbyHelper) getMoreVideoInfo(videoID string, isMovieOrSeries bool) (*e
 
 	if isMovieOrSeries == true {
 		// 电影的情况
-		info, err := em.embyApi.GetItemVideoInfo(videoID)
+		info, err := em.EmbyApi.GetItemVideoInfo(videoID)
 		if err != nil {
 			return nil, err
 		}
 
-		ancs, err := em.embyApi.GetItemAncestors(videoID)
+		ancs, err := em.EmbyApi.GetItemAncestors(videoID)
 		if err != nil {
 			return nil, err
 		}
@@ -387,7 +409,7 @@ func (em *EmbyHelper) getMoreVideoInfo(videoID string, isMovieOrSeries bool) (*e
 		return &mixInfo, nil
 	} else {
 		// 连续剧的情况,需要从一集对算到 series 目录,得到内部 series 的 ID,然后再得到 IMDB ID
-		ancs, err := em.embyApi.GetItemAncestors(videoID)
+		ancs, err := em.EmbyApi.GetItemAncestors(videoID)
 		if err != nil {
 			return nil, err
 		}
@@ -405,17 +427,17 @@ func (em *EmbyHelper) getMoreVideoInfo(videoID string, isMovieOrSeries bool) (*e
 			return nil, nil
 		}
 		// 这里的目标是从 Emby 获取 IMDB ID
-		info, err := em.embyApi.GetItemVideoInfo(ancs[ancestorIndex].ID)
+		info, err := em.EmbyApi.GetItemVideoInfo(ancs[ancestorIndex].ID)
 		if err != nil {
 			return nil, err
 		}
 		nowSeriesIMDBID := info.ProviderIds.Imdb
 		// 然后还是要跟电影一样的使用 Video ID 去获取 Ancestors 和 VideoInfo,而上面一步获取的是这个 Series 的 ID
-		info, err = em.embyApi.GetItemVideoInfo(videoID)
+		info, err = em.EmbyApi.GetItemVideoInfo(videoID)
 		if err != nil {
 			return nil, err
 		}
-		ancs, err = em.embyApi.GetItemAncestors(videoID)
+		ancs, err = em.EmbyApi.GetItemAncestors(videoID)
 		if err != nil {
 			return nil, err
 		}
@@ -823,12 +845,12 @@ func (em *EmbyHelper) filterNoChineseSubVideoList(videoList []emby.EmbyMixInfo)
 func (em *EmbyHelper) GetInternalEngSubAndExChineseEnglishSub(videoId string) (bool, []emby.SubInfo, []emby.SubInfo, error) {
 
 	// 先刷新以下这个资源,避免找到的字幕不存在了
-	err := em.embyApi.UpdateVideoSubList(videoId)
+	err := em.EmbyApi.UpdateVideoSubList(videoId)
 	if err != nil {
 		return false, nil, nil, err
 	}
 	// 获取这个资源的信息
-	videoInfo, err := em.embyApi.GetItemVideoInfo(videoId)
+	videoInfo, err := em.EmbyApi.GetItemVideoInfo(videoId)
 	if err != nil {
 		return false, nil, nil, err
 	}
@@ -900,7 +922,7 @@ func (em *EmbyHelper) GetInternalEngSubAndExChineseEnglishSub(videoId string) (b
 		var tmpSubContentLenList = make([]int, 0)
 		for _, index := range insideEngSUbIndexList {
 			// TODO 这里默认是去 Emby 去拿字幕,但是其实可以缓存在视频文件同级的目录下,这样后续就无需多次下载了,毕竟每次下载都需要读取完整的视频
-			subFileData, err := em.embyApi.GetSubFileData(videoId, mediaSourcesId, fmt.Sprintf("%d", index), common2.SubExtSRT)
+			subFileData, err := em.EmbyApi.GetSubFileData(videoId, mediaSourcesId, fmt.Sprintf("%d", index), common2.SubExtSRT)
 			if err != nil {
 				return false, nil, nil, err
 			}
@@ -920,7 +942,7 @@ func (em *EmbyHelper) GetInternalEngSubAndExChineseEnglishSub(videoId string) (b
 		if i == 1 {
 			tmpExt = common2.SubExtASS
 		}
-		subFileData, err := em.embyApi.GetSubFileData(videoId, mediaSourcesId, fmt.Sprintf("%d", InsideEngSubIndex), tmpExt)
+		subFileData, err := em.EmbyApi.GetSubFileData(videoId, mediaSourcesId, fmt.Sprintf("%d", InsideEngSubIndex), tmpExt)
 		if err != nil {
 			return false, nil, nil, err
 		}
@@ -930,7 +952,7 @@ func (em *EmbyHelper) GetInternalEngSubAndExChineseEnglishSub(videoId string) (b
 	}
 	// 再下载外置的
 	for i, subInfo := range exSubList {
-		subFileData, err := em.embyApi.GetSubFileData(videoId, mediaSourcesId, fmt.Sprintf("%d", subInfo.EmbyStreamIndex), subInfo.Ext)
+		subFileData, err := em.EmbyApi.GetSubFileData(videoId, mediaSourcesId, fmt.Sprintf("%d", subInfo.EmbyStreamIndex), subInfo.Ext)
 		if err != nil {
 			return false, nil, nil, err
 		}
@@ -944,7 +966,7 @@ func (em *EmbyHelper) GetInternalEngSubAndExChineseEnglishSub(videoId string) (b
 func (em *EmbyHelper) CheckPath(pathType string) ([]string, error) {
 
 	// 获取最近的影片列表
-	items, err := em.embyApi.GetRecentlyItems()
+	items, err := em.EmbyApi.GetRecentlyItems()
 	if err != nil {
 		return nil, err
 	}

+ 25 - 43
internal/logic/emby_helper/embyhelper_test.go

@@ -1,21 +1,25 @@
 package emby_helper
 
 import (
+	embyHelper "github.com/allanpk716/ChineseSubFinder/internal/pkg/emby_api"
+	"github.com/allanpk716/ChineseSubFinder/internal/pkg/log_helper"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/settings"
-	"reflect"
+	"github.com/sirupsen/logrus"
+	"sync"
 	"testing"
+	"time"
 )
 
 var ec = settings.EmbySettings{
-	//AddressUrl:            "http://192.168.50.252:xxx",
-	//APIKey:                "xxx",
-	//MaxRequestVideoNumber: 100,
-	//MoviePathsMapping: map[string]string{
-	//	"X:\\电影": "/mnt/share1/电影",
-	//},
-	//SeriesPathsMapping: map[string]string{
-	//	"X:\\连续剧": "/mnt/share1/连续剧",
-	//},
+	AddressUrl:            "http://192.168.50.252:xxx",
+	APIKey:                "xxx",
+	MaxRequestVideoNumber: 100,
+	MoviePathsMapping: map[string]string{
+		"X:\\电影": "/mnt/share1/电影",
+	},
+	SeriesPathsMapping: map[string]string{
+		"X:\\连续剧": "/mnt/share1/连续剧",
+	},
 }
 
 // TODO 暂不方便在其他环境进行单元测试
@@ -68,39 +72,6 @@ func TestEmbyHelper_GetInternalEngSubAndExSub(t *testing.T) {
 	//println(internalEngSub[0].FileName, exCh_EngSub[0].FileName)
 }
 
-func Test_sortStringSliceByLength(t *testing.T) {
-	type args struct {
-		m []string
-	}
-	tests := []struct {
-		name string
-		args args
-		want PathSlices
-	}{
-		{
-			name: "00",
-			args: args{
-				[]string{"/aa/bb/cc", "/aa", "/aa/bb"},
-			},
-			want: []PathSlice{{
-				Path: "/aa/bb/cc",
-			}, {
-				Path: "/aa/bb",
-			}, {
-				Path: "/aa",
-			},
-			},
-		},
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := sortStringSliceByLength(tt.args.m); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("sortStringSliceByLength() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
 // TODO 暂不方便在其他环境进行单元测试
 func TestEmbyHelper_GetPlayedItemsSubtitle(t *testing.T) {
 
@@ -134,3 +105,14 @@ func TestEmbyHelper_GetPlayedItemsSubtitle(t *testing.T) {
 func TestEmbyHelper_GetRecentlyAddVideoList1(t *testing.T) {
 
 }
+
+func TestEmbyHelper_IsVideoPlayed(t *testing.T) {
+
+	em := NewEmbyHelper(log_helper.GetLogger4Tester(), *ec)
+	moviePhyFPathMap, seriesPhyFPathMap, err := em.GetPlayedItemsSubtitle()
+	if err != nil {
+		t.Fatal(err)
+	}
+	played, err := ec.IsVideoPlayed(tt.args.videoID)
+
+}

+ 30 - 7
internal/pkg/downloader/downloader.go

@@ -4,6 +4,7 @@ import (
 	"errors"
 	"fmt"
 	"github.com/allanpk716/ChineseSubFinder/internal/ifaces"
+	embyHelper "github.com/allanpk716/ChineseSubFinder/internal/logic/emby_helper"
 	"github.com/allanpk716/ChineseSubFinder/internal/logic/file_downloader"
 	markSystem "github.com/allanpk716/ChineseSubFinder/internal/logic/mark_system"
 	"github.com/allanpk716/ChineseSubFinder/internal/logic/pre_download_process"
@@ -11,7 +12,6 @@ import (
 	subSupplier "github.com/allanpk716/ChineseSubFinder/internal/logic/sub_supplier"
 	"github.com/allanpk716/ChineseSubFinder/internal/logic/sub_supplier/zimuku"
 	"github.com/allanpk716/ChineseSubFinder/internal/logic/sub_timeline_fixer"
-	"github.com/allanpk716/ChineseSubFinder/internal/pkg/emby_api"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/log_helper"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/my_folder"
 	"github.com/allanpk716/ChineseSubFinder/internal/pkg/my_util"
@@ -41,7 +41,7 @@ type Downloader struct {
 	subTimelineFixerHelperEx *sub_timeline_fixer.SubTimelineFixerHelperEx // 字幕时间轴校正
 	downloaderLock           sync.Mutex                                   // 取消执行 task control 的 Lock
 	downloadQueue            *task_queue.TaskQueue                        // 需要下载的视频的队列
-	embyApi                  *emby_api.EmbyApi                            // 用于下载完毕字幕的刷新
+	embyHelper               *embyHelper.EmbyHelper                       // Emby 的实例
 }
 
 func NewDownloader(inSubFormatter ifaces.ISubFormatter, fileDownloader *file_downloader.FileDownloader, downloadQueue *task_queue.TaskQueue) *Downloader {
@@ -78,7 +78,7 @@ func NewDownloader(inSubFormatter ifaces.ISubFormatter, fileDownloader *file_dow
 	downloader.ctx, downloader.cancel = context.WithCancel(context.Background())
 	// 用于字幕下载后的刷新
 	if downloader.settings.EmbySettings.Enable == true {
-		downloader.embyApi = emby_api.NewEmbyApi(downloader.log, downloader.settings.EmbySettings)
+		downloader.embyHelper = embyHelper.NewEmbyHelper(downloader.log, downloader.settings)
 	}
 
 	return &downloader
@@ -183,6 +183,29 @@ func (d *Downloader) QueueDownloader() {
 		d.log.Debugln("Download Queue Is Empty, Skip This Time")
 		return
 	}
+	// 在拿出来后,如果是有内部媒体服务器媒体 ID 的,那么就去查询是否已经观看过了
+	isPlayed, err := d.embyHelper.IsVideoPlayed(oneJob.MediaServerInsideVideoID)
+	if err != nil {
+		d.log.Errorln("d.embyHelper.IsVideoPlayed()", oneJob.VideoFPath, err)
+		return
+	}
+
+	if isPlayed == true {
+		// 播放过了,那么就标记 ignore
+		oneJob.JobStatus = taskQueue2.Ignore
+		bok, err = d.downloadQueue.Update(oneJob)
+		if err != nil {
+			d.log.Errorln("d.downloadQueue.Update()", err)
+			return
+		}
+		if bok == false {
+			d.log.Errorln("d.downloadQueue.Update() Failed")
+			return
+		}
+		d.log.Infoln("Is Played, Ignore This Job")
+		return
+	}
+
 	// 取出来后,需要标记为正在下载
 	oneJob.JobStatus = taskQueue2.Downloading
 	bok, err = d.downloadQueue.Update(oneJob)
@@ -297,8 +320,8 @@ func (d *Downloader) movieDlFunc(ctx context.Context, job taskQueue2.OneJob, dow
 	d.downloadQueue.AutoDetectUpdateJobStatus(job, nil)
 
 	// TODO 刷新字幕,这里是 Emby 的,如果是其他的,需要再对接对应的媒体服务器
-	if d.settings.EmbySettings.Enable == true && d.embyApi != nil && job.MediaServerInsideVideoID != "" {
-		err = d.embyApi.UpdateVideoSubList(job.MediaServerInsideVideoID)
+	if d.settings.EmbySettings.Enable == true && d.embyHelper != nil && job.MediaServerInsideVideoID != "" {
+		err = d.embyHelper.EmbyApi.UpdateVideoSubList(job.MediaServerInsideVideoID)
 		if err != nil {
 			d.log.Errorln("UpdateVideoSubList", job.VideoFPath, job.MediaServerInsideVideoID, "Error:", err)
 			return err
@@ -467,8 +490,8 @@ func (d *Downloader) seriesDlFunc(ctx context.Context, job taskQueue2.OneJob, do
 	// 哪怕有一个写入到本地成功了,也无需对本次任务报错
 	d.downloadQueue.AutoDetectUpdateJobStatus(job, nil)
 	// TODO 刷新字幕,这里是 Emby 的,如果是其他的,需要再对接对应的媒体服务器
-	if d.settings.EmbySettings.Enable == true && d.embyApi != nil && job.MediaServerInsideVideoID != "" {
-		err = d.embyApi.UpdateVideoSubList(job.MediaServerInsideVideoID)
+	if d.settings.EmbySettings.Enable == true && d.embyHelper != nil && job.MediaServerInsideVideoID != "" {
+		err = d.embyHelper.EmbyApi.UpdateVideoSubList(job.MediaServerInsideVideoID)
 		if err != nil {
 			d.log.Errorln("UpdateVideoSubList", job.SeriesRootDirPath, job.MediaServerInsideVideoID, job.Season, job.Episode, "Error:", err)
 			return err

+ 21 - 21
internal/pkg/emby_api/emby_api_test.go

@@ -8,7 +8,7 @@ import (
 var ec = settings.EmbySettings{
 	Enable:                true,
 	AddressUrl:            "http://192.168.50.252:8096",
-	APIKey:                "123",
+	APIKey:                "asdasda",
 	MaxRequestVideoNumber: 100,
 }
 
@@ -50,9 +50,28 @@ func TestEmbyHelper_GetItemsAncestors(t *testing.T) {
 	//println(items[0].Name, items[0].Path)
 }
 
+// TODO 暂不方便在其他环境进行单元测试
+func TestEmbyHelper_GetItemVideoInfo(t *testing.T) {
+	//em := NewEmbyApi(log_helper.GetLogger4Tester(), &ec)
+	//// 95813 -- 命运夜
+	//// 96564 -- The Bad Batch - S01E11
+	//// R&M S05E10  2 org english, 5 简英 145499
+	//// R&M 15430
+	//// 基地 S01E03 166840
+	//// 基地 S01E04 173354
+	//// 算牌人 166837
+	//// 327198
+	//videoInfo, err := em.GetItemVideoInfo("15430")
+	//if err != nil {
+	//	t.Fatal(err)
+	//}
+	//
+	//println(videoInfo.Name, videoInfo.Path, videoInfo.MediaSources[0].Id)
+}
+
 // TODO 暂不方便在其他环境进行单元测试
 func TestEmbyHelper_GetItemVideoInfoByUserId(t *testing.T) {
-	//em := NewEmbyApi(&ec)
+	//em := NewEmbyApi(log_helper.GetLogger4Tester(), &ec)
 	//// 95813 -- 命运夜
 	//// 96564 -- The Bad Batch - S01E11
 	//// 108766 -- R&M - S05E06
@@ -99,25 +118,6 @@ func TestEmbyHelper_GetUserIdList(t *testing.T) {
 	//}
 }
 
-// TODO 暂不方便在其他环境进行单元测试
-func TestEmbyHelper_GetItemVideoInfo(t *testing.T) {
-	//em := NewEmbyApi(&ec)
-	//// 95813 -- 命运夜
-	//// 96564 -- The Bad Batch - S01E11
-	//// R&M S05E10  2 org english, 5 简英 145499
-	//// R&M 15430
-	//// 基地 S01E03 166840
-	//// 基地 S01E04 173354
-	//// 算牌人 166837
-	//// 327198
-	//videoInfo, err := em.GetItemVideoInfo("15430")
-	//if err != nil {
-	//	t.Fatal(err)
-	//}
-	//
-	//println(videoInfo.Name, videoInfo.Path, videoInfo.MediaSources[0].Id)
-}
-
 // TODO 暂不方便在其他环境进行单元测试
 func TestEmbyApi_GetSubFileData(t *testing.T) {
 	//em := NewEmbyApi(config.GetConfig().EmbyConfig)