refactor, bypass dns filtering using google dns, yts host resolution using qwant
This commit is contained in:
		@@ -1,81 +0,0 @@
 | 
			
		||||
package handler
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/anacrolix/torrent"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Engine struct {
 | 
			
		||||
	client      *torrent.Client
 | 
			
		||||
	files       map[string]*MovieTorrent
 | 
			
		||||
	storagePath string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewEngine(storagePath string) (*Engine, error) {
 | 
			
		||||
	logrus.Info("Creating Streaming engine")
 | 
			
		||||
	if storagePath == "" {
 | 
			
		||||
		storagePath = os.TempDir()
 | 
			
		||||
		logrus.Debug("Storage path undefined. Using default temp directory")
 | 
			
		||||
	}
 | 
			
		||||
	logrus.Debugf("Storage Path: %s", storagePath)
 | 
			
		||||
	conf := torrent.NewDefaultClientConfig()
 | 
			
		||||
	conf.DataDir = storagePath
 | 
			
		||||
	c, err := torrent.NewClient(conf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &Engine{c, map[string]*MovieTorrent{}, storagePath}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Engine) Close() {
 | 
			
		||||
	e.client.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Engine) Get(fileName string) (*MovieTorrent, error) {
 | 
			
		||||
	logrus.Infof("Requesting torrent: %s", fileName)
 | 
			
		||||
	if mt, ok := e.files[fileName]; ok {
 | 
			
		||||
		return mt, nil
 | 
			
		||||
	}
 | 
			
		||||
	return nil, fmt.Errorf("not found: %s", fileName)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Engine) Prepare(magnet string) error {
 | 
			
		||||
	logrus.Debugf("preparing magnet: %s", magnet)
 | 
			
		||||
	t, err := e.client.AddMagnet(magnet)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	<-t.GotInfo()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
func (e *Engine) Download(magnet string) (*MovieTorrent, error) {
 | 
			
		||||
	logrus.Debugf("downloading magnet: %s", magnet)
 | 
			
		||||
	t, err := e.client.AddMagnet(magnet)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	<-t.GotInfo()
 | 
			
		||||
	file := getLargestFile(t)
 | 
			
		||||
	file.Download()
 | 
			
		||||
	mt := newMovieTorrent(file, t)
 | 
			
		||||
	mt.engine = e
 | 
			
		||||
	e.files[mt.FileName] = mt
 | 
			
		||||
	logrus.Infof("Downloading: %s", mt.FileName)
 | 
			
		||||
	return mt, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getLargestFile(t *torrent.Torrent) *torrent.File {
 | 
			
		||||
	var target *torrent.File
 | 
			
		||||
	var maxSize int64
 | 
			
		||||
 | 
			
		||||
	for _, file := range t.Files() {
 | 
			
		||||
		if maxSize < file.Length() {
 | 
			
		||||
			maxSize = file.Length()
 | 
			
		||||
			target = file
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return target
 | 
			
		||||
}
 | 
			
		||||
@@ -2,18 +2,21 @@ package handler
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"git.adphi.net/Adphi/ytsflix/templates"
 | 
			
		||||
	"git.adphi.net/Adphi/ytsflix/ytsclient"
 | 
			
		||||
	"github.com/dustin/go-humanize"
 | 
			
		||||
	"github.com/gorilla/mux"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"gopkg.in/h2non/filetype.v1"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/dustin/go-humanize"
 | 
			
		||||
	"github.com/gorilla/mux"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"gopkg.in/h2non/filetype.v1"
 | 
			
		||||
 | 
			
		||||
	"git.adphi.net/adphi/ytsflix/engine"
 | 
			
		||||
	"git.adphi.net/adphi/ytsflix/templates"
 | 
			
		||||
	"git.adphi.net/adphi/ytsflix/ytsclient"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
@@ -21,9 +24,9 @@ var (
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Handler struct {
 | 
			
		||||
	engine      *Engine
 | 
			
		||||
	engine      *engine.Engine
 | 
			
		||||
	clients     map[string]int
 | 
			
		||||
	yts         *ytsclient.Client
 | 
			
		||||
	yts         ytsclient.Client
 | 
			
		||||
	mutex       sync.Mutex
 | 
			
		||||
	storagePath string
 | 
			
		||||
}
 | 
			
		||||
@@ -57,11 +60,11 @@ type MovieData struct {
 | 
			
		||||
func NewHandler(storagePath string) (*Handler, error) {
 | 
			
		||||
	h := Handler{storagePath: storagePath}
 | 
			
		||||
	var err error
 | 
			
		||||
	h.engine, err = NewEngine(storagePath)
 | 
			
		||||
	h.engine, err = engine.NewEngine(storagePath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	h.yts = ytsclient.NewClient("https://yts.am/api/v2")
 | 
			
		||||
	h.yts = ytsclient.NewClient()
 | 
			
		||||
	h.clients = map[string]int{}
 | 
			
		||||
	return &h, nil
 | 
			
		||||
}
 | 
			
		||||
@@ -86,7 +89,7 @@ func (h *Handler) Home(writer http.ResponseWriter, request *http.Request) {
 | 
			
		||||
				Quality: ytsclient.Quality1080p,
 | 
			
		||||
			})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				sendError(writer, err)
 | 
			
		||||
				logrus.WithField("genre", genre).Error(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			ms := map[string]Movie{}
 | 
			
		||||
@@ -233,7 +236,7 @@ func (h *Handler) Torrents(writer http.ResponseWriter, request *http.Request) {
 | 
			
		||||
 | 
			
		||||
func (h *Handler) Serve(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	vars := mux.Vars(r)
 | 
			
		||||
	var mt *MovieTorrent
 | 
			
		||||
	var mt *engine.MovieTorrent
 | 
			
		||||
	var err error
 | 
			
		||||
	movie := vars["movie"]
 | 
			
		||||
	h.mutex.Lock()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,145 +0,0 @@
 | 
			
		||||
package handler
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/anacrolix/torrent"
 | 
			
		||||
	"github.com/asticode/go-astisub"
 | 
			
		||||
	"github.com/odwrtw/yifysubs"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"gopkg.in/h2non/filetype.v1"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type MovieTorrent struct {
 | 
			
		||||
	FileName  string
 | 
			
		||||
	MIME      string
 | 
			
		||||
	Subtitles map[string]string
 | 
			
		||||
	torrent   *torrent.Torrent
 | 
			
		||||
	file      *torrent.File
 | 
			
		||||
	engine    *Engine
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newMovieTorrent(file *torrent.File, t *torrent.Torrent) *MovieTorrent {
 | 
			
		||||
	fileName := filepath.Base(file.Path())
 | 
			
		||||
	ext := strings.SplitAfter(path.Ext(fileName), ".")[1]
 | 
			
		||||
	MIME := filetype.GetType(ext).MIME.Value
 | 
			
		||||
	return &MovieTorrent{
 | 
			
		||||
		torrent:  t,
 | 
			
		||||
		file:     file,
 | 
			
		||||
		FileName: fileName,
 | 
			
		||||
		MIME:     MIME,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Progress struct {
 | 
			
		||||
	Downloaded    uint64
 | 
			
		||||
	Size          uint64
 | 
			
		||||
	DownloadSpeed uint64
 | 
			
		||||
	Percentage    int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MovieTorrent) NewReader() torrent.Reader {
 | 
			
		||||
	reader := m.file.NewReader()
 | 
			
		||||
	reader.SetReadahead(m.file.Length() / 100)
 | 
			
		||||
	reader.SetResponsive()
 | 
			
		||||
	return reader
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MovieTorrent) Progress() chan Progress {
 | 
			
		||||
	pc := make(chan Progress)
 | 
			
		||||
	var p int64 = 0
 | 
			
		||||
	size := m.torrent.Info().TotalLength()
 | 
			
		||||
	c := m.torrent.Closed()
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer close(pc)
 | 
			
		||||
		for {
 | 
			
		||||
			select {
 | 
			
		||||
			case <-c:
 | 
			
		||||
				logrus.Debugf("%s stopped", m.FileName)
 | 
			
		||||
				return
 | 
			
		||||
			default:
 | 
			
		||||
				if p >= size {
 | 
			
		||||
					logrus.Debugf("%s completed", m.FileName)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				currentProgress := m.torrent.BytesCompleted()
 | 
			
		||||
				percent := int(float64(currentProgress) / float64(size) * 100)
 | 
			
		||||
				pc <- Progress{
 | 
			
		||||
					Downloaded:    uint64(currentProgress),
 | 
			
		||||
					Size:          uint64(size),
 | 
			
		||||
					Percentage:    percent,
 | 
			
		||||
					DownloadSpeed: uint64(currentProgress - p),
 | 
			
		||||
				}
 | 
			
		||||
				p = currentProgress
 | 
			
		||||
				time.Sleep(time.Second)
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	return pc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MovieTorrent) Cancel() {
 | 
			
		||||
	logrus.Infof("Stopping torrent: %s", m.FileName)
 | 
			
		||||
	m.torrent.Drop()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MovieTorrent) DownloadSubtitles(imdbID string) error {
 | 
			
		||||
	logrus.Infof("Getting subtitles for: %s", m.FileName)
 | 
			
		||||
	//Create a client
 | 
			
		||||
	client := yifysubs.New("http://yifysubtitles.com")
 | 
			
		||||
 | 
			
		||||
	//Search subtitles
 | 
			
		||||
	subtitles, err := client.Search(imdbID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	m.Subtitles = map[string]string{}
 | 
			
		||||
	basePath := filepath.Join(m.engine.storagePath, filepath.Dir(m.file.Path()))
 | 
			
		||||
	logrus.Debugf("Subtitles base path: %s", basePath)
 | 
			
		||||
	if _, err := os.Stat(basePath); os.IsNotExist(err) {
 | 
			
		||||
		os.Mkdir(basePath, os.ModePerm)
 | 
			
		||||
	}
 | 
			
		||||
	var wg sync.WaitGroup
 | 
			
		||||
	wg.Add(len(subtitles))
 | 
			
		||||
	mx := sync.RWMutex{}
 | 
			
		||||
	for _, subtitle := range subtitles {
 | 
			
		||||
		go func(sub *yifysubs.Subtitle) {
 | 
			
		||||
			defer wg.Done()
 | 
			
		||||
			name := fmt.Sprintf("%s.vtt", sub.Lang)
 | 
			
		||||
			ref := filepath.Join(filepath.Dir(m.file.Path()), name)
 | 
			
		||||
			p := filepath.Join(basePath, name)
 | 
			
		||||
			if _, err := os.Stat(p); err == nil {
 | 
			
		||||
				mx.Lock()
 | 
			
		||||
				m.Subtitles[name] = ref
 | 
			
		||||
				mx.Unlock()
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			file, err := os.Create(p)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				logrus.Error(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			defer file.Close()
 | 
			
		||||
			defer sub.Close()
 | 
			
		||||
			s, _ := astisub.ReadFromSRT(sub)
 | 
			
		||||
 | 
			
		||||
			if err := s.WriteToWebVTT(file); err != nil {
 | 
			
		||||
				logrus.Debugf("error subtitle: %v", err)
 | 
			
		||||
				os.Remove(p)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			mx.Lock()
 | 
			
		||||
			m.Subtitles[name] = ref
 | 
			
		||||
			mx.Unlock()
 | 
			
		||||
 | 
			
		||||
		}(subtitle)
 | 
			
		||||
	}
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user