Fix provider search matching/ranking; add optional curd-web integration hooks#107
Open
ac1606 wants to merge 1 commit into
Open
Fix provider search matching/ranking; add optional curd-web integration hooks#107ac1606 wants to merge 1 commit into
ac1606 wants to merge 1 commit into
Conversation
Several real bugs found while building a browser front-end (curd-web)
that drives curd through a fake-mpv IPC bridge instead of real mpv:
- internal/provider.go: substring containment between a season and its
sequel ("Sword Art Online" vs "Sword Art Online II") was scored as a
fuzzy-match bonus instead of recognized as a different season.
isLikelyDifferentSeason() penalizes titles differing only by a
trailing season/sequel token.
- internal/anilist.go: search re-ranking used raw Levenshtein distance
against the full, unordered query, penalizing legitimate word
reordering ("bunny girl senpai rascal does not dream") as a near-total
mismatch. wordOverlapScore() (fraction of query words present,
order-independent) is now the primary sort key.
- internal/selection_menu.go: bubbletea's tea.NewProgram(...).Run() can
transiently report "could not open a new TTY" right after a prior
Program on the same pty just exited — a real timing race under
non-standard terminal backends, not specific to any one frontend.
Retried up to 4x/75ms apart, scoped to that exact error string.
- internal/provider.go, provider_mapping.go: a previously-saved
provider id was trusted without re-verifying it still matches the
current AniList media; now re-verified via a fresh provider search
(MAL id match, title/season checks, episode-count signal) before
playback.
- internal/provider_disabled.go: default provider stack reordered to
anineko -> anipub -> senshi. Senshi can return metadata-correct
(right title/MAL id/episode) but wrong video content — verified live
by sampling its HLS output with ffmpeg against the other providers
for the same episode.
Also adds two small, additive hooks used by curd-web (no effect on
normal/standalone use):
- CurdWebModeEnabled() (player.go): gated behind a CURD_WEB=1 env var,
exposes the active provider name over the existing mpv IPC channel
(--curd-web-provider on spawn, user-data/curd-web-provider
set_property on reuse) so a browser frontend can show which provider
is serving the current stream.
- SwitchToSingleProviderStream() + -remap-provider flag (main.go,
provider_mapping.go): non-interactively resolves and returns a
directly playable stream on one specific provider for one
anime/episode, without walking the full provider stack. Exists
because providerNamesForAnime deliberately always prefers config
stack order over any saved provider (see
TestProviderNamesForAnimePrefersStackBeforeSavedProvider) — so a
frontend offering a manual "try a different source" action needs a
way to get a specific provider's stream directly rather than relying
on a persisted mapping that the stack order would otherwise walk
straight past.
Full regression suite (go test ./...) and go vet ./... pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A handful of real provider-matching/search bugs found while building a browser
front-end (curd-web) that drives curd through a fake-mpv IPC bridge instead of
real mpv — plus two small, additive, opt-in hooks that frontend uses. None of
this changes default/standalone behavior.
Bug fixes
internal/provider.go): substring containmentbetween a season and its sequel (
"Sword Art Online"vs"Sword Art Online II") was scored as a fuzzy-match bonus instead ofrecognized as a different season.
isLikelyDifferentSeason()penalizestitles differing only by a trailing season/sequel token.
internal/anilist.go): re-rankingused raw Levenshtein distance against the full, unordered query, so a
legitimately reordered query (
"bunny girl senpai rascal does not dream")scored as a near-total mismatch.
wordOverlapScore()(fraction of querywords present, order-independent) is now the primary sort key, Levenshtein
only a tiebreaker.
internal/selection_menu.go):bubbletea's
tea.NewProgram(...).Run()can transiently report"could not open a new TTY"immediately after a priorProgramon the same pty justexited (real timing race, not frontend-specific). Retried up to 4x/75ms
apart, scoped to that exact error string.
internal/provider.go,internal/provider_mapping.go): a previously-saved provider id was usedwithout re-checking it still matches the current AniList media. Now
re-verified via a fresh provider search (MAL id match, title/season checks,
episode-count signal) before playback.
internal/provider_disabled.go):reordered to
anineko -> anipub -> senshi. Senshi can returnmetadata-correct (right title/MAL id/episode) but wrong video content —
verified live by sampling its HLS output with ffmpeg against the other
providers for the same episode/anime.
Regression tests added for each;
go test ./...andgo vet ./...pass.curd-web integration hooks (additive, opt-in, no effect on standalone use)
CurdWebModeEnabled()(internal/player.go): gated behind aCURD_WEB=1env var, exposes the active provider name over the existing mpv IPC channel
(
--curd-web-provideron spawn,user-data/curd-web-providerset_propertyon reuse) so a browser frontend can show which provider is serving the
current stream. Real mpv silently accepts unknown
user-data/*properties,and the CLI flag is never added unless
CURD_WEB=1is set, so this has noeffect when curd drives real mpv directly.
SwitchToSingleProviderStream()+-remap-providerflag (cmd/curd/main.go,internal/provider_mapping.go): non-interactively resolves and returns(as JSON on stdout) a directly playable stream on one specific provider for
one anime/episode, without walking the full provider stack. This exists
because
providerNamesForAnimedeliberately always prefers config stackorder over any saved provider (see
TestProviderNamesForAnimePrefersStackBeforeSavedProvider) — so a frontendoffering a manual "try a different source" action needs a way to get a
specific provider's stream directly, since a persisted remap alone would
otherwise get silently walked past by the stack on the very next episode
load.
Test plan
go build ./...go vet ./...go test ./...(full suite, including new regression tests)SAO II matching, reordered-query search, provider stack order, and the
new
-remap-providerflag resolving a real stream)