Skip to content
This repository was archived by the owner on Feb 10, 2023. It is now read-only.

Commit 9a37f98

Browse files
add support for bundles
1 parent 20ff83c commit 9a37f98

File tree

5 files changed

+315
-239
lines changed

5 files changed

+315
-239
lines changed

internal/ui/logger.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ package ui
22

33
import (
44
"fmt"
5-
"io"
65
"log"
76

87
"github.com/SoMuchForSubtlety/f1viewer/v2/internal/util"
8+
"github.com/rivo/tview"
99
)
1010

1111
type tviewLogger struct {
12-
io.Writer
12+
*tview.TextView
1313
}
1414

1515
func (s *UIState) Logger() *tviewLogger {
@@ -21,15 +21,17 @@ func (l *tviewLogger) Errorf(format string, v ...interface{}) {
2121
}
2222

2323
func (l *tviewLogger) Error(v ...interface{}) {
24-
fmt.Fprintln(l.Writer, fmt.Sprintf("[%s::b]ERROR:[-::-]", util.ColortoHexString(activeTheme.ErrorColor)), fmt.Sprint(v...))
24+
fmt.Fprintln(l.TextView, fmt.Sprintf("[%s::b]ERROR:[-::-]", util.ColortoHexString(activeTheme.ErrorColor)), fmt.Sprint(v...))
2525
log.Println("[ERROR]", fmt.Sprint(v...))
26+
l.ScrollToEnd()
2627
}
2728

2829
func (l *tviewLogger) Infof(format string, v ...interface{}) {
2930
l.Info(fmt.Sprintf(format, v...))
3031
}
3132

3233
func (l *tviewLogger) Info(v ...interface{}) {
33-
fmt.Fprintln(l.Writer, fmt.Sprintf("[%s::b]INFO:[-::-]", util.ColortoHexString(activeTheme.InfoColor)), fmt.Sprint(v...))
34+
fmt.Fprintln(l.TextView, fmt.Sprintf("[%s::b]INFO:[-::-]", util.ColortoHexString(activeTheme.InfoColor)), fmt.Sprint(v...))
3435
log.Println("[INFO]", fmt.Sprint(v...))
36+
l.ScrollToEnd()
3537
}

internal/ui/node.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"sync"
77

88
"github.com/SoMuchForSubtlety/f1viewer/v2/internal/cmd"
9+
"github.com/SoMuchForSubtlety/f1viewer/v2/pkg/f1tv/v2"
910
"github.com/atotto/clipboard"
1011
"github.com/gdamore/tcell/v2"
1112
"github.com/rivo/tview"
@@ -150,8 +151,9 @@ func (s *UIState) getLiveNode() (bool, *tview.TreeNode, error) {
150151
}
151152
}
152153

