mirror of
https://github.com/simon-ding/polaris.git
synced 2026-06-06 10:07:45 +08:00
implement download feature
This commit is contained in:
15
pkg/doc.go
Normal file
15
pkg/doc.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package pkg
|
||||
|
||||
type Torrent interface {
|
||||
Name() string
|
||||
Progress() int
|
||||
Stop() error
|
||||
Start() error
|
||||
Remove() error
|
||||
Save() string
|
||||
}
|
||||
|
||||
|
||||
type Storage interface {
|
||||
|
||||
}
|
||||
59
pkg/storage/local.go
Normal file
59
pkg/storage/local.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Storage interface {
|
||||
Move(src, dest string) error
|
||||
ReadDir(dir string) ([]FileInfo, error)
|
||||
}
|
||||
|
||||
func NewLocalStorage(dir string) *LocalStorage {
|
||||
return &LocalStorage{dir: dir}
|
||||
}
|
||||
|
||||
type LocalStorage struct {
|
||||
dir string
|
||||
}
|
||||
|
||||
func (l *LocalStorage) Move(src, dest string) error {
|
||||
targetDir := filepath.Join(l.dir, dest)
|
||||
err := filepath.Walk(src, func(path string, info fs.FileInfo, err error) error {
|
||||
destName := filepath.Join(targetDir, info.Name())
|
||||
srcName := filepath.Join(src, info.Name())
|
||||
if info.IsDir() {
|
||||
|
||||
if err := os.Mkdir(destName, 0666); err != nil {
|
||||
return errors.Wrapf(err, "mkdir %v", destName)
|
||||
}
|
||||
|
||||
} else { //is file
|
||||
if writer, err := os.Create(destName); err != nil {
|
||||
return errors.Wrapf(err, "create file %s", destName)
|
||||
} else {
|
||||
defer writer.Close()
|
||||
if f, err := os.OpenFile(srcName, os.O_RDONLY, 0666); err != nil {
|
||||
return errors.Wrapf(err, "read file %v", srcName)
|
||||
} else { //open success
|
||||
defer f.Close()
|
||||
_, err := io.Copy(writer, f)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "transmitting data error")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "move file error")
|
||||
}
|
||||
return os.RemoveAll(src)
|
||||
|
||||
}
|
||||
98
pkg/storage/webdav.go
Normal file
98
pkg/storage/webdav.go
Normal file
@@ -0,0 +1,98 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"polaris/log"
|
||||
"time"
|
||||
|
||||
"github.com/emersion/go-webdav"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
type FileInfo struct {
|
||||
Path string
|
||||
Size int64
|
||||
ModTime time.Time
|
||||
IsDir bool
|
||||
MIMEType string
|
||||
ETag string
|
||||
}
|
||||
|
||||
|
||||
type WebdavStorage struct {
|
||||
fs *webdav.Client
|
||||
}
|
||||
|
||||
func NewWebdavStorage(url, user, password string) (*WebdavStorage, error) {
|
||||
c, err := webdav.NewClient(webdav.HTTPClientWithBasicAuth(http.DefaultClient, user, password), url)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "new webdav")
|
||||
}
|
||||
fs, _ := c.ReadDir(context.TODO(), "./", false)
|
||||
for _, f := range fs {
|
||||
log.Infof("file: %v", f)
|
||||
}
|
||||
return &WebdavStorage{
|
||||
fs: c,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
func (w *WebdavStorage) Move(local, remote string) error {
|
||||
|
||||
err := filepath.Walk(local, func(path string, info fs.FileInfo, err error) error {
|
||||
name := filepath.Join(remote, info.Name())
|
||||
if info.IsDir() {
|
||||
|
||||
if err := w.fs.Mkdir(context.TODO(), name); err != nil {
|
||||
return errors.Wrapf(err, "mkdir %v", name)
|
||||
}
|
||||
|
||||
} else {//is file
|
||||
if writer, err := w.fs.Create(context.TODO(), name); err != nil {
|
||||
return errors.Wrapf(err, "create file %s", name)
|
||||
} else {
|
||||
defer writer.Close()
|
||||
if f, err := os.OpenFile(name, os.O_RDONLY, 0666); err != nil {
|
||||
return errors.Wrapf(err, "read file %v", name)
|
||||
} else { //open success
|
||||
defer f.Close()
|
||||
_, err := io.Copy(writer, f)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "transmitting data error")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "move file error")
|
||||
}
|
||||
return os.RemoveAll(local)
|
||||
}
|
||||
|
||||
func (w *WebdavStorage) ReadDir(dir string) ([]FileInfo,error) {
|
||||
fi, err := w.fs.ReadDir(context.TODO(), dir, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []FileInfo = make([]FileInfo, 0, len(fi))
|
||||
for _, f := range fi {
|
||||
res = append(res, FileInfo{
|
||||
Path: f.Path,
|
||||
Size : f.Size,
|
||||
ModTime : f.ModTime,
|
||||
IsDir : f.IsDir,
|
||||
MIMEType : f.MIMEType,
|
||||
ETag : f.ETag,
|
||||
|
||||
})
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -48,6 +48,10 @@ func (c *Client) GetSeasonDetails(id, seasonNumber int, language string) (*tmdb.
|
||||
return c.tmdbClient.GetTVSeasonDetails(id, seasonNumber, withLangOption(language))
|
||||
}
|
||||
|
||||
func (c *Client) GetTVAlternativeTitles(id int, language string) (*tmdb.TVAlternativeTitles, error) {
|
||||
return c.tmdbClient.GetTVAlternativeTitles(id, withLangOption(language))
|
||||
}
|
||||
|
||||
func wrapLanguage(lang string) string {
|
||||
if lang == "" {
|
||||
lang = "zh-CN"
|
||||
|
||||
@@ -2,6 +2,8 @@ package transmission
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hekmon/transmissionrpc"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -22,7 +24,48 @@ type Client struct {
|
||||
c *transmissionrpc.Client
|
||||
}
|
||||
|
||||
func (c *Client) Download(magnet string) (*transmissionrpc.Torrent, error) {
|
||||
t, err := c.c.TorrentAdd(&transmissionrpc.TorrentAddPayload{Filename: &magnet})
|
||||
return t, err
|
||||
func (c *Client) Download(magnet, dir string) (*Torrent, error) {
|
||||
t, err := c.c.TorrentAdd(&transmissionrpc.TorrentAddPayload{
|
||||
Filename: &magnet,
|
||||
DownloadDir: &dir,
|
||||
})
|
||||
return &Torrent{
|
||||
t: t,
|
||||
c: c.c,
|
||||
}, err
|
||||
}
|
||||
|
||||
type Torrent struct {
|
||||
t *transmissionrpc.Torrent
|
||||
c *transmissionrpc.Client
|
||||
}
|
||||
|
||||
func (t *Torrent) Name() string {
|
||||
return *t.t.Name
|
||||
}
|
||||
|
||||
func (t *Torrent) Progress() int {
|
||||
if *t.t.IsFinished {
|
||||
return 100
|
||||
}
|
||||
return int(*t.t.PercentDone*100)
|
||||
}
|
||||
|
||||
func (t *Torrent) Stop() error {
|
||||
return t.c.TorrentStopIDs([]int64{*t.t.ID})
|
||||
}
|
||||
|
||||
func (t *Torrent) Start() error {
|
||||
return t.c.TorrentStartIDs([]int64{*t.t.ID})
|
||||
}
|
||||
|
||||
func (t *Torrent) Remove() error {
|
||||
return t.c.TorrentRemove(&transmissionrpc.TorrentRemovePayload{
|
||||
IDs: []int64{*t.t.ID},
|
||||
DeleteLocalData: true,
|
||||
})
|
||||
}
|
||||
|
||||
func (t *Torrent) Save() string {
|
||||
return strconv.Itoa(int(*t.t.ID))
|
||||
}
|
||||
Reference in New Issue
Block a user