-
Notifications
You must be signed in to change notification settings - Fork 0
fix(library): count logical episodes #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,6 +10,15 @@ data class MediaIndexPosterGroup( | |
| val entries: List<MediaIndexEntry>, | ||
| val animeId: String = entries.posterGroupAnimeId(mergeSameAnimeEnabled = false), | ||
| ) { | ||
| val episodeCount: Int = entries | ||
| .asSequence() | ||
| .filterNot(MediaIndexEntry::isSeriesExtra) | ||
| .distinctBy { entry -> | ||
| entry.episodeNumber?.let { episodeNumber -> | ||
| (entry.seasonNumber ?: 1) to episodeNumber | ||
| } ?: entry.path | ||
| } | ||
| .count() | ||
|
Comment on lines
+13
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Locate indexed-entry conversion and all logical episode-count calculations.
rg -n -C 10 'toIndexedEpisode|distinctSeasonEpisodeCount|MediaIndexEntry|episodeNumber\s*=' --glob '*.kt'Repository: ModerRAS/MiruPlay Length of output: 155 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- candidate files ---'
git ls-files '*MediaIndexPosterGrouping.kt' '*LibraryAnimeResolver.kt' '*MediaIndexEntry*.kt' '*Episode*.kt'
printf '%s\n' '--- relevant symbols ---'
rg -n -C 8 'distinctSeasonEpisodeCount|MediaIndexEntry|episodeNumber|toEpisode|IndexedEpisode|loadAnimeDetail' repository-api --glob '*.kt' || trueRepository: ModerRAS/MiruPlay Length of output: 50374 🏁 Script executed: #!/bin/bash
set -euo pipefail
for file in \
repository-api/src/main/kotlin/com/miruplay/tv/repository/MediaIndexPosterGrouping.kt \
repository-api/src/main/kotlin/com/miruplay/tv/repository/LibraryAnimeResolver.kt
do
echo "--- $file ---"
wc -l "$file"
sed -n '1,180p' "$file"
done
echo '--- conversion and count definitions/usages ---'
rg -n -C 5 'distinctSeasonEpisodeCount|Episode\(|episodeNumber\s*=|filePath\s*=|loadEpisodesForAnime|loadAnimeDetail' \
repository-api/src/main/kotlin/com/miruplay/tv/repository \
--glob '*.kt' \
| head -n 500Repository: ModerRAS/MiruPlay Length of output: 50373 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- logical episode grouping definitions ---'
rg -n -l 'distinctSeasonEpisodeCount|groupEpisodeVersions' --glob '*.kt' | while read -r file; do
echo "--- $file ---"
rg -n -C 18 'distinctSeasonEpisodeCount|groupEpisodeVersions' "$file"
done
echo '--- indexed conversion tests and unnumbered-entry coverage ---'
rg -n -C 12 'toIndexedEpisode|toIndexedEpisodes|episodeNumber\s*=\s*null|episodeCount|unnumbered|without.*episode|missing.*episode' \
repository-api/src/test --glob '*.kt' | head -n 500
echo '--- minimal behavioral model ---'
python3 - <<'PY'
from collections import OrderedDict
entries = [
{"path": "/Show/file-a.mkv", "season": None, "episode": None},
{"path": "/Show/file-b.mkv", "season": None, "episode": None},
]
poster_keys = [
(e["season"] if e["season"] is not None else 1, e["episode"])
if e["episode"] is not None else e["path"]
for e in entries
]
indexed_keys = [
(e["season"] if e["season"] is not None else 1,
e["episode"] if e["episode"] is not None else 1)
for e in entries
]
print({"poster_keys": poster_keys, "poster_count": len(set(poster_keys)),
"indexed_keys": indexed_keys, "detail_count": len(set(indexed_keys))})
PYRepository: ModerRAS/MiruPlay Length of output: 200 🏁 Script executed: #!/bin/bash
set -u
echo '--- exact function references ---'
git grep -n -C 12 -E 'distinctSeasonEpisodeCount|groupEpisodeVersions' -- '*.kt' || true
echo '--- model files containing Episode ---'
git ls-files '*.kt' | while read -r file; do
if grep -qE 'distinctSeasonEpisodeCount|groupEpisodeVersions' "$file"; then
echo "$file"
fi
done
echo '--- behavioral probe ---'
python3 - <<'PY'
entries = [
{"path": "/Show/file-a.mkv", "season": None, "episode": None},
{"path": "/Show/file-b.mkv", "season": None, "episode": None},
]
poster_keys = [
(e["season"] if e["season"] is not None else 1, e["episode"])
if e["episode"] is not None else e["path"]
for e in entries
]
indexed_keys = [
(e["season"] if e["season"] is not None else 1,
e["episode"] if e["episode"] is not None else 1)
for e in entries
]
print("poster_count =", len(set(poster_keys)))
print("detail_count =", len(set(indexed_keys)))
print("poster_keys =", poster_keys)
print("indexed_keys =", indexed_keys)
PYRepository: ModerRAS/MiruPlay Length of output: 43263 Align unnumbered-entry identity rules.
🤖 Prompt for AI Agents |
||
| val primaryEntry: MediaIndexEntry = | ||
| entries | ||
| .filterNot(MediaIndexEntry::isSeriesExtra) | ||
|
|
@@ -24,7 +33,6 @@ data class MediaIndexPosterGroup( | |
| ?: entry.animeName?.takeIf { it.isNotBlank() }?.let { "title:${it.lowercase()}" } | ||
| } | ||
| val subtitle: String = buildString { | ||
| val episodeCount = entries.count { !it.isSeriesExtra() } | ||
| append(episodeCount) | ||
| append(" episode") | ||
| if (episodeCount != 1) append('s') | ||
|
|
@@ -65,7 +73,7 @@ fun MediaIndexPosterGroup.toIndexedAnime(): Anime = | |
| Anime( | ||
| id = animeId, | ||
| title = title, | ||
| episodeCount = entries.count { !it.isSeriesExtra() }, | ||
| episodeCount = episodeCount, | ||
| summary = primaryEntry.plot.orEmpty(), | ||
| ) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Use distinct file paths in the cache regression test.
createTestEpisodeuses/storage/anime/ep01.mkvas the default path for every call. The four rows therefore do not represent four physical files. Pass distinct paths so this test verifies that duplicate playback versions remain available.Proposed test fixture update
📝 Committable suggestion
🤖 Prompt for AI Agents