From 0fb9c747989657b27df2f0a835aa1919ca96ac42 Mon Sep 17 00:00:00 2001 From: nikk gitanes Date: Sat, 11 Sep 2021 20:29:07 +0300 Subject: [PATCH 1/8] update meta for samsung tvs --- server/dlna/dlna.go | 21 +++++++++++++++++++-- server/dlna/list.go | 29 +++++++++++++++++++++++++++++ server/go.mod | 2 +- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/server/dlna/dlna.go b/server/dlna/dlna.go index b9c0bca..ed4315a 100644 --- a/server/dlna/dlna.go +++ b/server/dlna/dlna.go @@ -13,6 +13,7 @@ import ( "github.com/anacrolix/dms/upnpav" "server/log" + "server/torr" "server/web/pages/template" ) @@ -121,7 +122,6 @@ func onBrowse(path, rootObjectPath, host, userAgent string) (ret []interface{}, func onBrowseMeta(path string, rootObjectPath string, host, userAgent string) (ret interface{}, err error) { if path == "/" { - // Root Object Meta rootObj := upnpav.Object{ ID: "0", ParentID: "-1", @@ -134,8 +134,25 @@ func onBrowseMeta(path string, rootObjectPath string, host, userAgent string) (r // add Root Object ret = upnpav.Container{Object: rootObj, ChildCount: 1} return + } else if path == "/TR" { + // Torrents Object Meta + trObj := upnpav.Object{ + ID: "%2FR", + ParentID: "0", + Restricted: 1, + Searchable: 1, + Title: "Torrents", + Date: upnpav.Timestamp{Time: time.Now()}, + Class: "object.container.storageFolder", + } + vol := len(torr.ListTorrent()) + ret = upnpav.Container{Object: trObj, ChildCount: vol} + return + } else if isHashPath(path) { + ret = getTorrentMeta(path, host) + return } - err = fmt.Errorf("not implemented") + // err = fmt.Errorf("not implemented") return } diff --git a/server/dlna/list.go b/server/dlna/list.go index d87c388..1040ec0 100644 --- a/server/dlna/list.go +++ b/server/dlna/list.go @@ -113,6 +113,35 @@ func getTorrent(path, host string) (ret []interface{}) { return } +func getTorrentMeta(path, host string) (ret interface{}) { + // find torrent without load + torrs := torr.ListTorrent() + var torr *torr.Torrent + for _, t := range torrs { + if strings.Contains(path, t.TorrentSpec.InfoHash.HexString()) { + torr = t + break + } + } + if torr == nil { + return nil + } + + // Meta object + obj := upnpav.Object{ + ID: "%2F" + torr.TorrentSpec.InfoHash.HexString(), + ParentID: "%2FTR", + Restricted: 1, + Title: torr.Title, + Class: "object.container.storageFolder", + Date: upnpav.Timestamp{Time: time.Now()}, + } + + meta := upnpav.Container{Object: obj, ChildCount: 1} + + return meta +} + func loadTorrent(path, host string) (ret []interface{}) { hash := filepath.Base(filepath.Dir(path)) if hash == "/" { diff --git a/server/go.mod b/server/go.mod index 48db26c..df8352d 100644 --- a/server/go.mod +++ b/server/go.mod @@ -3,7 +3,7 @@ module server go 1.17 replace ( - github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210909053938-38af4173d4ac + github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163 github.com/anacrolix/torrent v1.31.0 => github.com/tsynik/torrent v1.2.7-0.20210907192509-2141ede9aa09 ) From b596f412d66f826b8b90ce6ae6d88a99a8813d75 Mon Sep 17 00:00:00 2001 From: nikk gitanes Date: Sat, 11 Sep 2021 20:31:44 +0300 Subject: [PATCH 2/8] fix build --- build-my.sh | 118 ++++++++++++++++++++++++++++++++++++++++++++ server/dlna/dlna.go | 1 - server/go.sum | 4 +- 3 files changed, 120 insertions(+), 3 deletions(-) create mode 100755 build-my.sh diff --git a/build-my.sh b/build-my.sh new file mode 100755 index 0000000..6b9bfee --- /dev/null +++ b/build-my.sh @@ -0,0 +1,118 @@ +#!/usr/local/bin/bash + +PLATFORMS=( +# 'linux/arm64' +# 'linux/arm7' +# 'linux/amd64' + 'linux/arm5' +# 'linux/386' +# 'windows/amd64' +# 'windows/386' +# 'darwin/amd64' +# 'darwin/arm64' +# 'freebsd/amd64' +# 'linux/mips' +# 'linux/mipsle' +# 'linux/mips64' +# 'linux/mips64le' +) + +type setopt >/dev/null 2>&1 + +set_goarm() { + if [[ "$1" =~ arm([5,7]) ]]; then + GOARCH="arm" + GOARM="${BASH_REMATCH[1]}" + GO_ARM="GOARM=${GOARM}" + else + GOARM="" + GO_ARM="" + fi +} +# use softfloat for mips builds +set_gomips() { + if [[ "$1" =~ mips ]]; then + if [[ "$1" =~ mips(64) ]]; then MIPS64="${BASH_REMATCH[1]}"; fi + GO_MIPS="GOMIPS${MIPS64}=softfloat" + else + GO_MIPS="" + fi +} + +GOBIN="go" + +$GOBIN version + +LDFLAGS="'-s -w'" +FAILURES="" +ROOT=${PWD} +OUTPUT="${ROOT}/dist/TorrServer" + +#### Build web +echo "Build web" +#$GOBIN run gen_web.go || exit 1 + +#### Build server +echo "Build server" +cd "${ROOT}/server" || exit 1 +$GOBIN clean -i -r -cache #--modcache +$GOBIN mod tidy + +BUILD_FLAGS="-ldflags=${LDFLAGS}" + +##################################### +### X86 build section +##### + +for PLATFORM in "${PLATFORMS[@]}"; do + GOOS=${PLATFORM%/*} + GOARCH=${PLATFORM#*/} + set_goarm "$GOARCH" + set_gomips "$GOARCH" + BIN_FILENAME="${OUTPUT}-${GOOS}-${GOARCH}${GOARM}" + if [[ "${GOOS}" == "windows" ]]; then BIN_FILENAME="${BIN_FILENAME}.exe"; fi + CMD="GOOS=${GOOS} GOARCH=${GOARCH} ${GO_ARM} ${GO_MIPS} ${GOBIN} build ${BUILD_FLAGS} -o ${BIN_FILENAME} ./cmd" + echo "${CMD}" + eval "$CMD" || FAILURES="${FAILURES} ${GOOS}/${GOARCH}${GOARM}" + CMD="upx -q ${BIN_FILENAME}"; # upx --brute produce much smaller binaries + echo "compress with ${CMD}" +# eval "$CMD" +done + +##################################### +### Android build section +##### + +declare -A COMPILERS=( + ["arm7"]="armv7a-linux-androideabi21-clang" +# ["arm64"]="aarch64-linux-android21-clang" +# ["386"]="i686-linux-android21-clang" +# ["amd64"]="x86_64-linux-android21-clang" +) + +#export NDK_TOOLCHAIN=$ROOT/toolchain +export NDK_VER="21.3.6528147" +#export NDK_VER="23.0.7599858" +export NDK_TOOLCHAIN="${ANDROID_HOME}/ndk/${NDK_VER}/toolchains/llvm/prebuilt/darwin-x86_64" + +GOOS=android + +for GOARCH in "${!COMPILERS[@]}"; do + export CC="$NDK_TOOLCHAIN/bin/${COMPILERS[$GOARCH]}" + export CXX="$NDK_TOOLCHAIN/bin/${COMPILERS[$GOARCH]}++" + set_goarm "$GOARCH" + BIN_FILENAME="${OUTPUT}-${GOOS}-${GOARCH}${GOARM}" + CMD="GOOS=${GOOS} GOARCH=${GOARCH} ${GO_ARM} CGO_ENABLED=1 ${GOBIN} build ${BUILD_FLAGS} -o ${BIN_FILENAME} ./cmd" + echo "${CMD}" + eval "${CMD}" || FAILURES="${FAILURES} ${GOOS}/${GOARCH}${GOARM}" + CMD="upx -q ${BIN_FILENAME}"; # upx --brute produce much smaller binaries + echo "compress with ${CMD}" +# eval "$CMD" +done + +# eval errors +if [[ "${FAILURES}" != "" ]]; then + echo "" + echo "failed on: ${FAILURES}" + exit 1 +fi diff --git a/server/dlna/dlna.go b/server/dlna/dlna.go index ed4315a..a479d75 100644 --- a/server/dlna/dlna.go +++ b/server/dlna/dlna.go @@ -2,7 +2,6 @@ package dlna import ( "bytes" - "fmt" "net" "os" "os/user" diff --git a/server/go.sum b/server/go.sum index 777fe18..78338e8 100644 --- a/server/go.sum +++ b/server/go.sum @@ -678,8 +678,8 @@ 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.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tsynik/dms v0.0.0-20210909053938-38af4173d4ac h1:1JLBJz2aGJhQ6ZR+zJWl68/0DLJkr+E3E74HEzOFOjw= -github.com/tsynik/dms v0.0.0-20210909053938-38af4173d4ac/go.mod h1:oWW4QbQ9YGl+FJ1X8xcrUYVObfA/KdipoeBuTC4ltG8= +github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163 h1:qBZPOad8wOmvFe6rIx1d0U7VpymFalvbM5kjHeEx8Gs= +github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163/go.mod h1:oWW4QbQ9YGl+FJ1X8xcrUYVObfA/KdipoeBuTC4ltG8= github.com/tsynik/torrent v1.2.7-0.20210907192509-2141ede9aa09 h1:GHhNKxddZiYrWeiXqMQiPKcSIXKF+o/w1wrqHOgOFrk= github.com/tsynik/torrent v1.2.7-0.20210907192509-2141ede9aa09/go.mod h1:E9gvoHzc58EtTudJbzZ2Ho7SKDCYk84734hB9ztBJS4= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= From 44ec8ac13c902d72113ffa802b88e3c5b4aa99f8 Mon Sep 17 00:00:00 2001 From: nikk gitanes Date: Sat, 11 Sep 2021 20:32:29 +0300 Subject: [PATCH 3/8] remove local build --- build-my.sh | 118 ---------------------------------------------------- 1 file changed, 118 deletions(-) delete mode 100755 build-my.sh diff --git a/build-my.sh b/build-my.sh deleted file mode 100755 index 6b9bfee..0000000 --- a/build-my.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/local/bin/bash - -PLATFORMS=( -# 'linux/arm64' -# 'linux/arm7' -# 'linux/amd64' - 'linux/arm5' -# 'linux/386' -# 'windows/amd64' -# 'windows/386' -# 'darwin/amd64' -# 'darwin/arm64' -# 'freebsd/amd64' -# 'linux/mips' -# 'linux/mipsle' -# 'linux/mips64' -# 'linux/mips64le' -) - -type setopt >/dev/null 2>&1 - -set_goarm() { - if [[ "$1" =~ arm([5,7]) ]]; then - GOARCH="arm" - GOARM="${BASH_REMATCH[1]}" - GO_ARM="GOARM=${GOARM}" - else - GOARM="" - GO_ARM="" - fi -} -# use softfloat for mips builds -set_gomips() { - if [[ "$1" =~ mips ]]; then - if [[ "$1" =~ mips(64) ]]; then MIPS64="${BASH_REMATCH[1]}"; fi - GO_MIPS="GOMIPS${MIPS64}=softfloat" - else - GO_MIPS="" - fi -} - -GOBIN="go" - -$GOBIN version - -LDFLAGS="'-s -w'" -FAILURES="" -ROOT=${PWD} -OUTPUT="${ROOT}/dist/TorrServer" - -#### Build web -echo "Build web" -#$GOBIN run gen_web.go || exit 1 - -#### Build server -echo "Build server" -cd "${ROOT}/server" || exit 1 -$GOBIN clean -i -r -cache #--modcache -$GOBIN mod tidy - -BUILD_FLAGS="-ldflags=${LDFLAGS}" - -##################################### -### X86 build section -##### - -for PLATFORM in "${PLATFORMS[@]}"; do - GOOS=${PLATFORM%/*} - GOARCH=${PLATFORM#*/} - set_goarm "$GOARCH" - set_gomips "$GOARCH" - BIN_FILENAME="${OUTPUT}-${GOOS}-${GOARCH}${GOARM}" - if [[ "${GOOS}" == "windows" ]]; then BIN_FILENAME="${BIN_FILENAME}.exe"; fi - CMD="GOOS=${GOOS} GOARCH=${GOARCH} ${GO_ARM} ${GO_MIPS} ${GOBIN} build ${BUILD_FLAGS} -o ${BIN_FILENAME} ./cmd" - echo "${CMD}" - eval "$CMD" || FAILURES="${FAILURES} ${GOOS}/${GOARCH}${GOARM}" - CMD="upx -q ${BIN_FILENAME}"; # upx --brute produce much smaller binaries - echo "compress with ${CMD}" -# eval "$CMD" -done - -##################################### -### Android build section -##### - -declare -A COMPILERS=( - ["arm7"]="armv7a-linux-androideabi21-clang" -# ["arm64"]="aarch64-linux-android21-clang" -# ["386"]="i686-linux-android21-clang" -# ["amd64"]="x86_64-linux-android21-clang" -) - -#export NDK_TOOLCHAIN=$ROOT/toolchain -export NDK_VER="21.3.6528147" -#export NDK_VER="23.0.7599858" -export NDK_TOOLCHAIN="${ANDROID_HOME}/ndk/${NDK_VER}/toolchains/llvm/prebuilt/darwin-x86_64" - -GOOS=android - -for GOARCH in "${!COMPILERS[@]}"; do - export CC="$NDK_TOOLCHAIN/bin/${COMPILERS[$GOARCH]}" - export CXX="$NDK_TOOLCHAIN/bin/${COMPILERS[$GOARCH]}++" - set_goarm "$GOARCH" - BIN_FILENAME="${OUTPUT}-${GOOS}-${GOARCH}${GOARM}" - CMD="GOOS=${GOOS} GOARCH=${GOARCH} ${GO_ARM} CGO_ENABLED=1 ${GOBIN} build ${BUILD_FLAGS} -o ${BIN_FILENAME} ./cmd" - echo "${CMD}" - eval "${CMD}" || FAILURES="${FAILURES} ${GOOS}/${GOARCH}${GOARM}" - CMD="upx -q ${BIN_FILENAME}"; # upx --brute produce much smaller binaries - echo "compress with ${CMD}" -# eval "$CMD" -done - -# eval errors -if [[ "${FAILURES}" != "" ]]; then - echo "" - echo "failed on: ${FAILURES}" - exit 1 -fi From 97361015dc0f7a407d5d800d544fe7c8f2062ba9 Mon Sep 17 00:00:00 2001 From: nikk gitanes Date: Sat, 11 Sep 2021 22:48:07 +0300 Subject: [PATCH 4/8] rework torrents meta response --- server/dlna/dlna.go | 13 ++++++------ server/dlna/list.go | 52 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/server/dlna/dlna.go b/server/dlna/dlna.go index a479d75..6e43f45 100644 --- a/server/dlna/dlna.go +++ b/server/dlna/dlna.go @@ -2,6 +2,7 @@ package dlna import ( "bytes" + "fmt" "net" "os" "os/user" @@ -134,9 +135,9 @@ func onBrowseMeta(path string, rootObjectPath string, host, userAgent string) (r ret = upnpav.Container{Object: rootObj, ChildCount: 1} return } else if path == "/TR" { - // Torrents Object Meta + // TR Object Meta trObj := upnpav.Object{ - ID: "%2FR", + ID: "%2FTR", ParentID: "0", Restricted: 1, Searchable: 1, @@ -147,11 +148,11 @@ func onBrowseMeta(path string, rootObjectPath string, host, userAgent string) (r vol := len(torr.ListTorrent()) ret = upnpav.Container{Object: trObj, ChildCount: vol} return - } else if isHashPath(path) { - ret = getTorrentMeta(path, host) - return } - // err = fmt.Errorf("not implemented") + ret = getTorrentMeta(path, host) + if ret == nil { + err = fmt.Errorf("meta not found") + } return } diff --git a/server/dlna/list.go b/server/dlna/list.go index 1040ec0..962cf6b 100644 --- a/server/dlna/list.go +++ b/server/dlna/list.go @@ -128,18 +128,48 @@ func getTorrentMeta(path, host string) (ret interface{}) { } // Meta object - obj := upnpav.Object{ - ID: "%2F" + torr.TorrentSpec.InfoHash.HexString(), - ParentID: "%2FTR", - Restricted: 1, - Title: torr.Title, - Class: "object.container.storageFolder", - Date: upnpav.Timestamp{Time: time.Now()}, + if isHashPath(path) { + // hash object meta + obj := upnpav.Object{ + ID: "%2F" + torr.TorrentSpec.InfoHash.HexString(), + ParentID: "%2FTR", + Restricted: 1, + Title: torr.Title, + Date: upnpav.Timestamp{Time: time.Now()}, + } + meta := upnpav.Container{Object: obj, ChildCount: 1} + return meta + } else if filepath.Base(path) == "LD" { + parent := url.PathEscape(filepath.Dir(path)) + // LD object meta + obj := upnpav.Object{ + ID: parent + "%2FLD", + ParentID: parent, + Restricted: 1, + Searchable: 1, + Title: "Load Torrents", + Date: upnpav.Timestamp{Time: time.Now()}, + } + meta := upnpav.Container{Object: obj, ChildCount: 1} + return meta + } else { + file := filepath.Base(path) + id := url.PathEscape(path) + parent := url.PathEscape(filepath.Dir(path)) + // file object meta + obj := upnpav.Object{ + ID: id, + ParentID: parent, + Restricted: 1, + Searchable: 1, + Title: file, + Date: upnpav.Timestamp{Time: time.Now()}, + } + meta := upnpav.Container{Object: obj, ChildCount: 1} + return meta } - - meta := upnpav.Container{Object: obj, ChildCount: 1} - - return meta + + return nil } func loadTorrent(path, host string) (ret []interface{}) { From ef964829e612fc38bf2954b9e78001fe088d49f8 Mon Sep 17 00:00:00 2001 From: nikk gitanes Date: Sat, 11 Sep 2021 22:50:56 +0300 Subject: [PATCH 5/8] gofmt -l -w . --- gen_web.go | 12 ++++++------ server/web/pages/template/route.go | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gen_web.go b/gen_web.go index e98f0cd..76dc4f1 100644 --- a/gen_web.go +++ b/gen_web.go @@ -90,11 +90,11 @@ func RouteWebPages(route *gin.RouterGroup) { mime.AddExtensionType(".map", "application/json") mime.AddExtensionType(".webmanifest", "application/manifest+json") // sort fmap - keys := make([]string, 0, len(fmap)) - for key := range fmap { - keys = append(keys, key) - } - sort.Strings(keys) + keys := make([]string, 0, len(fmap)) + for key := range fmap { + keys = append(keys, key) + } + sort.Strings(keys) for _, link := range keys { fmime := mime.TypeByExtension(filepath.Ext(link)) embedStr += ` @@ -103,7 +103,7 @@ func RouteWebPages(route *gin.RouterGroup) { }) ` } - embedStr += "}" + embedStr += "}\n" ff.WriteString(embedStr) } diff --git a/server/web/pages/template/route.go b/server/web/pages/template/route.go index 2cf3da7..91f06f4 100644 --- a/server/web/pages/template/route.go +++ b/server/web/pages/template/route.go @@ -96,4 +96,4 @@ func RouteWebPages(route *gin.RouterGroup) { route.GET("/static/js/runtime-main.33603a80.js.map", func(c *gin.Context) { c.Data(200, "application/json", Staticjsruntimemain33603a80jsmap) }) -} \ No newline at end of file +} From 1353f274a0c03cad8be316a5f75bf441756f7b85 Mon Sep 17 00:00:00 2001 From: nikk gitanes Date: Sat, 11 Sep 2021 23:08:51 +0300 Subject: [PATCH 6/8] return NoSuchObject in case no meta --- server/go.mod | 2 +- server/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/server/go.mod b/server/go.mod index df8352d..32b8da0 100644 --- a/server/go.mod +++ b/server/go.mod @@ -3,7 +3,7 @@ module server go 1.17 replace ( - github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163 + github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210911200354-fd999256e04d github.com/anacrolix/torrent v1.31.0 => github.com/tsynik/torrent v1.2.7-0.20210907192509-2141ede9aa09 ) diff --git a/server/go.sum b/server/go.sum index 78338e8..414dc69 100644 --- a/server/go.sum +++ b/server/go.sum @@ -678,8 +678,8 @@ 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.5/go.mod h1:eQsjooMTnV42mHu917E26IogZ2930nFyBQdofk10Udg= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163 h1:qBZPOad8wOmvFe6rIx1d0U7VpymFalvbM5kjHeEx8Gs= -github.com/tsynik/dms v0.0.0-20210911171915-d3d89ee99163/go.mod h1:oWW4QbQ9YGl+FJ1X8xcrUYVObfA/KdipoeBuTC4ltG8= +github.com/tsynik/dms v0.0.0-20210911200354-fd999256e04d h1:YFNG0P4SKHxOvHM3Ae+FI1/kRnhi/qyvblHOKzDgRPE= +github.com/tsynik/dms v0.0.0-20210911200354-fd999256e04d/go.mod h1:oWW4QbQ9YGl+FJ1X8xcrUYVObfA/KdipoeBuTC4ltG8= github.com/tsynik/torrent v1.2.7-0.20210907192509-2141ede9aa09 h1:GHhNKxddZiYrWeiXqMQiPKcSIXKF+o/w1wrqHOgOFrk= github.com/tsynik/torrent v1.2.7-0.20210907192509-2141ede9aa09/go.mod h1:E9gvoHzc58EtTudJbzZ2Ho7SKDCYk84734hB9ztBJS4= github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31/go.mod h1:onvgF043R+lC5RZ8IT9rBXDaEDnpnw/Cl+HFiw+v/7Q= From 44f1cfbd9df3d2725128bbedd47f0d9364b73bc4 Mon Sep 17 00:00:00 2001 From: nikk gitanes Date: Mon, 13 Sep 2021 00:37:56 +0300 Subject: [PATCH 7/8] change meta response --- server/dlna/dlna.go | 30 ----------------------------- server/dlna/list.go | 47 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/server/dlna/dlna.go b/server/dlna/dlna.go index 6e43f45..a8763f8 100644 --- a/server/dlna/dlna.go +++ b/server/dlna/dlna.go @@ -10,10 +10,8 @@ import ( "time" "github.com/anacrolix/dms/dlna/dms" - "github.com/anacrolix/dms/upnpav" "server/log" - "server/torr" "server/web/pages/template" ) @@ -121,34 +119,6 @@ func onBrowse(path, rootObjectPath, host, userAgent string) (ret []interface{}, } func onBrowseMeta(path string, rootObjectPath string, host, userAgent string) (ret interface{}, err error) { - if path == "/" { - rootObj := upnpav.Object{ - ID: "0", - ParentID: "-1", - Restricted: 1, - Searchable: 1, - Title: "TorrServer", - Date: upnpav.Timestamp{Time: time.Now()}, - Class: "object.container.storageFolder", - } - // add Root Object - ret = upnpav.Container{Object: rootObj, ChildCount: 1} - return - } else if path == "/TR" { - // TR Object Meta - trObj := upnpav.Object{ - ID: "%2FTR", - ParentID: "0", - Restricted: 1, - Searchable: 1, - Title: "Torrents", - Date: upnpav.Timestamp{Time: time.Now()}, - Class: "object.container.storageFolder", - } - vol := len(torr.ListTorrent()) - ret = upnpav.Container{Object: trObj, ChildCount: vol} - return - } ret = getTorrentMeta(path, host) if ret == nil { err = fmt.Errorf("meta not found") diff --git a/server/dlna/list.go b/server/dlna/list.go index 962cf6b..4e1922f 100644 --- a/server/dlna/list.go +++ b/server/dlna/list.go @@ -114,6 +114,36 @@ func getTorrent(path, host string) (ret []interface{}) { } func getTorrentMeta(path, host string) (ret interface{}) { + + if path=="/" { + rootObj := upnpav.Object{ + ID: "0", + ParentID: "-1", + Restricted: 1, + Searchable: 1, + Title: "TorrServer", + Date: upnpav.Timestamp{Time: time.Now()}, + Class: "object.container", + } + // add Root Object + meta := upnpav.Container{Object: rootObj} + return meta + } else if path == "/TR" { + // TR Object Meta + trObj := upnpav.Object{ + ID: "%2FTR", + ParentID: "0", + Restricted: 1, + Searchable: 1, + Title: "Torrents", + Date: upnpav.Timestamp{Time: time.Now()}, + Class: "object.container", + } + //vol := len(torr.ListTorrent()) + meta := upnpav.Container{Object: trObj} + return meta + } + // find torrent without load torrs := torr.ListTorrent() var torr *torr.Torrent @@ -136,11 +166,15 @@ func getTorrentMeta(path, host string) (ret interface{}) { Restricted: 1, Title: torr.Title, Date: upnpav.Timestamp{Time: time.Now()}, + Class: "object.container", } - meta := upnpav.Container{Object: obj, ChildCount: 1} + meta := upnpav.Container{Object: obj} return meta } else if filepath.Base(path) == "LD" { parent := url.PathEscape(filepath.Dir(path)) + if settings.BTsets.EnableDebug { + log.TLogln("getTorrentMeta parent for LD", parent) + } // LD object meta obj := upnpav.Object{ ID: parent + "%2FLD", @@ -149,13 +183,17 @@ func getTorrentMeta(path, host string) (ret interface{}) { Searchable: 1, Title: "Load Torrents", Date: upnpav.Timestamp{Time: time.Now()}, + Class: "object.container", } - meta := upnpav.Container{Object: obj, ChildCount: 1} + meta := upnpav.Container{Object: obj} return meta } else { file := filepath.Base(path) id := url.PathEscape(path) parent := url.PathEscape(filepath.Dir(path)) + if settings.BTsets.EnableDebug { + log.TLogln("getTorrentMeta id:", id, "parent:", parent) + } // file object meta obj := upnpav.Object{ ID: id, @@ -164,11 +202,12 @@ func getTorrentMeta(path, host string) (ret interface{}) { Searchable: 1, Title: file, Date: upnpav.Timestamp{Time: time.Now()}, + Class: "object.container", } - meta := upnpav.Container{Object: obj, ChildCount: 1} + meta := upnpav.Container{Object: obj} return meta } - + // for error response return nil } From 02b749a4c419da734b4467bc1214db25b232979a Mon Sep 17 00:00:00 2001 From: nikk gitanes Date: Mon, 13 Sep 2021 02:39:45 +0300 Subject: [PATCH 8/8] add some iface fun and don't start dlna on loopback and tunnels --- server/dlna/dlna.go | 10 +- server/dlna/list.go | 4 +- server/utils/net_interface_filter.go | 38 +++++++ .../utils/net_interface_filter_nix_darwin.go | 29 +++++ server/utils/net_interface_filter_win.go | 105 ++++++++++++++++++ 5 files changed, 182 insertions(+), 4 deletions(-) create mode 100644 server/utils/net_interface_filter.go create mode 100644 server/utils/net_interface_filter_nix_darwin.go create mode 100644 server/utils/net_interface_filter_win.go diff --git a/server/dlna/dlna.go b/server/dlna/dlna.go index a8763f8..dfef97c 100644 --- a/server/dlna/dlna.go +++ b/server/dlna/dlna.go @@ -12,6 +12,7 @@ import ( "github.com/anacrolix/dms/dlna/dms" "server/log" + "server/utils" "server/web/pages/template" ) @@ -21,11 +22,16 @@ func Start() { dmsServer = &dms.Server{ Interfaces: func() (ifs []net.Interface) { var err error - ifs, err = net.Interfaces() + ifaces, err := net.Interfaces() if err != nil { log.TLogln(err) os.Exit(1) } + for _, element := range ifaces { + if element.Flags&net.FlagLoopback == 0 && element.Flags&net.FlagUp == net.FlagUp && element.Flags&net.FlagMulticast == net.FlagMulticast && utils.IsPhysicalInterface(element.HardwareAddr.String()) { + ifs = append(ifs, element) + } + } return }(), HTTPConn: func() net.Listener { @@ -159,7 +165,7 @@ func getDefaultFriendlyName() string { var list []string for _, i := range ifaces { addrs, _ := i.Addrs() - if i.Flags&net.FlagUp == net.FlagUp { + if i.Flags&net.FlagLoopback == 0 && i.Flags&net.FlagUp == net.FlagUp && i.Flags&net.FlagMulticast == net.FlagMulticast && utils.IsPhysicalInterface(i.HardwareAddr.String()) { for _, addr := range addrs { var ip net.IP switch v := addr.(type) { diff --git a/server/dlna/list.go b/server/dlna/list.go index 4e1922f..28fc268 100644 --- a/server/dlna/list.go +++ b/server/dlna/list.go @@ -115,7 +115,7 @@ func getTorrent(path, host string) (ret []interface{}) { func getTorrentMeta(path, host string) (ret interface{}) { - if path=="/" { + if path == "/" { rootObj := upnpav.Object{ ID: "0", ParentID: "-1", @@ -143,7 +143,7 @@ func getTorrentMeta(path, host string) (ret interface{}) { meta := upnpav.Container{Object: trObj} return meta } - + // find torrent without load torrs := torr.ListTorrent() var torr *torr.Torrent diff --git a/server/utils/net_interface_filter.go b/server/utils/net_interface_filter.go new file mode 100644 index 0000000..23bdb7b --- /dev/null +++ b/server/utils/net_interface_filter.go @@ -0,0 +1,38 @@ +package utils + +import ( + "strings" +) + +type PhysicalInterface struct { + MACAddress string + Name string + FriendlyName string +} + +// Mac Address parts to look for, and identify non physical devices. There may be more, update me! +var macAddrPartsToFilter []string = []string{ + "00:03:FF", // Microsoft Hyper-V, Virtual Server, Virtual PC + "0A:00:27", // VirtualBox + "00:00:00:00:00", // Teredo Tunneling Pseudo-Interface + "00:50:56", // VMware ESX 3, Server, Workstation, Player + "00:1C:14", // VMware ESX 3, Server, Workstation, Player + "00:0C:29", // VMware ESX 3, Server, Workstation, Player + "00:05:69", // VMware ESX 3, Server, Workstation, Player + "00:1C:42", // Microsoft Hyper-V, Virtual Server, Virtual PC + "00:0F:4B", // Virtual Iron 4 + "00:16:3E", // Red Hat Xen, Oracle VM, XenSource, Novell Xen + "08:00:27", // Sun xVM VirtualBox + "7A:79", // Hamachi +} + +// Filters the possible physical interface address by comparing it to known popular VM Software adresses +// and Teredo Tunneling Pseudo-Interface. +func IsPhysicalInterface(addr string) bool { + for _, macPart := range macAddrPartsToFilter { + if strings.HasPrefix(strings.ToLower(addr), strings.ToLower(macPart)) { + return false + } + } + return true +} diff --git a/server/utils/net_interface_filter_nix_darwin.go b/server/utils/net_interface_filter_nix_darwin.go new file mode 100644 index 0000000..5777510 --- /dev/null +++ b/server/utils/net_interface_filter_nix_darwin.go @@ -0,0 +1,29 @@ +//go:build linux || darwin +// +build linux darwin + +package utils + +import ( + "fmt" + "net" +) + +// Gets all physical interfaces based on filter results, ignoring all VM, Loopback and Tunnel interfaces. +func GetAllPhysicalInterfaces() []PhysicalInterface { + ifaces, err := net.Interfaces() + + if err != nil { + fmt.Println(err) + return nil + } + + var outInterfaces []PhysicalInterface + + for _, element := range ifaces { + if element.Flags&net.FlagLoopback == 0 && element.Flags&net.FlagUp == 1 && isPhysicalInterface(element.HardwareAddr.String()) { + outInterfaces = append(outInterfaces, PhysicalInterface{MACAddress: element.HardwareAddr.String(), Name: element.Name, FriendlyName: element.Name}) + } + } + + return outInterfaces +} diff --git a/server/utils/net_interface_filter_win.go b/server/utils/net_interface_filter_win.go new file mode 100644 index 0000000..0620d59 --- /dev/null +++ b/server/utils/net_interface_filter_win.go @@ -0,0 +1,105 @@ +//go:build windows +// +build windows + +package utils + +import ( + "os" + "syscall" + "unicode/utf16" + "unsafe" + + "golang.org/x/sys/windows" +) + +const ( + IfOperStatusUp = 1 + IF_TYPE_SOFTWARE_LOOPBACK = 24 + IF_TYPE_TUNNEL = 131 +) + +const hexDigit = "0123456789abcdef" + +func adapterAddresses() ([]*windows.IpAdapterAddresses, error) { + var b []byte + l := uint32(15000) // recommended initial size + for { + b = make([]byte, l) + err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, windows.GAA_FLAG_INCLUDE_PREFIX, 0, (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])), &l) + if err == nil { + if l == 0 { + return nil, nil + } + break + } + if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW { + return nil, os.NewSyscallError("getadaptersaddresses", err) + } + if l <= uint32(len(b)) { + return nil, os.NewSyscallError("getadaptersaddresses", err) + } + } + var aas []*windows.IpAdapterAddresses + for aa := (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])); aa != nil; aa = aa.Next { + aas = append(aas, aa) + } + return aas, nil +} + +func bytePtrToString(p *uint8) string { + a := (*[10000]uint8)(unsafe.Pointer(p)) + i := 0 + for a[i] != 0 { + i++ + } + return string(a[:i]) +} + +func physicalAddrToString(physAddr [8]byte) string { + if len(physAddr) == 0 { + return "" + } + buf := make([]byte, 0, len(physAddr)*3-1) + for i, b := range physAddr { + if i > 0 { + buf = append(buf, ':') + } + buf = append(buf, hexDigit[b>>4]) + buf = append(buf, hexDigit[b&0xF]) + } + return string(buf) +} + +func cStringToString(cs *uint16) (s string) { + if cs != nil { + us := make([]uint16, 0, 256) + for p := uintptr(unsafe.Pointer(cs)); ; p += 2 { + u := *(*uint16)(unsafe.Pointer(p)) + if u == 0 { + return string(utf16.Decode(us)) + } + us = append(us, u) + } + } + return "" +} + +// Gets all physical interfaces based on filter results, ignoring all VM, Loopback and Tunnel interfaces. +func GetAllPhysicalInterfaces() []PhysicalInterface { + aa, _ := adapterAddresses() + + var outInterfaces []PhysicalInterface + + for _, pa := range aa { + mac := physicalAddrToString(pa.PhysicalAddress) + name := "\\Device\\NPF_" + bytePtrToString(pa.AdapterName) + + if pa.IfType != uint32(IF_TYPE_SOFTWARE_LOOPBACK) && pa.IfType != uint32(IF_TYPE_TUNNEL) && + pa.OperStatus == uint32(IfOperStatusUp) && IsPhysicalInterface(mac) { + + outInterfaces = append(outInterfaces, PhysicalInterface{MACAddress: mac, Name: name, FriendlyName: cStringToString(pa.FriendlyName)}) + } + } + + return outInterfaces +}