153-
func (s *UIState) getHomepageNodes() []*tview.TreeNode {
154-
headings, err := s.v2.GetVideoContainers()
154+
func (s *UIState) getPageNodes(id f1tv.PageID) []*tview.TreeNode {
155+
s.logger.Infof("loading %d", id)
156+
headings, bundles, err := s.v2.GetPageContent(id)
155157
if err != nil {
156158
s.logger.Error(err)
157159
return nil
@@ -164,6 +166,9 @@ func (s *UIState) getHomepageNodes() []*tview.TreeNode {
164166
if title == "" {
165167
title = h.RetrieveItems.ResultObj.MeetingName
166168
}
169+
if title == "" {
170+
title = "???"
171+
}
167172
metadata := cmd.MetaData{CategoryTitle: title}
168173
headingNode := tview.NewTreeNode(title).
169174
SetColor(activeTheme.CategoryNodeColor).
@@ -175,6 +180,22 @@ func (s *UIState) getHomepageNodes() []*tview.TreeNode {
175180
}
176181
headingNodes = append(headingNodes, headingNode)
177182
}
183+
for _, b := range bundles {
184+
b := b
185+
186+
metadata := cmd.MetaData{CategoryTitle: b.Title}
187+
headingNode := tview.NewTreeNode(b.Title).
188+
SetColor(activeTheme.FolderNodeColor).
189+
SetReference(&NodeMetadata{nodeType: CategoryNode, metadata: metadata}).
190+
SetExpanded(false)
191+
192+
headingNode.SetSelectedFunc(s.withBlink(headingNode, func() {
193+
headingNode.SetSelectedFunc(nil)
194+
appendNodes(headingNode, s.getPageNodes(b.ID)...)
195+
headingNode.SetExpanded(true)
196+
}, nil))
197+
headingNodes = append(headingNodes, headingNode)
198+
}
178199

179200
return headingNodes
180201
}

internal/ui/state.go

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,39 @@ func NewUI(cfg config.Config, version string) *UIState {
111111
ui.initUI()
112112
}
113113

114-
appendNodes(root, ui.getHomepageNodes()...)
114+
homepageContent := tview.NewTreeNode("homepage").
115+
SetColor(activeTheme.CategoryNodeColor).
116+
SetReference(&NodeMetadata{nodeType: CategoryNode, metadata: cmd.MetaData{}}).
117+
SetExpanded(true)
118+
homepageContent.SetSelectedFunc(ui.withBlink(homepageContent, func() {
119+
homepageContent.SetSelectedFunc(nil)
120+
appendNodes(homepageContent, ui.getPageNodes(f1tv.PAGE_HOMEPAGE)...)
121+
}, nil))
122+
123+
appendNodes(root,
124+
ui.pageNode(f1tv.PAGE_HOMEPAGE, "Homepage"),
125+
ui.pageNode(f1tv.PAGE_SEASON_20201, "2021 Season"),
126+
ui.pageNode(f1tv.PAGE_ARCHIVE, "archive"),
127+
ui.pageNode(f1tv.PAGE_DOCUMENTARIES, "Documentaries"),
128+
ui.pageNode(f1tv.PAGE_SHOWS, "Shows"),
129+
)
130+
115131
return &ui
116132
}
117133

134+
func (ui *UIState) pageNode(id f1tv.PageID, title string) *tview.TreeNode {
135+
node := tview.NewTreeNode(title).
136+
SetColor(activeTheme.FolderNodeColor).
137+
SetReference(&NodeMetadata{nodeType: CategoryNode, metadata: cmd.MetaData{}}).
138+
SetExpanded(true)
139+
node.SetSelectedFunc(ui.withBlink(node, func() {
140+
node.SetSelectedFunc(nil)
141+
appendNodes(node, ui.getPageNodes(id)...)
142+
}, nil))
143+
144+
return node
145+
}
146+
118147
func (ui *UIState) Stop() {
119148
ui.app.Stop()
120149
}

pkg/f1tv/v2/api.go

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,14 @@ const (
3030
MOBILE_DASH StreamType = "MOBILE_DASH"
3131
TABLET_DASH StreamType = "TABLET_DASH"
3232

33-
CATEGORY_LIVE RequestCategory = 395
33+
PAGE_HOMEPAGE PageID = 395
34+
PAGE_ARCHIVE PageID = 493
35+
PAGE_SHOWS PageID = 410
36+
PAGE_DOCUMENTARIES PageID = 413
37+
PAGE_SEASON_20201 PageID = 1510
3438

35-
VIDEO ContentType = "VIDEO"
39+
VIDEO ContentType = "VIDEO"
40+
BUNDLE ContentType = "BUNDLE"
3641

3742
LIVE ContentSubType = "LIVE"
3843
REPLAY ContentSubType = "REPLAY"
@@ -44,7 +49,7 @@ type ContentSubType string
4449

4550
type StreamType string
4651

47-
type RequestCategory int
52+
type PageID int64
4853

4954
func assembleURL(urlPath string, format StreamType, args ...interface{}) (*url.URL, error) {
5055
args = append([]interface{}{format}, args...)
@@ -98,7 +103,7 @@ func (f *F1TV) Authenticate(username, password string) error {
98103
return err
99104
}
100105

101-
func (f *F1TV) GetContent(format StreamType, category RequestCategory, v interface{}) error {
106+
func (f *F1TV) GetContent(format StreamType, category PageID, v interface{}) error {
102107
reqURL, err := assembleURL(categoryPagePath, format, category)
103108
if err != nil {
104109
return err
@@ -115,28 +120,47 @@ func (f *F1TV) GetContent(format StreamType, category RequestCategory, v interfa
115120
return json.NewDecoder(resp.Body).Decode(v)
116121
}
117122

118-
func (f *F1TV) GetVideoContainers() ([]TopContainer, error) {
123+
type RemoteContent struct {
124+
ID PageID
125+
Title string
126+
}
127+
128+
func (f *F1TV) GetPageContent(id PageID) ([]TopContainer, []RemoteContent, error) {
119129
var resp APIResponse
120-
err := f.GetContent(WEB_DASH, CATEGORY_LIVE, &resp)
130+
err := f.GetContent(WEB_DASH, id, &resp)
121131
if err != nil {
122-
return nil, err
132+
return nil, nil, err
123133
}
124134

125-
var nonEmpty []TopContainer
135+
var content []TopContainer
136+
var bundles []RemoteContent
126137
for _, container := range resp.ResultObj.Containers {
127138
var videoContainers []ContentContainer
128139
for _, contentContainer := range container.RetrieveItems.ResultObj.Containers {
129140
if contentContainer.Metadata.ContentType == VIDEO {
130141
videoContainers = append(videoContainers, contentContainer)
142+
} else if contentContainer.Metadata.ContentType == BUNDLE {
143+
if contentContainer.Metadata.EmfAttributes.PageID == id {
144+
// we don't need recusion
145+
continue
146+
}
147+
title := contentContainer.Metadata.Label
148+
if title == "" {
149+
title = contentContainer.Metadata.EmfAttributes.GlobalTitle
150+
}
151+
if title == "" {
152+
title = contentContainer.Metadata.EmfAttributes.GlobalMeetingName
153+
}
154+
bundles = append(bundles, RemoteContent{ID: contentContainer.Metadata.EmfAttributes.PageID, Title: title})
131155
}
132156
}
133157
container.RetrieveItems.ResultObj.Containers = videoContainers
134158
if len(videoContainers) > 0 {
135-
nonEmpty = append(nonEmpty, container)
159+
content = append(content, container)
136160
}
137161
}
138162

139-
return nonEmpty, err
163+
return content, bundles, err
140164
}
141165

142166
func (s AdditionalStream) PrettyName() string {
@@ -153,7 +177,7 @@ func (s AdditionalStream) PrettyName() string {
153177
}
154178

155179
func (f *F1TV) GetLiveVideoContainers() ([]ContentContainer, error) {
156-
topContainers, err := f.GetVideoContainers()
180+
topContainers, _, err := f.GetPageContent(PAGE_HOMEPAGE)
157181
if err != nil {
158182
return nil, err
159183
}

0 commit comments

Comments
 (0)