Expose session/last-used user and device IP on player rows. Filter retrieve_player_list by users, merge GET /Devices when include_offline is set, and resolve spoken names to HA media_player entities via player_links (device_id or IP). PlayNow still requires a live session.
85 lines
1.8 KiB
Go
85 lines
1.8 KiB
Go
// Package state holds the per-session mutable context shared by the MCP
|
|
// tools: the authenticated Emby client, library selection, and in-progress
|
|
// search-result chunking. It mirrors the Python lifespan context dict.
|
|
package state
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"git.i3omb.com/gronod/emby-mcp/internal/config"
|
|
"git.i3omb.com/gronod/emby-mcp/internal/emby"
|
|
)
|
|
|
|
// SearchChunk tracks an in-progress chunked search result set.
|
|
type SearchChunk struct {
|
|
SearchID string
|
|
TotalItems int
|
|
ChunkSize int
|
|
ChunkNum int // last returned chunk (1-based); 0 = none returned yet
|
|
Items []emby.MediaItem
|
|
}
|
|
|
|
// State is the shared server state. All access goes through the mutex.
|
|
type State struct {
|
|
mu sync.Mutex
|
|
|
|
Client *emby.Client
|
|
UserID string
|
|
MaxChunkSize int
|
|
PlayerUsers []string
|
|
PlayerLinks []config.PlayerLink
|
|
|
|
libraries []emby.Library
|
|
current *emby.Library
|
|
search *SearchChunk
|
|
}
|
|
|
|
func New(client *emby.Client, userID string, maxChunkSize int) *State {
|
|
return &State{Client: client, UserID: userID, MaxChunkSize: maxChunkSize}
|
|
}
|
|
|
|
// Libraries returns a copy of the cached library list.
|
|
func (s *State) Libraries() []emby.Library {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
out := make([]emby.Library, len(s.libraries))
|
|
copy(out, s.libraries)
|
|
return out
|
|
}
|
|
|
|
func (s *State) SetLibraries(libs []emby.Library) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.libraries = libs
|
|
}
|
|
|
|
func (s *State) CurrentLibrary() *emby.Library {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
return s.current
|
|
}
|
|
|
|
func (s *State) SetCurrentLibrary(l *emby.Library) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.current = l
|
|
}
|
|
|
|
func (s *State) Search() *SearchChunk {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
return s.search
|
|
}
|
|
|
|
func (s *State) SetSearch(c *SearchChunk) {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.search = c
|
|
}
|
|
|
|
func (s *State) ClearSearch() {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.search = nil
|
|
}
|