diff --git a/server/web/msx/msx.go b/server/web/msx/msx.go index 0dfdab8..42c98d1 100644 --- a/server/web/msx/msx.go +++ b/server/web/msx/msx.go @@ -1,262 +1,44 @@ package msx import ( - "fmt" - "net/url" - "path/filepath" - "strings" - - sets "server/settings" - "server/torr" - "server/torr/state" - "server/utils" + _ "embed" + "server/version" "github.com/gin-gonic/gin" ) -type msxMenu struct { - Logo string `json:"logo,omitempty"` - Reuse bool `json:"reuse"` - Cache bool `json:"cache"` - Restore bool `json:"restore"` - Reference string `json:"reference,omitempty"` - Menu []msxMenuItem `json:"menu"` +var ( + //go:embed assets/tvx.js.gz + tvx []byte + //go:embed assets/tizen.html.gz + tzn []byte + //go:embed assets/torrents.min.html.gz + trn []byte + //go:embed assets/html5x.html.gz + h5x []byte + //go:embed assets/russian.json.gz + rus []byte +) + +func ass(b []byte, t string) func(*gin.Context) { + return func(c *gin.Context) { + c.Header("Content-Encoding", "gzip") + c.Data(200, t+"; charset=UTF-8", b) + } } -type msxMenuItem struct { - Icon string `json:"icon,omitempty"` - Label string `json:"label,omitempty"` - Data msxData `json:"data,omitempty"` -} - -type msxTemplate struct { - Type string `json:"type,omitempty"` - Layout string `json:"layout,omitempty"` - Color string `json:"color,omitempty"` - Icon string `json:"icon,omitempty"` - IconSize string `json:"iconSize,omitempty"` - BadgeColor string `json:"badgeColor,omitempty"` - TagColor string `json:"tagColor,omitempty"` - Properties gin.H `json:"properties,omitempty"` -} - -type msxData struct { - Type string `json:"type,omitempty"` - Headline string `json:"headline,omitempty"` - Action string `json:"action,omitempty"` - Template msxTemplate `json:"template,omitempty"` - Items []msxItem `json:"items,omitempty"` - Pages []msxPage `json:"pages,omitempty"` -} - -type msxItem struct { - Title string `json:"title,omitempty"` - Label string `json:"label,omitempty"` - PlayerLabel string `json:"playerLabel,omitempty"` - Action string `json:"action,omitempty"` - Image string `json:"image,omitempty"` - Icon string `json:"icon,omitempty"` - Badge string `json:"badge,omitempty"` - Tag string `json:"tag,omitempty"` - Data gin.H `json:"data,omitempty"` -} - -type msxPage struct { - Items []gin.H `json:"items,omitempty"` -} - -const ICON_OPTIONS = "tune" - -func msxStart(c *gin.Context) { - c.JSON(200, gin.H{ - "name": "TorrServer", - "version": version.Version, - "parameter": "menu:{PREFIX}{SERVER}/msx/torrents", +func SetupRoute(r *gin.RouterGroup) { + r.GET("/msx/start.json", func(c *gin.Context) { + c.JSON(200, gin.H{ + "name": "TorrServer", + "version": "0.0.1", + "parameter": "content:request:interaction:init@{PREFIX}{SERVER}/msx/torrents", + }) }) -} - -// /msx/torrents -func msxTorrents(c *gin.Context) { - torrs := torr.ListTorrent() - - host := utils.GetScheme(c) + "://" + c.Request.Host - logo := host + "/apple-touch-icon.png" - list := make([]msxItem, len(torrs)) - - for i, tor := range torrs { - item := msxItem{ - Title: tor.Title, - Image: tor.Poster, - Action: "content:" + host + "/msx/playlist/" + url.PathEscape(tor.Title) + - "?hash=" + tor.TorrentSpec.InfoHash.HexString() + "&platform={PLATFORM}", - } - list[i] = item - } - - c.JSON(200, msxMenu{ - Logo: logo, - Cache: false, - Reuse: false, - Restore: false, - Reference: host + "/msx/torrents", - Menu: []msxMenuItem{ - // Main page - { - Icon: "list", - Label: "Torrents", - Data: msxData{ - Type: "pages", - Template: msxTemplate{ - Type: "separate", - Layout: "0,0,2,4", - Icon: "msx-white-soft:movie", - Color: "msx-glass", - }, - Items: list, - }, - // About - }, { - Icon: "info", - Label: "About", - Data: msxData{ - Pages: []msxPage{ - { - Items: []gin.H{ - { - "type": "default", - "headline": "TorrServer " + version.Version, - "text": "https://github.com/YouROK/TorrServer", - "image": logo, - "imageFiller": "height-left", - "imageWidth": 2, - "layout": "0,0,8,2", - "color": "msx-gray-soft", - }, - }, - }, - }, - }, - }, - }, - }) -} - -// /msx/playlist?hash=... -func msxPlaylist(c *gin.Context) { - hash, _ := c.GetQuery("hash") - if hash == "" { - c.JSON(200, msxData{ - Action: "error:Item not found", - }) - return - } - platform, _ := c.GetQuery("platform") - - tor := torr.GetTorrent(hash) - if tor == nil { - c.JSON(200, msxData{ - Action: "error:Item not found", - }) - return - } - - if tor.Stat == state.TorrentInDB { - tor = torr.LoadTorrent(tor) - if tor == nil { - c.JSON(200, msxData{ - Action: "error:Error while getting torrent info", - }) - return - } - } - - host := utils.GetScheme(c) + "://" + c.Request.Host - status := tor.Status() - viewed := sets.ListViewed(hash) - var list []msxItem - contentAction := "" - - for _, f := range status.FileStats { - mime := utils.GetMimeType(f.Path) - action := mime[0 : len(mime)-2] - - if action == "*" { - continue - } - name := filepath.Base(f.Path) - uri := host + "/stream/" + url.PathEscape(name) + "?link=" + hash + "&index=" + fmt.Sprint(f.Id) + "&play" - item := msxItem{ - Label: name, - PlayerLabel: strings.TrimSuffix(name, filepath.Ext(name)), - Action: action + ":" + uri, - } - - if platform == "android" || platform == "firetv" { - item.Action = "system:tvx:launch" - item.Data = gin.H{ - "id": hash + "-" + fmt.Sprint(f.Id), - "uri": uri, - "type": mime, - } - } else if platform == "tizen" { - contentAction = "content:request:interaction:init@" + host + "/msx/tizen.html" - } else if platform == "netcast" { - contentAction = "system:netcast:menu" - } else if platform == "ios" || platform == "mac" { - // TODO - for iOS and Mac the application must be defined in scheme but we don't know what user has installed - item.Action = "system:tvx:launch:vlc://" + uri - } else { - item.Action = "video:plugin:" + host + "/msx/html5x.html?url= " + url.QueryEscape(uri) - contentAction = "panel:request:player:options" - } - - if isViewed(viewed, f.Id) { - item.Tag = " " - } - if action == "audio" { - item.Icon = "msx-white-soft:music-note" - } - list = append(list, item) - } - - if len(list) == 0 { - c.JSON(200, msxData{ - Action: "error:No supported content found", - }) - return - } - - res := msxData{ - Headline: tor.Title, - Type: "list", - Template: msxTemplate{ - Type: "control", - Layout: "0,2,12,1", - Color: "msx-glass", - Icon: "msx-white-soft:movie", - IconSize: "medium", - BadgeColor: "msx-yellow", - TagColor: "msx-yellow", - }, - Items: list, - } - - if contentAction != "" { - res.Template.Properties = gin.H{ - "button:content:icon": ICON_OPTIONS, - "button:content:action": contentAction, - } - } - - c.JSON(200, res) -} - -func isViewed(viewed []*sets.Viewed, id int) bool { - for _, v := range viewed { - if v.FileIndex == id { - return true - } - } - return false + r.GET("/msx/russian.json", ass(rus, "application/json")) + r.GET("/msx/tvx.js", ass(tvx, "text/javascript")) + r.GET("/msx/torrents", ass(trn, "text/html")) + r.GET("/msx/tizen", ass(tzn, "text/html")) + r.GET("/msx/html5x", ass(h5x, "text/html")) }