feat: code refactor and support season pack write .plexmatch file

This commit is contained in:
Simon Ding
2024-08-12 22:19:57 +08:00
parent 9632ca45b3
commit 081338df24
11 changed files with 374 additions and 31 deletions

View File

@@ -3,24 +3,30 @@ package core
import (
"bytes"
"fmt"
"github.com/pkg/errors"
"os"
"path/filepath"
"polaris/db"
"polaris/ent/media"
storage1 "polaris/ent/storage"
"polaris/log"
"polaris/pkg/metadata"
"polaris/pkg/notifier"
"polaris/pkg/storage"
"polaris/pkg/utils"
"slices"
"strings"
"github.com/pkg/errors"
)
func (c *Client) writePlexmatch(seriesId int, episodeId int, targetDir, name string) error {
func (c *Client) writePlexmatch(historyId int) error {
if !c.plexmatchEnabled() {
return nil
}
series, err := c.db.GetMedia(seriesId)
his := c.db.GetHistory(historyId)
series, err := c.db.GetMedia(his.MediaID)
if err != nil {
return err
}
@@ -47,24 +53,44 @@ func (c *Client) writePlexmatch(seriesId int, episodeId int, targetDir, name str
}
}
//season plexmatch file
ep, err := c.db.GetEpisodeByID(episodeId)
if err != nil {
return errors.Wrap(err, "query episode")
}
buff := bytes.Buffer{}
seasonPlex := filepath.Join(targetDir, ".plexmatch")
seasonPlex := filepath.Join(his.TargetDir, ".plexmatch")
data, err := st.ReadFile(seasonPlex)
if err != nil {
log.Infof("read season plexmatch: %v", err)
} else {
buff.Write(data)
}
if strings.Contains(buff.String(), name) {
log.Debugf("already write plex episode line: %v", name)
return nil
if his.EpisodeID > 0 {
//single episode download
ep, err := c.db.GetEpisodeByID(his.EpisodeID)
if err != nil {
return errors.Wrap(err, "query episode")
}
if strings.Contains(buff.String(), ep.TargetFile) {
log.Debugf("already write plex episode line: %v", ep.TargetFile)
return nil
}
buff.WriteString(fmt.Sprintf("\nep: %d: %s\n", ep.EpisodeNumber, ep.TargetFile))
} else {
seasonNum, err := utils.SeasonId(his.TargetDir)
if err != nil {
return errors.Wrap(err, "no season id")
}
allEpisodes, err := c.db.GetSeasonEpisodes(his.MediaID, seasonNum)
if err != nil {
return errors.Wrap(err, "query season episode")
}
for _, ep := range allEpisodes {
if strings.Contains(buff.String(), ep.TargetFile) {
log.Debugf("already write plex episode line: %v", ep.TargetFile)
continue
}
buff.WriteString(fmt.Sprintf("\nep: %d: %s\n", ep.EpisodeNumber, ep.TargetFile))
}
}
buff.WriteString(fmt.Sprintf("\nep: %d: %s\n", ep.EpisodeNumber, name))
log.Infof("write season plexmatch file content: %s", buff.String())
return st.WriteFile(seasonPlex, buff.Bytes())
}
@@ -128,3 +154,63 @@ func (c *Client) sendMsg(msg string) {
log.Debugf("send message to %s success, msg is %s", cl.Name, msg)
}
}
func (c *Client) findEpisodeFilesPreMoving(historyId int) error {
his := c.db.GetHistory(historyId)
isSingleEpisode := his.EpisodeID > 0
downloadDir := c.db.GetDownloadDir()
task := c.tasks[historyId]
target := filepath.Join(downloadDir, task.Name())
fi, err := os.Stat(target)
if err != nil {
return errors.Wrapf(err, "read dir %v", target)
}
if isSingleEpisode {
if fi.IsDir() {
//download single episode in dir
//TODO
} else {
//is file
if err := c.db.UpdateEpisodeTargetFile(his.EpisodeID, fi.Name()); err != nil {
log.Errorf("writing downloaded file name to db error: %v", err)
}
}
} else {
if fi.IsDir() {
return fmt.Errorf("not season pack downloaded")
}
seasonNum, err := utils.SeasonId(his.TargetDir)
if err != nil {
return errors.Wrap(err, "no season id")
}
files, err := os.ReadDir(target)
if err != nil {
return err
}
for _, f := range files {
if f.IsDir() { //want media file
continue
}
excludedExt := []string{".txt", ".srt", ".ass", ".sub"}
ext := filepath.Ext(f.Name())
if slices.Contains(excludedExt, strings.ToLower(ext)) {
continue
}
meta := metadata.ParseTv(f.Name())
if meta.Episode > 0 {
//episode exists
ep, err := c.db.GetEpisode(his.MediaID, seasonNum, meta.Episode)
if err != nil {
return err
}
if err := c.db.UpdateEpisodeTargetFile(ep.ID, f.Name()); err != nil {
return errors.Wrap(err, "update episode file")
}
}
}
}
return nil
}

View File

@@ -61,15 +61,25 @@ func (c *Client) checkTasks() {
}
log.Infof("task is done: %v", t.Name())
c.sendMsg(fmt.Sprintf(message.DownloadComplete, t.Name()))
go func() {
if err := c.moveCompletedTask(id); err != nil {
log.Infof("post tasks for id %v fail: %v", id, err)
}
}()
go c.postTaskProcessing(id)
}
}
}
func (c *Client) postTaskProcessing(id int) {
if err := c.findEpisodeFilesPreMoving(id); err != nil {
log.Errorf("finding all episode file error: %v", err)
} else {
if err := c.writePlexmatch(id); err != nil {
log.Errorf("write plexmatch file error: %v", err)
}
}
if err := c.moveCompletedTask(id); err != nil {
log.Infof("post tasks for id %v fail: %v", id, err)
}
}
func (c *Client) moveCompletedTask(id int) (err1 error) {
torrent := c.tasks[id]
r := c.db.GetHistory(id)
@@ -119,11 +129,6 @@ func (c *Client) moveCompletedTask(id int) (err1 error) {
return err
}
// .plexmatch file
if err := c.writePlexmatch(r.MediaID, r.EpisodeID, r.TargetDir, torrentName); err != nil {
log.Errorf("create .plexmatch file error: %v", err)
}
//如果种子是路径,则会把路径展开,只移动文件,类似 move dir/* dir2/, 如果种子是文件,则会直接移动文件,类似 move file dir/
if err := stImpl.Copy(filepath.Join(c.db.GetDownloadDir(), torrentName), r.TargetDir); err != nil {
return errors.Wrap(err, "move file")