mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 20:24:27 -04:00
Use cmap for infos
This commit is contained in:
parent
2afed432f7
commit
f54a876636
@ -176,19 +176,20 @@ func (h *Handler) GetInfo(c echo.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
route := GetRoute(c)
|
||||||
sha, err := src.GetHash(path)
|
sha, err := src.GetHash(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ret, err := src.GetInfo(path)
|
ret, err := src.GetInfo(path, sha, route)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Run extractors to have them in cache
|
// Run extractors to have them in cache
|
||||||
src.Extract(ret.Path, sha)
|
src.Extract(ret.Path, sha, route)
|
||||||
go h.thumbnails.ExtractThumbnail(
|
go h.thumbnails.ExtractThumbnail(
|
||||||
ret.Path,
|
ret.Path,
|
||||||
fmt.Sprintf("%s/thumbnails.png", c.Request().Header.Get("X-Route")),
|
fmt.Sprintf("%s/thumbnails.png", route),
|
||||||
)
|
)
|
||||||
return c.JSON(http.StatusOK, ret)
|
return c.JSON(http.StatusOK, ret)
|
||||||
}
|
}
|
||||||
@ -208,11 +209,12 @@ func (h *Handler) GetAttachment(c echo.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
route := GetRoute(c)
|
||||||
sha, err := src.GetHash(path)
|
sha, err := src.GetHash(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
wait, err := src.Extract(path, sha)
|
wait, err := src.Extract(path, sha, route)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -237,11 +239,12 @@ func (h *Handler) GetSubtitle(c echo.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
route := GetRoute(c)
|
||||||
sha, err := src.GetHash(path)
|
sha, err := src.GetHash(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
wait, err := src.Extract(path, sha)
|
wait, err := src.Extract(path, sha, route)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -264,7 +267,7 @@ func (h *Handler) GetThumbnails(c echo.Context) error {
|
|||||||
|
|
||||||
out, err := h.thumbnails.ExtractThumbnail(
|
out, err := h.thumbnails.ExtractThumbnail(
|
||||||
path,
|
path,
|
||||||
fmt.Sprintf("%s/thumbnails.png", c.Request().Header.Get("X-Route")),
|
fmt.Sprintf("%s/thumbnails.png", GetRoute(c)),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -287,7 +290,7 @@ func (h *Handler) GetThumbnailsVtt(c echo.Context) error {
|
|||||||
|
|
||||||
out, err := h.thumbnails.ExtractThumbnail(
|
out, err := h.thumbnails.ExtractThumbnail(
|
||||||
path,
|
path,
|
||||||
fmt.Sprintf("%s/thumbnails.png", c.Request().Header.Get("X-Route")),
|
fmt.Sprintf("%s/thumbnails.png", GetRoute(c)),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -48,6 +48,13 @@ func (m *CMap[K, V]) GetOrSet(key K, val V) (V, bool) {
|
|||||||
return m.GetOrCreate(key, func() V { return val })
|
return m.GetOrCreate(key, func() V { return val })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *CMap[K, V]) Set(key K, val V) {
|
||||||
|
m.lock.Lock()
|
||||||
|
defer m.lock.Unlock()
|
||||||
|
|
||||||
|
m.data[key] = val
|
||||||
|
}
|
||||||
|
|
||||||
func (m *CMap[K, V]) Remove(key K) {
|
func (m *CMap[K, V]) Remove(key K) {
|
||||||
m.lock.Lock()
|
m.lock.Lock()
|
||||||
defer m.lock.Unlock()
|
defer m.lock.Unlock()
|
||||||
|
@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
var extracted = NewCMap[string, <-chan struct{}]()
|
var extracted = NewCMap[string, <-chan struct{}]()
|
||||||
|
|
||||||
func Extract(path string, sha string) (<-chan struct{}, error) {
|
func Extract(path string, sha string, route string) (<-chan struct{}, error) {
|
||||||
ret := make(chan struct{})
|
ret := make(chan struct{})
|
||||||
existing, created := extracted.GetOrSet(sha, ret)
|
existing, created := extracted.GetOrSet(sha, ret)
|
||||||
if !created {
|
if !created {
|
||||||
@ -16,7 +16,7 @@ func Extract(path string, sha string) (<-chan struct{}, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
info, err := GetInfo(path)
|
info, err := GetInfo(path, sha, route)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
extracted.Remove(sha)
|
extracted.Remove(sha)
|
||||||
close(ret)
|
close(ret)
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package src
|
package src
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha1"
|
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -12,6 +10,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type MediaInfo struct {
|
type MediaInfo struct {
|
||||||
|
// closed if the mediainfo is ready for read. open otherwise
|
||||||
|
ready <-chan struct{}
|
||||||
// The sha1 of the video file.
|
// The sha1 of the video file.
|
||||||
Sha string `json:"sha"`
|
Sha string `json:"sha"`
|
||||||
/// The internal path of the video file.
|
/// The internal path of the video file.
|
||||||
@ -173,7 +173,32 @@ var SubtitleExtensions = map[string]string{
|
|||||||
"vtt": "vtt",
|
"vtt": "vtt",
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetInfo(path string) (*MediaInfo, error) {
|
var infos = NewCMap[string, *MediaInfo]()
|
||||||
|
|
||||||
|
func GetInfo(path string, sha string, route string) (*MediaInfo, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ret, _ := infos.GetOrCreate(sha, func() *MediaInfo {
|
||||||
|
readyChan := make(chan struct{})
|
||||||
|
mi := &MediaInfo{
|
||||||
|
Sha: sha,
|
||||||
|
ready: readyChan,
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
var val *MediaInfo
|
||||||
|
val, err = getInfo(path, route)
|
||||||
|
*mi = *val
|
||||||
|
mi.ready = readyChan
|
||||||
|
mi.Sha = sha
|
||||||
|
close(readyChan)
|
||||||
|
}()
|
||||||
|
return mi
|
||||||
|
})
|
||||||
|
<-ret.ready
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func getInfo(path string, route string) (*MediaInfo, error) {
|
||||||
defer printExecTime("mediainfo for %s", path)()
|
defer printExecTime("mediainfo for %s", path)()
|
||||||
|
|
||||||
mi, err := mediainfo.Open(path)
|
mi, err := mediainfo.Open(path)
|
||||||
@ -182,17 +207,6 @@ func GetInfo(path string) (*MediaInfo, error) {
|
|||||||
}
|
}
|
||||||
defer mi.Close()
|
defer mi.Close()
|
||||||
|
|
||||||
sha := mi.Parameter(mediainfo.StreamGeneral, 0, "UniqueID")
|
|
||||||
// Remove dummy values that some tools use.
|
|
||||||
if len(sha) <= 5 {
|
|
||||||
date := mi.Parameter(mediainfo.StreamGeneral, 0, "File_Modified_Date")
|
|
||||||
|
|
||||||
h := sha1.New()
|
|
||||||
h.Write([]byte(path))
|
|
||||||
h.Write([]byte(date))
|
|
||||||
sha = hex.EncodeToString(h.Sum(nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
chapters_begin := ParseUint(mi.Parameter(mediainfo.StreamMenu, 0, "Chapters_Pos_Begin"))
|
chapters_begin := ParseUint(mi.Parameter(mediainfo.StreamMenu, 0, "Chapters_Pos_Begin"))
|
||||||
chapters_end := ParseUint(mi.Parameter(mediainfo.StreamMenu, 0, "Chapters_Pos_End"))
|
chapters_end := ParseUint(mi.Parameter(mediainfo.StreamMenu, 0, "Chapters_Pos_End"))
|
||||||
|
|
||||||
@ -204,7 +218,6 @@ func GetInfo(path string) (*MediaInfo, error) {
|
|||||||
// fmt.Printf("%s", mi.Option("info_parameters", ""))
|
// fmt.Printf("%s", mi.Option("info_parameters", ""))
|
||||||
|
|
||||||
ret := MediaInfo{
|
ret := MediaInfo{
|
||||||
Sha: sha,
|
|
||||||
Path: path,
|
Path: path,
|
||||||
// Remove leading .
|
// Remove leading .
|
||||||
Extension: filepath.Ext(path)[1:],
|
Extension: filepath.Ext(path)[1:],
|
||||||
@ -248,7 +261,7 @@ func GetInfo(path string) (*MediaInfo, error) {
|
|||||||
extension := OrNull(SubtitleExtensions[format])
|
extension := OrNull(SubtitleExtensions[format])
|
||||||
var link *string
|
var link *string
|
||||||
if extension != nil {
|
if extension != nil {
|
||||||
x := fmt.Sprintf("/video/%s/subtitle/%d.%s", sha, i, *extension)
|
x := fmt.Sprintf("%s/subtitle/%d.%s", route, i, *extension)
|
||||||
link = &x
|
link = &x
|
||||||
}
|
}
|
||||||
return Subtitle{
|
return Subtitle{
|
||||||
@ -273,7 +286,7 @@ func GetInfo(path string) (*MediaInfo, error) {
|
|||||||
Fonts: Map(
|
Fonts: Map(
|
||||||
attachments,
|
attachments,
|
||||||
func(font string, _ int) string {
|
func(font string, _ int) string {
|
||||||
return fmt.Sprintf("/video/%s/attachment/%s", sha, font)
|
return fmt.Sprintf("%s/attachment/%s", route, font)
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
if len(ret.Videos) > 0 {
|
if len(ret.Videos) > 0 {
|
||||||
|
@ -23,6 +23,10 @@ func GetPath(c echo.Context) (string, error) {
|
|||||||
return key, nil
|
return key, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetRoute(c echo.Context) string {
|
||||||
|
return c.Request().Header.Get("X-Route")
|
||||||
|
}
|
||||||
|
|
||||||
func SanitizePath(path string) error {
|
func SanitizePath(path string) error {
|
||||||
if strings.Contains(path, "/") || strings.Contains(path, "..") {
|
if strings.Contains(path, "/") || strings.Contains(path, "..") {
|
||||||
return echo.NewHTTPError(http.StatusBadRequest, "Invalid parameter. Can't contains path delimiters or ..")
|
return echo.NewHTTPError(http.StatusBadRequest, "Invalid parameter. Can't contains path delimiters or ..")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user