Merge branch 'master' into new-torrent

This commit is contained in:
nikk gitanes
2021-09-07 23:32:35 +03:00
6 changed files with 98 additions and 23 deletions

View File

@@ -1,7 +1,29 @@
//go:build windows
// +build windows // +build windows
package main package main
func Preconfig(kill bool) { import (
"syscall"
"time"
)
const (
EsSystemRequired = 0x00000001
EsContinuous = 0x80000000
)
var pulseTime = 1 * time.Minute
func Preconfig(kill bool) {
// don't sleep/hibernate windows
kernel32 := syscall.NewLazyDLL("kernel32.dll")
setThreadExecStateProc := kernel32.NewProc("SetThreadExecutionState")
pulse := time.NewTicker(pulseTime)
for {
select {
case <-pulse.C:
setThreadExecStateProc.Call(uintptr(EsSystemRequired))
}
}
} }

View File

@@ -90,12 +90,15 @@ func Stop() {
func onBrowse(path, rootObjectPath, host, userAgent string) (ret []interface{}, err error) { func onBrowse(path, rootObjectPath, host, userAgent string) (ret []interface{}, err error) {
if path == "/" { if path == "/" {
ret = getRoot()
return
} else if path == "/TR" {
ret = getTorrents() ret = getTorrents()
return return
} else if isHashPath(path) { } else if isHashPath(path) {
ret = getTorrent(path, host) ret = getTorrent(path, host)
return return
} else if filepath.Base(path) == "Load Torrent" { } else if filepath.Base(path) == "LD" {
ret = loadTorrent(path, host) ret = loadTorrent(path, host)
} }
return return

View File

@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"net/url" "net/url"
"path/filepath" "path/filepath"
"sort"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@@ -17,14 +18,41 @@ import (
"server/torr/state" "server/torr/state"
) )
func getRoot() (ret []interface{}) {
// Root Object
rootObj := upnpav.Object{
ID: "%2FTR",
ParentID: "0",
Title: "Torrents",
Class: "object.container.storageFolder",
Restricted: 1,
Date: upnpav.Timestamp{Time: time.Now()},
}
// add Root Object
len := len(torr.ListTorrent())
cnt := upnpav.Container{Object: rootObj, ChildCount: len}
ret = append(ret, cnt)
return
}
func getTorrents() (ret []interface{}) { func getTorrents() (ret []interface{}) {
torrs := torr.ListTorrent() torrs := torr.ListTorrent()
// sort by title as in cds SortCaps
sort.Slice(torrs, func(i, j int) bool {
return torrs[i].Title < torrs[j].Title
})
var vol = 0 var vol = 0
for _, t := range torrs { for _, t := range torrs {
vol++ vol++
obj := upnpav.Object{ obj := upnpav.Object{
ID: "%2F" + t.TorrentSpec.InfoHash.HexString(), ID: "%2F" + t.TorrentSpec.InfoHash.HexString(),
ParentID: "0", ParentID: "%2FTR",
Title: t.Title, Title: t.Title,
Class: "object.container.storageFolder", Class: "object.container.storageFolder",
Restricted: 1, Restricted: 1,
@@ -37,8 +65,8 @@ func getTorrents() (ret []interface{}) {
} }
if vol == 0 { if vol == 0 {
obj := upnpav.Object{ obj := upnpav.Object{
ID: "%2FNo Torrents", ID: "%2FNT",
ParentID: "0", ParentID: "%2FTR",
Title: "No Torrents", Title: "No Torrents",
Class: "object.container.storageFolder", Class: "object.container.storageFolder",
Restricted: 1, Restricted: 1,
@@ -46,6 +74,7 @@ func getTorrents() (ret []interface{}) {
} }
cnt := upnpav.Container{Object: obj, ChildCount: 1} cnt := upnpav.Container{Object: obj, ChildCount: 1}
ret = append(ret, cnt) ret = append(ret, cnt)
vol = 1
} }
return return
} }
@@ -69,7 +98,7 @@ func getTorrent(path, host string) (ret []interface{}) {
// if torrent not loaded, get button for load // if torrent not loaded, get button for load
if torr.Files() == nil { if torr.Files() == nil {
obj := upnpav.Object{ obj := upnpav.Object{
ID: parent + "%2FLoad Torrent", ID: parent + "%2FLD",
ParentID: parent, ParentID: parent,
Title: "Load Torrent", Title: "Load Torrent",
Class: "object.container.storageFolder", Class: "object.container.storageFolder",
@@ -139,15 +168,21 @@ func getObjFromTorrent(path, parent, host string, torr *torr.Torrent, file *stat
mime, err := MimeTypeByPath(file.Path) mime, err := MimeTypeByPath(file.Path)
if err != nil { if err != nil {
log.TLogln("Can't detect mime type", err) if settings.BTsets.EnableDebug {
log.TLogln("Can't detect mime type", err)
}
return return
} }
// TODO: handle subtitles for media
if !mime.IsMedia() { if !mime.IsMedia() {
return return
} }
if settings.BTsets.EnableDebug {
log.TLogln("mime type", mime.String(), file.Path)
}
obj := upnpav.Object{ obj := upnpav.Object{
ID: parent + "%2F" + file.Path, ID: parent + "%2F" + url.PathEscape(file.Path),
ParentID: parent, ParentID: parent,
Title: file.Path, Title: file.Path,
Class: "object.item." + mime.Type() + "Item", Class: "object.item." + mime.Type() + "Item",
@@ -163,6 +198,7 @@ func getObjFromTorrent(path, parent, host string, torr *torr.Torrent, file *stat
item.Res = append(item.Res, upnpav.Resource{ item.Res = append(item.Res, upnpav.Resource{
URL: getLink(host, pathPlay), URL: getLink(host, pathPlay),
ProtocolInfo: fmt.Sprintf("http-get:*:%s:%s", mime, dlna.ContentFeatures{ ProtocolInfo: fmt.Sprintf("http-get:*:%s:%s", mime, dlna.ContentFeatures{
SupportTimeSeek: true,
SupportRange: true, SupportRange: true,
}.String()), }.String()),
Size: uint64(file.Length), Size: uint64(file.Length),

View File

@@ -19,29 +19,31 @@ func init() {
mimeType string mimeType string
extensions string extensions string
}{ }{
{"audio/aac", ".aac"}, {"image/bmp", ".bmp"},
{"image/gif", ".gif"},
{"image/jpeg", ".jpg,.jpeg"},
{"image/png", ".png"},
{"image/tiff", ".tiff,.tif"},
{"audio/x-aac", ".aac"},
{"audio/flac", ".flac"}, {"audio/flac", ".flac"},
{"audio/mpeg", ".mpga,.mpega,.mp2,.mp3,.m4a"}, {"audio/mpeg", ".mpga,.mpega,.mp2,.mp3,.m4a"},
{"audio/ogg", ".oga,.ogg,.opus,.spx"}, {"audio/ogg", ".oga,.ogg,.opus,.spx"},
{"audio/opus", ".opus"}, {"audio/opus", ".opus"},
{"audio/weba", ".weba"}, {"audio/weba", ".weba"},
{"audio/x-wav", ".wav"}, {"audio/x-wav", ".wav"},
{"image/bmp", ".bmp"},
{"image/gif", ".gif"},
{"image/jpeg", ".jpg,.jpeg"},
{"image/png", ".png"},
{"image/tiff", ".tiff,.tif"},
{"video/dv", ".dif,.dv"}, {"video/dv", ".dif,.dv"},
{"video/fli", ".fli"}, {"video/fli", ".fli"},
{"video/mpeg", ".mpeg,.mpg,.mpe"},
{"video/mp2t", ".ts,.m2ts,.mts"},
{"video/mp4", ".mp4"}, {"video/mp4", ".mp4"},
{"video/quicktime", ".qt,.mov"}, {"video/mpeg", ".mpeg,.mpg,.mpe"},
{"video/x-matroska", ".mpv,.mkv"},
{"video/mp2t", ".ts,.m2ts,.mts"},
{"video/ogg", ".ogv"}, {"video/ogg", ".ogv"},
{"video/webm", ".webm"}, {"video/webm", ".webm"},
{"video/x-msvideo", ".avi"}, {"video/x-msvideo", ".avi"},
{"video/x-matroska", ".mpv,.mkv"}, {"video/x-quicktime", ".qt,.mov"},
{"text/srt", ".srt"}, {"text/srt", ".srt"},
{"text/smi", ".smi"},
{"text/ssa", ".ssa"},
} { } {
for _, ext := range strings.Split(t.extensions, ",") { for _, ext := range strings.Split(t.extensions, ",") {
err := mime.AddExtensionType(ext, t.mimeType) err := mime.AddExtensionType(ext, t.mimeType)
@@ -78,6 +80,11 @@ func (mt mimeType) IsImage() bool {
return strings.HasPrefix(string(mt), "image/") return strings.HasPrefix(string(mt), "image/")
} }
// IsSub returns true for subtitles MIME-types
func (mt mimeType) IsSub() bool {
return strings.HasPrefix(string(mt), "text/srt") || strings.HasPrefix(string(mt), "text/smi") || strings.HasPrefix(string(mt), "text/ssa")
}
// Returns the group "type", the part before the '/'. // Returns the group "type", the part before the '/'.
func (mt mimeType) Type() string { func (mt mimeType) Type() string {
return strings.SplitN(string(mt), "/", 2)[0] return strings.SplitN(string(mt), "/", 2)[0]
@@ -94,7 +101,13 @@ func MimeTypeByPath(filePath string) (ret mimeType, err error) {
if ret == "" { if ret == "" {
ret, err = mimeTypeByContent(filePath) ret, err = mimeTypeByContent(filePath)
} }
if ret == "video/x-msvideo" { // Custom DLNA-compat mime mappings
// TODO: make this client headers / profile map
if ret == "video/mp2t" {
ret = "video/mpeg"
} else if ret == "video/x-matroska" {
ret = "video/mpeg"
} else if ret == "video/x-msvideo" {
ret = "video/avi" ret = "video/avi"
} else if ret == "" { } else if ret == "" {
ret = "application/octet-stream" ret = "application/octet-stream"

View File

@@ -2,7 +2,9 @@ module server
go 1.17 go 1.17
replace github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210902055723-0fcf49216c68 replace (
github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210906013928-2decf97d15be
)
exclude github.com/willf/bitset v1.2.0 exclude github.com/willf/bitset v1.2.0
@@ -88,7 +90,7 @@ require (
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect golang.org/x/text v0.3.6 // indirect
google.golang.org/protobuf v1.25.0 // indirect google.golang.org/protobuf v1.25.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
) )

View File

@@ -696,8 +696,6 @@ github.com/tinylib/msgp v1.1.1/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDW
github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= github.com/tinylib/msgp v1.1.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tsynik/dms v0.0.0-20210902055723-0fcf49216c68 h1:Pzqhxa0KgN6DVHCmLqzkyp9qlA6RKft9LY2Mj1+Ykgg=
github.com/tsynik/dms v0.0.0-20210902055723-0fcf49216c68/go.mod h1:1GqMUla/yTV3GFjpKMpmdntkTl6aslGK3jfIksEwIdI=
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q=
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
@@ -893,6 +891,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=