mirror of
https://github.com/simon-ding/polaris.git
synced 2026-06-09 03:27:39 +08:00
implement download feature
This commit is contained in:
@@ -3,10 +3,12 @@ package server
|
||||
import (
|
||||
"fmt"
|
||||
"polaris/db"
|
||||
"polaris/ent"
|
||||
"polaris/log"
|
||||
"polaris/pkg/torznab"
|
||||
"polaris/pkg/transmission"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pkg/errors"
|
||||
@@ -88,6 +90,15 @@ func (s *Server) SearchAndDownload(c *gin.Context) (interface{}, error) {
|
||||
if series == nil {
|
||||
return nil, fmt.Errorf("no tv series of id %v", in.ID)
|
||||
}
|
||||
var ep *ent.Episode
|
||||
for _, e := range series.Episodes {
|
||||
if e.SeasonNumber == in.Season && e.EpisodeNumber == in.Episode {
|
||||
ep = e
|
||||
}
|
||||
}
|
||||
if ep == nil {
|
||||
return nil, errors.Errorf("no episode of season %d episode %d", in.Season, in.Episode)
|
||||
}
|
||||
|
||||
res := s.searchTvWithTorznab(series.OriginalName, in.Season, in.Episode)
|
||||
if len(res) == 0 {
|
||||
@@ -95,11 +106,33 @@ func (s *Server) SearchAndDownload(c *gin.Context) (interface{}, error) {
|
||||
}
|
||||
r1 := res[0]
|
||||
log.Infof("found resource to download: %v", r1)
|
||||
torrent, err := trc.Download(r1.Magnet)
|
||||
torrent, err := trc.Download(r1.Magnet, s.db.GetDownloadDir())
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "downloading")
|
||||
}
|
||||
s.tasks[r1.Name] = torrent
|
||||
torrent.Start()
|
||||
|
||||
var name = series.NameEn
|
||||
if name == "" {
|
||||
name = series.OriginalName
|
||||
}
|
||||
var year = strings.Split(series.AirDate, "-")[0]
|
||||
|
||||
dir := fmt.Sprintf("%s (%s)/Season %02d", name, year, ep.SeasonNumber)
|
||||
|
||||
history, err :=s.db.SaveHistoryRecord(ent.History{
|
||||
SeriesID: ep.SeriesID,
|
||||
EpisodeID: ep.ID,
|
||||
SourceTitle: r1.Name,
|
||||
TargetDir: dir,
|
||||
Completed: false,
|
||||
Saved: torrent.Save(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "save record")
|
||||
}
|
||||
s.tasks[history.ID] = torrent
|
||||
|
||||
// t, err := downloader.DownloadByMagnet(r1.Magnet, "~")
|
||||
// if err != nil {
|
||||
// return nil, errors.Wrap(err, "download torrent")
|
||||
|
||||
49
server/scheduler.go
Normal file
49
server/scheduler.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"polaris/db"
|
||||
"polaris/log"
|
||||
"polaris/pkg/storage"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (s *Server) scheduler() {
|
||||
s.cron.AddFunc("@every 1m", s.checkTasks)
|
||||
}
|
||||
|
||||
func (s *Server) checkTasks() {
|
||||
for id, t := range s.tasks {
|
||||
log.Infof("task %s percentage done: %d%%", t.Name(), t.Progress())
|
||||
if t.Progress() == 100 {
|
||||
log.Infof("task is done: %v", t.Name())
|
||||
s.moveCompletedTask(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) moveCompletedTask(id int) error {
|
||||
torrent := s.tasks[id]
|
||||
r := s.db.GetHistory(id)
|
||||
series := s.db.GetSeriesDetails(r.SeriesID)
|
||||
st := s.db.GetStorage(series.StorageID)
|
||||
if st.Implementation == db.ImplWebdav {
|
||||
storageImpl, err := storage.NewWebdavStorage(st.Path, st.User, st.Password)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "new webdav")
|
||||
}
|
||||
if err := storageImpl.Move(filepath.Join(s.db.GetDownloadDir(), torrent.Name()), r.TargetDir); err != nil {
|
||||
return errors.Wrap(err, "move webdav")
|
||||
}
|
||||
} else if st.Implementation == db.ImplLocal {
|
||||
storageImpl := storage.NewLocalStorage(st.Path)
|
||||
|
||||
if err := storageImpl.Move(filepath.Join(s.db.GetDownloadDir(), torrent.Name()), r.TargetDir); err != nil {
|
||||
return errors.Wrap(err, "move webdav")
|
||||
}
|
||||
|
||||
}
|
||||
log.Infof("move downloaded files to target dir success, file: %v, target dir: %v", torrent.Name(), r.TargetDir)
|
||||
return nil
|
||||
}
|
||||
@@ -3,11 +3,11 @@ package server
|
||||
import (
|
||||
"polaris/db"
|
||||
"polaris/log"
|
||||
"polaris/pkg"
|
||||
"polaris/pkg/tmdb"
|
||||
"polaris/ui"
|
||||
|
||||
"github.com/gin-contrib/static"
|
||||
"github.com/hekmon/transmissionrpc"
|
||||
"github.com/robfig/cron"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -20,7 +20,7 @@ func NewServer(db *db.Client) *Server {
|
||||
r: r,
|
||||
db: db,
|
||||
cron: cron.New(),
|
||||
tasks: make(map[string]*transmissionrpc.Torrent),
|
||||
tasks: make(map[int]pkg.Torrent),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,18 +29,9 @@ type Server struct {
|
||||
db *db.Client
|
||||
cron *cron.Cron
|
||||
language string
|
||||
tasks map[string]*transmissionrpc.Torrent
|
||||
tasks map[int]pkg.Torrent
|
||||
}
|
||||
|
||||
func (s *Server) scheduler() {
|
||||
s.cron.AddFunc("@every 1m", s.checkTasks)
|
||||
}
|
||||
|
||||
func (s *Server) checkTasks() {
|
||||
for name, t := range s.tasks {
|
||||
log.Infof("task %s percentage done: %f", name, *t.PercentDone)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) Serve() error {
|
||||
s.scheduler()
|
||||
@@ -76,6 +67,12 @@ func (s *Server) Serve() error {
|
||||
downloader.POST("/add", HttpHandler(s.AddDownloadClient))
|
||||
downloader.DELETE("/del/:id", HttpHandler(s.DeleteDownloadCLient))
|
||||
}
|
||||
storage := api.Group("/storage")
|
||||
{
|
||||
storage.GET("/", HttpHandler(s.GetAllStorage))
|
||||
storage.POST("/", HttpHandler(s.AddStorage))
|
||||
storage.DELETE("/:id", HttpHandler(s.DeleteStorage))
|
||||
}
|
||||
|
||||
s.language = s.db.GetLanguage()
|
||||
return s.r.Run(":8080")
|
||||
|
||||
37
server/storage.go
Normal file
37
server/storage.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"polaris/db"
|
||||
"polaris/log"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func (s *Server) GetAllStorage(c *gin.Context) (interface{}, error) {
|
||||
data := s.db.GetAllStorage()
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddStorage(c *gin.Context) (interface{}, error) {
|
||||
var in db.StorageInfo
|
||||
if err := c.ShouldBindJSON(&in); err != nil {
|
||||
return nil, errors.Wrap(err, "bind json")
|
||||
}
|
||||
|
||||
log.Infof("received add storage input: %v", in)
|
||||
err := s.db.AddStorage(in)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (s *Server) DeleteStorage(c *gin.Context) (interface{}, error) {
|
||||
ids := c.Param("id")
|
||||
id, err := strconv.Atoi(ids)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("id is not int: %v", ids)
|
||||
}
|
||||
err = s.db.DeleteStorage(id)
|
||||
return nil, err
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"polaris/db"
|
||||
"polaris/ent"
|
||||
"polaris/log"
|
||||
"strconv"
|
||||
@@ -27,8 +28,8 @@ func (s *Server) SearchTvSeries(c *gin.Context) (interface{}, error) {
|
||||
}
|
||||
|
||||
type addWatchlistIn struct {
|
||||
ID int `json:"id" binding:"required"`
|
||||
RootFolder string `json:"folder" binding:"required"`
|
||||
TmdbID int `json:"id" binding:"required"`
|
||||
StorageID int `json:"folder"`
|
||||
}
|
||||
|
||||
func (s *Server) AddWatchlist(c *gin.Context) (interface{}, error) {
|
||||
@@ -36,11 +37,22 @@ func (s *Server) AddWatchlist(c *gin.Context) (interface{}, error) {
|
||||
if err := c.ShouldBindJSON(&in); err != nil {
|
||||
return nil, errors.Wrap(err, "bind query")
|
||||
}
|
||||
detail, err := s.MustTMDB().GetTvDetails(in.ID, s.language)
|
||||
detail, err := s.MustTMDB().GetTvDetails(in.TmdbID, s.language)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get tv detail")
|
||||
}
|
||||
log.Infof("find detail for tv id %d: %v", in.ID, detail)
|
||||
log.Infof("find detail for tv id %d: %v", in.TmdbID, detail)
|
||||
var nameEn = detail.OriginalName
|
||||
alterTitles, err := s.MustTMDB().GetTVAlternativeTitles(in.TmdbID, s.language)
|
||||
if err == nil {
|
||||
for _, r := range alterTitles.Results {
|
||||
if r.Iso3166_1 == "US" {
|
||||
log.Infof("found en name: %s", r.Title)
|
||||
nameEn = r.Title
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
var epIds []int
|
||||
@@ -66,7 +78,7 @@ func (s *Server) AddWatchlist(c *gin.Context) (interface{}, error) {
|
||||
epIds = append(epIds, epid)
|
||||
}
|
||||
}
|
||||
_, err = s.db.AddWatchlist(in.RootFolder, detail, epIds)
|
||||
_, err = s.db.AddWatchlist(in.StorageID, nameEn, detail, epIds, db.R1080p)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "add to list")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user