mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 13:36:09 +05:00
Merge branch 'master' into new-torrent
This commit is contained in:
14
build-all.sh
14
build-all.sh
@@ -50,7 +50,7 @@ OUTPUT="${ROOT}/dist/TorrServer"
|
|||||||
|
|
||||||
#### Build web
|
#### Build web
|
||||||
echo "Build web"
|
echo "Build web"
|
||||||
$GOBIN run gen_web.go || exit 1
|
$GOBIN run gen_web.go
|
||||||
|
|
||||||
#### Build server
|
#### Build server
|
||||||
echo "Build server"
|
echo "Build server"
|
||||||
@@ -74,9 +74,9 @@ for PLATFORM in "${PLATFORMS[@]}"; do
|
|||||||
CMD="GOOS=${GOOS} GOARCH=${GOARCH} ${GO_ARM} ${GO_MIPS} ${GOBIN} build ${BUILD_FLAGS} -o ${BIN_FILENAME} ./cmd"
|
CMD="GOOS=${GOOS} GOARCH=${GOARCH} ${GO_ARM} ${GO_MIPS} ${GOBIN} build ${BUILD_FLAGS} -o ${BIN_FILENAME} ./cmd"
|
||||||
echo "${CMD}"
|
echo "${CMD}"
|
||||||
eval "$CMD" || FAILURES="${FAILURES} ${GOOS}/${GOARCH}${GOARM}"
|
eval "$CMD" || FAILURES="${FAILURES} ${GOOS}/${GOARCH}${GOARM}"
|
||||||
CMD="../upx -q ${BIN_FILENAME}"; # upx --brute produce much smaller binaries
|
# CMD="../upx -q ${BIN_FILENAME}"; # upx --brute produce much smaller binaries
|
||||||
echo "compress with ${CMD}"
|
# echo "compress with ${CMD}"
|
||||||
eval "$CMD"
|
# eval "$CMD"
|
||||||
done
|
done
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
@@ -102,9 +102,9 @@ for GOARCH in "${!COMPILERS[@]}"; do
|
|||||||
CMD="GOOS=${GOOS} GOARCH=${GOARCH} ${GO_ARM} CGO_ENABLED=1 ${GOBIN} build ${BUILD_FLAGS} -o ${BIN_FILENAME} ./cmd"
|
CMD="GOOS=${GOOS} GOARCH=${GOARCH} ${GO_ARM} CGO_ENABLED=1 ${GOBIN} build ${BUILD_FLAGS} -o ${BIN_FILENAME} ./cmd"
|
||||||
echo "${CMD}"
|
echo "${CMD}"
|
||||||
eval "${CMD}" || FAILURES="${FAILURES} ${GOOS}/${GOARCH}${GOARM}"
|
eval "${CMD}" || FAILURES="${FAILURES} ${GOOS}/${GOARCH}${GOARM}"
|
||||||
CMD="../upx -q ${BIN_FILENAME}"; # upx --brute produce much smaller binaries
|
# CMD="../upx -q ${BIN_FILENAME}"; # upx --brute produce much smaller binaries
|
||||||
echo "compress with ${CMD}"
|
# echo "compress with ${CMD}"
|
||||||
eval "$CMD"
|
# eval "$CMD"
|
||||||
done
|
done
|
||||||
|
|
||||||
# eval errors
|
# eval errors
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ func Start() {
|
|||||||
FriendlyName: getDefaultFriendlyName(),
|
FriendlyName: getDefaultFriendlyName(),
|
||||||
NoTranscode: true,
|
NoTranscode: true,
|
||||||
NoProbe: true,
|
NoProbe: true,
|
||||||
|
StallEventSubscribe: true,
|
||||||
Icons: []dms.Icon{
|
Icons: []dms.Icon{
|
||||||
dms.Icon{
|
dms.Icon{
|
||||||
Width: 32,
|
Width: 32,
|
||||||
|
|||||||
@@ -9,29 +9,42 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/anacrolix/dms/dlna"
|
"github.com/anacrolix/dms/dlna"
|
||||||
"github.com/anacrolix/dms/dlna/dms"
|
|
||||||
"github.com/anacrolix/dms/upnpav"
|
"github.com/anacrolix/dms/upnpav"
|
||||||
|
|
||||||
"server/log"
|
"server/log"
|
||||||
"server/settings"
|
"server/settings"
|
||||||
"server/torr"
|
"server/torr"
|
||||||
"server/torr/state"
|
"server/torr/state"
|
||||||
"server/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func getTorrents() (ret []interface{}) {
|
func getTorrents() (ret []interface{}) {
|
||||||
torrs := torr.ListTorrent()
|
torrs := torr.ListTorrent()
|
||||||
|
var vol = 0
|
||||||
for _, t := range torrs {
|
for _, t := range torrs {
|
||||||
|
vol++
|
||||||
obj := upnpav.Object{
|
obj := upnpav.Object{
|
||||||
ID: "%2F" + t.TorrentSpec.InfoHash.HexString(),
|
ID: "%2F" + t.TorrentSpec.InfoHash.HexString(),
|
||||||
Restricted: 1,
|
|
||||||
ParentID: "0",
|
ParentID: "0",
|
||||||
Class: "object.container.storageFolder",
|
|
||||||
Title: t.Title,
|
Title: t.Title,
|
||||||
|
Class: "object.container.storageFolder",
|
||||||
|
Restricted: 1,
|
||||||
Icon: t.Poster,
|
Icon: t.Poster,
|
||||||
AlbumArtURI: t.Poster,
|
AlbumArtURI: t.Poster,
|
||||||
|
Date: upnpav.Timestamp{Time: time.Now()},
|
||||||
}
|
}
|
||||||
cnt := upnpav.Container{Object: obj}
|
cnt := upnpav.Container{Object: obj, ChildCount: 1}
|
||||||
|
ret = append(ret, cnt)
|
||||||
|
}
|
||||||
|
if vol == 0 {
|
||||||
|
obj := upnpav.Object{
|
||||||
|
ID: "%2FNo Torrents",
|
||||||
|
ParentID: "0",
|
||||||
|
Title: "No Torrents",
|
||||||
|
Class: "object.container.storageFolder",
|
||||||
|
Restricted: 1,
|
||||||
|
Date: upnpav.Timestamp{Time: time.Now()},
|
||||||
|
}
|
||||||
|
cnt := upnpav.Container{Object: obj, ChildCount: 1}
|
||||||
ret = append(ret, cnt)
|
ret = append(ret, cnt)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -57,12 +70,13 @@ func getTorrent(path, host string) (ret []interface{}) {
|
|||||||
if torr.Files() == nil {
|
if torr.Files() == nil {
|
||||||
obj := upnpav.Object{
|
obj := upnpav.Object{
|
||||||
ID: parent + "%2FLoad Torrent",
|
ID: parent + "%2FLoad Torrent",
|
||||||
Restricted: 1,
|
|
||||||
ParentID: parent,
|
ParentID: parent,
|
||||||
Class: "object.container.storageFolder",
|
|
||||||
Title: "Load Torrent",
|
Title: "Load Torrent",
|
||||||
|
Class: "object.container.storageFolder",
|
||||||
|
Restricted: 1,
|
||||||
|
Date: upnpav.Timestamp{Time: time.Now()},
|
||||||
}
|
}
|
||||||
cnt := upnpav.Container{Object: obj}
|
cnt := upnpav.Container{Object: obj, ChildCount: 1}
|
||||||
ret = append(ret, cnt)
|
ret = append(ret, cnt)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -122,26 +136,23 @@ func getLink(host, path string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getObjFromTorrent(path, parent, host string, torr *torr.Torrent, file *state.TorrentFileStat) (ret interface{}) {
|
func getObjFromTorrent(path, parent, host string, torr *torr.Torrent, file *state.TorrentFileStat) (ret interface{}) {
|
||||||
// only playable files
|
|
||||||
if utils.GetMimeType(file.Path) == "*/*" {
|
mime, err := MimeTypeByPath(file.Path)
|
||||||
|
if err != nil {
|
||||||
|
log.TLogln("Can't detect mime type", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mime, err := dms.MimeTypeByPath(file.Path)
|
if !mime.IsMedia() {
|
||||||
if err != nil {
|
return
|
||||||
//return // this always err
|
|
||||||
if utils.GetMimeType(file.Path) == "video/*" {
|
|
||||||
mime = "video/mpeg"
|
|
||||||
} else {
|
|
||||||
mime = "audio/mpeg"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
obj := upnpav.Object{
|
obj := upnpav.Object{
|
||||||
ID: parent + "%2F" + file.Path,
|
ID: parent + "%2F" + file.Path,
|
||||||
Restricted: 1,
|
|
||||||
ParentID: parent,
|
ParentID: parent,
|
||||||
Class: "object.item." + mime.Type() + "Item",
|
|
||||||
Title: file.Path,
|
Title: file.Path,
|
||||||
|
Class: "object.item." + mime.Type() + "Item",
|
||||||
|
Restricted: 1,
|
||||||
|
Date: upnpav.Timestamp{Time: time.Now()},
|
||||||
}
|
}
|
||||||
|
|
||||||
item := upnpav.Item{
|
item := upnpav.Item{
|
||||||
|
|||||||
127
server/dlna/mimetype.go
Normal file
127
server/dlna/mimetype.go
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
package dlna
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"mime"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
// Add a minimal number of mime types to augment go's built in types
|
||||||
|
// for environments which don't have access to a mime.types file (e.g.
|
||||||
|
// Termux on android)
|
||||||
|
for _, t := range []struct {
|
||||||
|
mimeType string
|
||||||
|
extensions string
|
||||||
|
}{
|
||||||
|
{"audio/aac", ".aac"},
|
||||||
|
{"audio/flac", ".flac"},
|
||||||
|
{"audio/mpeg", ".mpga,.mpega,.mp2,.mp3,.m4a"},
|
||||||
|
{"audio/ogg", ".oga,.ogg,.opus,.spx"},
|
||||||
|
{"audio/opus", ".opus"},
|
||||||
|
{"audio/weba", ".weba"},
|
||||||
|
{"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/fli", ".fli"},
|
||||||
|
{"video/mpeg", ".mpeg,.mpg,.mpe"},
|
||||||
|
{"video/mp2t", ".ts,.m2ts,.mts"},
|
||||||
|
{"video/mp4", ".mp4"},
|
||||||
|
{"video/quicktime", ".qt,.mov"},
|
||||||
|
{"video/ogg", ".ogv"},
|
||||||
|
{"video/webm", ".webm"},
|
||||||
|
{"video/x-msvideo", ".avi"},
|
||||||
|
{"video/x-matroska", ".mpv,.mkv"},
|
||||||
|
{"text/srt", ".srt"},
|
||||||
|
} {
|
||||||
|
for _, ext := range strings.Split(t.extensions, ",") {
|
||||||
|
err := mime.AddExtensionType(ext, t.mimeType)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err := mime.AddExtensionType(".rmvb", "application/vnd.rn-realmedia-vbr"); err != nil {
|
||||||
|
log.Printf("Could not register application/vnd.rn-realmedia-vbr MIME type: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example: "video/mpeg"
|
||||||
|
type mimeType string
|
||||||
|
|
||||||
|
// IsMedia returns true for media MIME-types
|
||||||
|
func (mt mimeType) IsMedia() bool {
|
||||||
|
return mt.IsVideo() || mt.IsAudio() || mt.IsImage()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsVideo returns true for video MIME-types
|
||||||
|
func (mt mimeType) IsVideo() bool {
|
||||||
|
return strings.HasPrefix(string(mt), "video/") || mt == "application/vnd.rn-realmedia-vbr"
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAudio returns true for audio MIME-types
|
||||||
|
func (mt mimeType) IsAudio() bool {
|
||||||
|
return strings.HasPrefix(string(mt), "audio/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsImage returns true for image MIME-types
|
||||||
|
func (mt mimeType) IsImage() bool {
|
||||||
|
return strings.HasPrefix(string(mt), "image/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the group "type", the part before the '/'.
|
||||||
|
func (mt mimeType) Type() string {
|
||||||
|
return strings.SplitN(string(mt), "/", 2)[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the string representation of this MIME-type
|
||||||
|
func (mt mimeType) String() string {
|
||||||
|
return string(mt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MimeTypeByPath determines the MIME-type of file at the given path
|
||||||
|
func MimeTypeByPath(filePath string) (ret mimeType, err error) {
|
||||||
|
ret = mimeTypeByBaseName(path.Base(filePath))
|
||||||
|
if ret == "" {
|
||||||
|
ret, err = mimeTypeByContent(filePath)
|
||||||
|
}
|
||||||
|
if ret == "video/x-msvideo" {
|
||||||
|
ret = "video/avi"
|
||||||
|
} else if ret == "" {
|
||||||
|
ret = "application/octet-stream"
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guess MIME-type from the extension, ignoring ".part".
|
||||||
|
func mimeTypeByBaseName(name string) mimeType {
|
||||||
|
name = strings.TrimSuffix(name, ".part")
|
||||||
|
ext := path.Ext(name)
|
||||||
|
if ext != "" {
|
||||||
|
return mimeType(mime.TypeByExtension(ext))
|
||||||
|
}
|
||||||
|
return mimeType("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guess the MIME-type by analysing the first 512 bytes of the file.
|
||||||
|
func mimeTypeByContent(path string) (ret mimeType, err error) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
var data [512]byte
|
||||||
|
if n, err := file.Read(data[:]); err == nil {
|
||||||
|
ret = mimeType(http.DetectContentType(data[:n]))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -2,7 +2,9 @@ module server
|
|||||||
|
|
||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
replace github.com/anacrolix/dms v1.2.2 => github.com/yourok/dms v0.0.0-20210826085116-42eca44e0aef
|
replace (
|
||||||
|
github.com/anacrolix/dms v1.2.2 => github.com/tsynik/dms v0.0.0-20210902055723-0fcf49216c68
|
||||||
|
)
|
||||||
|
|
||||||
exclude github.com/willf/bitset v1.2.0
|
exclude github.com/willf/bitset v1.2.0
|
||||||
|
|
||||||
|
|||||||
@@ -715,8 +715,6 @@ github.com/willf/bloom v0.0.0-20170505221640-54e3b963ee16/go.mod h1:MmAltL9pDMNT
|
|||||||
github.com/willf/bloom v2.0.3+incompatible h1:QDacWdqcAUI1MPOwIQZRy9kOR7yxfyEmxX8Wdm2/JPA=
|
github.com/willf/bloom v2.0.3+incompatible h1:QDacWdqcAUI1MPOwIQZRy9kOR7yxfyEmxX8Wdm2/JPA=
|
||||||
github.com/willf/bloom v2.0.3+incompatible/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8=
|
github.com/willf/bloom v2.0.3+incompatible/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8=
|
||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/yourok/dms v0.0.0-20210826085116-42eca44e0aef h1:8W9j6a/BpZjss9p6GkD5xvmLtONhWkkWT3XoRPtje0g=
|
|
||||||
github.com/yourok/dms v0.0.0-20210826085116-42eca44e0aef/go.mod h1:1GqMUla/yTV3GFjpKMpmdntkTl6aslGK3jfIksEwIdI=
|
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
||||||
|
|||||||
41498
web/package-lock.json
generated
Normal file
41498
web/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user