Files
TorrServerJellyfin/server/cmd/main.go
2023-11-14 11:41:02 +03:00

196 lines
5.0 KiB
Go

package main
import (
"context"
"fmt"
"net"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/metainfo"
"github.com/alexflint/go-arg"
"github.com/pkg/browser"
"server"
"server/docs"
"server/log"
"server/settings"
"server/torr"
"server/version"
)
type args struct {
Port string `arg:"-p" help:"web server port, default 8090"`
Ssl bool `help:"enables https"`
SslPort string `help:"web server ssl port, If not set, will be set to default 8091 or taken from db(if stored previously). Accepted if --ssl enabled."`
SslCert string `help:"path to ssl cert file. If not set, will be taken from db(if stored previously) or default self-signed certificate/key will be generated. Accepted if --ssl enabled."`
SslKey string `help:"path to ssl key file. If not set, will be taken from db(if stored previously) or default self-signed certificate/key will be generated. Accepted if --ssl enabled."`
Path string `arg:"-d" help:"database dir path"`
LogPath string `arg:"-l" help:"server log file path"`
WebLogPath string `arg:"-w" help:"web access log file path"`
RDB bool `arg:"-r" help:"start in read-only DB mode"`
HttpAuth bool `arg:"-a" help:"enable http auth on all requests"`
DontKill bool `arg:"-k" help:"don't kill server on signal"`
UI bool `arg:"-u" help:"open torrserver page in browser"`
TorrentsDir string `arg:"-t" help:"autoload torrents from dir"`
TorrentAddr string `help:"Torrent client address, default :32000"`
PubIPv4 string `arg:"-4" help:"set public IPv4 addr"`
PubIPv6 string `arg:"-6" help:"set public IPv6 addr"`
SearchWA bool `arg:"-s" help:"search without auth"`
}
func (args) Version() string {
return "TorrServer " + version.Version
}
var params args
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
arg.MustParse(&params)
if params.Path == "" {
params.Path, _ = os.Getwd()
}
if params.Port == "" {
params.Port = "8090"
}
settings.Path = params.Path
settings.HttpAuth = params.HttpAuth
log.Init(params.LogPath, params.WebLogPath)
fmt.Println("=========== START ===========")
fmt.Println("TorrServer", version.Version+",", runtime.Version()+",", "CPU Num:", runtime.NumCPU())
if params.HttpAuth {
log.TLogln("Use HTTP Auth file", settings.Path+"/accs.db")
}
docs.SwaggerInfo.Version = version.Version
dnsResolve()
Preconfig(params.DontKill)
if params.UI {
go func() {
time.Sleep(time.Second)
if params.Ssl {
browser.OpenURL("https://127.0.0.1:" + params.SslPort)
} else {
browser.OpenURL("http://127.0.0.1:" + params.Port)
}
}()
}
if params.TorrentAddr != "" {
settings.TorAddr = params.TorrentAddr
}
if params.PubIPv4 != "" {
settings.PubIPv4 = params.PubIPv4
}
if params.PubIPv6 != "" {
settings.PubIPv6 = params.PubIPv6
}
if params.TorrentsDir != "" {
go watchTDir(params.TorrentsDir)
}
server.Start(params.Port, params.SslPort, params.SslCert, params.SslKey, params.Ssl, params.RDB, params.SearchWA)
log.TLogln(server.WaitServer())
log.Close()
time.Sleep(time.Second * 3)
os.Exit(0)
}
func dnsResolve() {
addrs, err := net.LookupHost("www.google.com")
if len(addrs) == 0 {
log.TLogln("Check dns failed", addrs, err)
fn := func(ctx context.Context, network, address string) (net.Conn, error) {
d := net.Dialer{}
return d.DialContext(ctx, "udp", "1.1.1.1:53")
}
net.DefaultResolver = &net.Resolver{
Dial: fn,
}
addrs, err = net.LookupHost("www.google.com")
log.TLogln("Check cloudflare dns", addrs, err)
} else {
log.TLogln("Check dns OK", addrs, err)
}
}
func watchTDir(dir string) {
time.Sleep(5 * time.Second)
path, err := filepath.Abs(dir)
if err != nil {
path = dir
}
for {
files, err := os.ReadDir(path)
if err == nil {
for _, file := range files {
filename := filepath.Join(path, file.Name())
if strings.ToLower(filepath.Ext(file.Name())) == ".torrent" {
sp, err := openFile(filename)
if err == nil {
tor, err := torr.AddTorrent(sp, "", "", "")
if err == nil {
if tor.GotInfo() {
if tor.Title == "" {
tor.Title = tor.Name()
}
torr.SaveTorrentToDB(tor)
tor.Drop()
os.Remove(filename)
time.Sleep(time.Second)
} else {
log.TLogln("Error get info from torrent")
}
} else {
log.TLogln("Error parse torrent file:", err)
}
} else {
log.TLogln("Error parse file name:", err)
}
}
}
} else {
log.TLogln("Error read dir:", err)
}
time.Sleep(time.Second * 5)
}
}
func openFile(path string) (*torrent.TorrentSpec, error) {
minfo, err := metainfo.LoadFromFile(path)
if err != nil {
return nil, err
}
info, err := minfo.UnmarshalInfo()
if err != nil {
return nil, err
}
// mag := minfo.Magnet(info.Name, minfo.HashInfoBytes())
mag := minfo.Magnet(nil, &info)
return &torrent.TorrentSpec{
InfoBytes: minfo.InfoBytes,
Trackers: [][]string{mag.Trackers},
DisplayName: info.Name,
InfoHash: minfo.HashInfoBytes(),
}, nil
}