clone

a desktop tv and program guide for over-the-air broadcasts: what's on air, what your tuner gets, live tv, recordings

Show stations' logos drawn for light backgrounds

FelineStateMachine committed 2d030fb
Schedules Direct files each logo by the background it's drawn for: its
"dark" and "white" ones are white, unreadable on the guide's light logo
chips, and "light" is the colored one. The server now keeps every
variant and picks light, then gray. Stations kept before have the lineup
read again at the next start for theirs, the schedules left as they are.
commit
2d030fb47ff44863b02338be3c070a8a50642d14
parent
6260142c0b9b3bd1d7a271f726dbce6b4a86471b
author
FelineStateMachine <226808055+FelineStateMachine@users.noreply.github.com>
kind
fix risk score 1.9 of 3, Jev's estimate
4 files changed, +72 -13
Minternal/sd/client.go14++++-------
Minternal/sd/sd_test.go29+++++++++++++++++++++--
Minternal/sd/source.go4+++
Minternal/sd/state.go38++++++++++++++++++++++++++++--
M internal/sd/client.go +5 -9
M internal/sd/sd_test.go +27 -2
@@ -81,7 +81,7 @@ func (f *fakeSD) ServeHTTP(w http.ResponseWriter, r *http.Request) {
8181 },8282 "stations": []any{8383 map[string]any{"stationID": "20370", "callsign": "KWGNDT", "name": "KWGNDT (KWGN-DT)", "affiliate": "CW",84- "stationLogo": []any{map[string]any{"URL": "https://example.com/kwgn-white.png", "category": "white"}, map[string]any{"URL": "https://example.com/kwgn-dark.png", "category": "dark"}}},84+ "stationLogo": []any{map[string]any{"URL": "https://example.com/kwgn-dark.png", "category": "dark"}, map[string]any{"URL": "https://example.com/kwgn-light.png", "category": "light"}}},8585 map[string]any{"stationID": "21252", "callsign": "KCNCDT", "affiliate": "CBS"},8686 },8787 })
@@ -195,7 +195,7 @@ func TestUpdate(t *testing.T) {
195195 }196196 197197 g := s.Guide()198- if g == nil || len(g.Channels) != 2 || g.Channels[0].Number != "2.1" || g.Channels[0].CallSign != "KWGNDT" || g.Channels[0].Logo != "https://example.com/kwgn-dark.png" {198+ if g == nil || len(g.Channels) != 2 || g.Channels[0].Number != "2.1" || g.Channels[0].CallSign != "KWGNDT" || g.Channels[0].Logo != "https://example.com/kwgn-light.png" {199199 t.Fatalf("guide channels = %+v", g)200200 }201201 ps := g.Programs["20370"]
@@ -343,3 +343,28 @@ func TestRunOncePerDay(t *testing.T) {
343343 t.Fatalf("next update %s", next)344344 }345345 }346+347+// TestOldLogos: stations kept before their logos' variants were have the348+// lineup read again at the next start, without the schedules.349+func TestOldLogos(t *testing.T) {350+ s, f := newSource(t)351+ _ = s.SetAccount("viewer", "hunter2")352+ a, _ := LoadAccount(s.accountPath())353+ s.update(context.Background(), a)354+ st, _ := loadState(s.statePath())355+ for i := range st.Stations {356+ st.Stations[i].Logos, st.Stations[i].Logo = nil, "https://example.com/white.png"357+ }358+ if err := st.save(s.statePath()); err != nil {359+ t.Fatal(err)360+ }361+ again := &Source{Dir: s.Dir, ZIP: "80302", HTTP: s.HTTP, UserAgent: "airwaves/test", BaseURL: s.BaseURL}362+ if g := again.Guide(); g == nil || g.Channels[0].Logo != "https://example.com/white.png" {363+ t.Fatalf("before: %+v", g)364+ }365+ asked := len(f.asked)366+ again.update(context.Background(), a)367+ if g := again.Guide(); g.Channels[0].Logo != "https://example.com/kwgn-light.png" || len(f.asked) != asked || f.count("GET lineups/USA-OTA-80302") != 2 {368+ t.Fatalf("after: logo %q, %d schedules asked, calls %v", g.Channels[0].Logo, len(f.asked)-asked, f.calls)369+ }370+}
M internal/sd/source.go +4 -0
M internal/sd/state.go +36 -2
@@ -45,7 +45,41 @@ type station struct {
4545 CallSign string `json:"callSign"`4646 Name string `json:"name,omitempty"`4747 Affiliate string `json:"affiliate,omitempty"`48- Logo string `json:"logo,omitempty"`48+ // Logos are the station's logo by the background it's drawn for:49+ // "light" (the colored one), "gray", "dark" and "white" (white ones);50+ // Logo is the one Schedules Direct gives without saying.51+ Logos map[string]string `json:"logos,omitempty"`52+ Logo string `json:"logo,omitempty"`53+}54+55+// logo is the station's logo for the guide's light logo chips: the one56+// drawn for a light background, else gray, else any.57+func (s station) logo() string {58+ for _, c := range []string{"light", "gray"} {59+ if u := s.Logos[c]; u != "" {60+ return u61+ }62+ }63+ if s.Logo != "" {64+ return s.Logo65+ }66+ for _, c := range []string{"white", "dark"} {67+ if u := s.Logos[c]; u != "" {68+ return u69+ }70+ }71+ return ""72+}73+74+// oldLogos reports whether the stations were kept before their logos'75+// variants were, so the lineup should be read again for them.76+func (st *state) oldLogos() bool {77+ for _, s := range st.Stations {78+ if len(s.Logos) > 0 {79+ return false80+ }81+ }82+ return len(st.Stations) > 04983 }5084 5185 type day struct {
@@ -206,7 +240,7 @@ func (st *state) guide(zip string, now time.Time) *guide.Guide {
206240 from := now.Add(-24 * time.Hour)207241 for _, sta := range st.Stations {208242 g.Channels = append(g.Channels, guide.Channel{209- ID: sta.ID, Number: sta.Number, CallSign: sta.CallSign, Network: guide.NetworkName(sta.Affiliate), Logo: sta.Logo,243+ ID: sta.ID, Number: sta.Number, CallSign: sta.CallSign, Network: guide.NetworkName(sta.Affiliate), Logo: sta.logo(),210244 })211245 for _, d := range st.Days[sta.ID] {212246 for _, a := range d.Airings {