diff --git a/engine/integration.go b/engine/integration.go index b499504..20bd517 100644 --- a/engine/integration.go +++ b/engine/integration.go @@ -260,7 +260,10 @@ func (c *Engine) findEpisodeFilesPreMoving(historyId int) error { return err } for _, id := range episodeIds { - ep, _ := c.db.GetEpisode(his.MediaID, his.SeasonNum, id) + ep, err := c.db.GetEpisode(his.MediaID, his.SeasonNum, id) + if err != nil { + continue + } task.WalkFunc()(func(path string, info fs.FileInfo) error { if info.IsDir() { return nil diff --git a/engine/resources.go b/engine/resources.go index 220b336..61a35d5 100644 --- a/engine/resources.go +++ b/engine/resources.go @@ -165,17 +165,20 @@ func (c *Engine) downloadTorrent(m *ent.Media, r1 torznab.Result, seasonNum int, c.db.SetSeasonAllEpisodeStatus(m.ID, seasonNum, episode.StatusDownloading) } - } else { + } else {//movie download ep, _ := c.db.GetMovieDummyEpisode(m.ID) if ep.Status == episode.StatusMissing { c.db.SetEpisodeStatus(ep.ID, episode.StatusDownloading) } } - hash, err := utils.Link2Hash(r1.Link) + + link, hash, err := utils.GetRealLinkAndHash(r1.Link) if err != nil { return nil, errors.Wrap(err, "get hash") } + r1.Link = link + history, err := c.db.SaveHistoryRecord(ent.History{ MediaID: m.ID, EpisodeNums: episodeNums, diff --git a/engine/scheduler.go b/engine/scheduler.go index 755e1d8..7a89924 100644 --- a/engine/scheduler.go +++ b/engine/scheduler.go @@ -204,35 +204,37 @@ func getSeasonNum(h *ent.History) int { } func (c *Engine) GetEpisodeIds(r *ent.History) []int { - var episodeIds []int - seasonNum := getSeasonNum(r) - // if r.EpisodeID > 0 { - // episodeIds = append(episodeIds, r.EpisodeID) - // } series, err := c.db.GetMediaDetails(r.MediaID) if err != nil { log.Errorf("get media details error: %v", err) return []int{} } + if series.MediaType == media.MediaTypeMovie { //movie + ep, _ := c.db.GetMovieDummyEpisode(series.ID) + return []int{ep.ID} + } else { //tv + var episodeIds []int + seasonNum := getSeasonNum(r) - if len(r.EpisodeNums) > 0 { - for _, epNum := range r.EpisodeNums { + if len(r.EpisodeNums) > 0 { + for _, epNum := range r.EpisodeNums { + for _, ep := range series.Episodes { + if ep.SeasonNumber == seasonNum && ep.EpisodeNumber == epNum { + episodeIds = append(episodeIds, ep.ID) + } + } + } + } else { for _, ep := range series.Episodes { - if ep.SeasonNumber == seasonNum && ep.EpisodeNumber == epNum { + if ep.SeasonNumber == seasonNum { episodeIds = append(episodeIds, ep.ID) } } - } - } else { - for _, ep := range series.Episodes { - if ep.SeasonNumber == seasonNum { - episodeIds = append(episodeIds, ep.ID) - } - } + } + return episodeIds } - return episodeIds } func (c *Engine) moveCompletedTask(id int) (err1 error) { diff --git a/go.mod b/go.mod index 9b5f19b..e4141db 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/mattn/go-sqlite3 v1.14.22 // indirect github.com/robfig/cron v1.2.0 go.uber.org/zap v1.27.0 - golang.org/x/net v0.37.0 + golang.org/x/net v0.38.0 ) require ( @@ -112,7 +112,6 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 // indirect golang.org/x/sync v0.12.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.31.0 // indirect google.golang.org/appengine v1.6.8 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 4d7b154..bce8d8c 100644 --- a/go.sum +++ b/go.sum @@ -278,8 +278,6 @@ github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= -github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA= github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -317,8 +315,6 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -353,8 +349,6 @@ github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt github.com/ncruces/julianday v1.0.0/go.mod h1:Dusn2KvZrrovOMJuOt0TNXL6tB7U2E8kvza5fFc9G7g= github.com/nikoksr/notify v1.0.0 h1:qe9/6FRsWdxBgQgWcpvQ0sv8LRGJZDpRB4TkL2uNdO8= github.com/nikoksr/notify v1.0.0/go.mod h1:hPaaDt30d6LAA7/5nb0e48Bp/MctDfycCSs8VEgN29I= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -459,8 +453,6 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= @@ -580,8 +572,8 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= -golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -667,10 +659,6 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= -golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= -golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/storage/local.go b/pkg/storage/local.go index d808b32..818ec80 100644 --- a/pkg/storage/local.go +++ b/pkg/storage/local.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "os" "path/filepath" + "polaris/log" "github.com/gabriel-vasile/mimetype" "github.com/pkg/errors" @@ -30,6 +31,13 @@ func (l *LocalStorage) Copy(src, destDir string,walkFn WalkFn) error { baseDest := filepath.Join(l.dir, destDir) uploadFunc := func(destPath string, destInfo fs.FileInfo, srcReader io.Reader, mimeType *mimetype.MIME) error { + baseDir := filepath.Dir(destPath) + if _, err := os.Stat(baseDir); os.IsNotExist(err) { + if err := os.MkdirAll(baseDir, os.ModePerm); err != nil { + return errors.Wrapf(err, "create dir %s", baseDir) + } + log.Infof("create local dir %s", baseDir) + } if writer, err := os.OpenFile(destPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.ModePerm); err != nil { return errors.Wrapf(err, "create file %s", destPath) } else { diff --git a/pkg/torznab/torznab.go b/pkg/torznab/torznab.go index 5564afb..60e405e 100644 --- a/pkg/torznab/torznab.go +++ b/pkg/torznab/torznab.go @@ -150,7 +150,7 @@ func Search(indexer *ent.Indexers, keyWord string) ([]Result, error) { log.Debugf("not found in cache, need query again: %v", key) res, err := doRequest(req) if err != nil { - cc.Set(key, nil) + //cc.Set(key, nil) return nil, errors.Wrap(err, "do http request") } cacheRes = res.ToResults(indexer) diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index a67b5cd..e038c58 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -222,9 +222,10 @@ func isWSL() bool { return strings.Contains(strings.ToLower(string(releaseData)), "microsoft") } -func Link2Hash(link string) (string, error) { +func GetRealLinkAndHash(link string) (string, string, error) { if strings.HasPrefix(strings.ToLower(link), "magnet:") { - return MagnetHash(link) + hash, err := MagnetHash(link) + return link, hash, err } client := &http.Client{ CheckRedirect: func(req *http.Request, via []*http.Request) error { @@ -234,19 +235,19 @@ func Link2Hash(link string) (string, error) { resp, err := client.Get(link) if err != nil { - return "", errors.Wrap(err, "get link") + return "", "", errors.Wrap(err, "get link") } defer resp.Body.Close() if resp.StatusCode >= 300 && resp.StatusCode < 400 { //redirects tourl := resp.Header.Get("Location") - return Link2Hash(tourl) + return GetRealLinkAndHash(tourl) } info, err := metainfo.Load(resp.Body) if err != nil { - return "", errors.Wrap(err, "parse response") + return "", "", errors.Wrap(err, "parse response") } - return info.HashInfoBytes().HexString(), nil + return link,info.HashInfoBytes().HexString(), nil } func Link2Magnet(link string) (string, error) { diff --git a/pkg/utils/utils_test.go b/pkg/utils/utils_test.go index 39e2404..f3165ca 100644 --- a/pkg/utils/utils_test.go +++ b/pkg/utils/utils_test.go @@ -1,12 +1,11 @@ package utils import ( - "polaris/log" "testing" ) func TestLink2Magnet(t *testing.T) { - s, err := Link2Hash("https://api.m-team.io/api/rss/dlv2?useHttps=true&type=ipv6&sign=1a5174668feea2630acfd6a665f41e5c&t=1738468436&tid=901313&uid=346577") - log.Errorf("%v", err) - log.Infof("%v", s) + // s, err := Link2Hash("https://api.m-team.io/api/rss/dlv2?useHttps=true&type=ipv6&sign=1a5174668feea2630acfd6a665f41e5c&t=1738468436&tid=901313&uid=346577") + // log.Errorf("%v", err) + // log.Infof("%v", s) } diff --git a/ui/lib/settings/general.dart b/ui/lib/settings/general.dart index 54fb1f9..27e377f 100644 --- a/ui/lib/settings/general.dart +++ b/ui/lib/settings/general.dart @@ -47,7 +47,7 @@ class _GeneralState extends ConsumerState { FormBuilderTextField( name: "tmdb_api", decoration: const InputDecoration( - labelText: "TMDB Api Key", icon: Icon(Icons.key), helperText: "未防止被限流,可以提供自定义的 TMDB Api Key"), + labelText: "TMDB Api Key", icon: Icon(Icons.key), helperText: "为防止被限流,可以提供自定义的 TMDB Api Key"), // ), FormBuilderTextField(