feat: add historical backfill with --init CLI and episode numbering
Adds a --init mode that seeds the database with past shows from a given anchor episode/date forward, batch-fetching likes from SoundCloud and partitioning them into weekly buckets. Episode numbers are tracked in the shows table and auto-incremented by the poller for new shows. Includes full API documentation (docs/api.md) and updated README. Made-with: Cursor
This commit is contained in:
@@ -93,6 +93,89 @@ async def test_poll_once_removes_unliked_tracks():
|
||||
assert call_args[0][1] == [1]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_poll_once_auto_assigns_episode_number():
|
||||
mock_sc = AsyncMock()
|
||||
mock_sc.resolve_user.return_value = 206979918
|
||||
mock_sc.fetch_likes.return_value = [
|
||||
_make_track(1, "2026-03-14T01:00:00+00:00"),
|
||||
]
|
||||
|
||||
mock_db = MagicMock()
|
||||
mock_show = MagicMock()
|
||||
mock_show.id = 5
|
||||
mock_show.episode_number = None
|
||||
mock_db.get_or_create_show.return_value = mock_show
|
||||
mock_db.get_latest_episode_number.return_value = 530
|
||||
|
||||
poller = Poller(
|
||||
db=mock_db,
|
||||
soundcloud=mock_sc,
|
||||
soundcloud_user="nicktherat",
|
||||
show_day=2,
|
||||
show_hour=22,
|
||||
poll_interval=3600,
|
||||
)
|
||||
|
||||
await poller.poll_once()
|
||||
|
||||
mock_db.update_show_episode_number.assert_called_once_with(5, 531)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_poll_once_skips_numbering_when_no_history():
|
||||
mock_sc = AsyncMock()
|
||||
mock_sc.resolve_user.return_value = 206979918
|
||||
mock_sc.fetch_likes.return_value = []
|
||||
|
||||
mock_db = MagicMock()
|
||||
mock_show = MagicMock()
|
||||
mock_show.id = 1
|
||||
mock_show.episode_number = None
|
||||
mock_db.get_or_create_show.return_value = mock_show
|
||||
mock_db.get_latest_episode_number.return_value = None
|
||||
|
||||
poller = Poller(
|
||||
db=mock_db,
|
||||
soundcloud=mock_sc,
|
||||
soundcloud_user="nicktherat",
|
||||
show_day=2,
|
||||
show_hour=22,
|
||||
poll_interval=3600,
|
||||
)
|
||||
|
||||
await poller.poll_once()
|
||||
|
||||
mock_db.update_show_episode_number.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_poll_once_skips_numbering_when_already_assigned():
|
||||
mock_sc = AsyncMock()
|
||||
mock_sc.resolve_user.return_value = 206979918
|
||||
mock_sc.fetch_likes.return_value = []
|
||||
|
||||
mock_db = MagicMock()
|
||||
mock_show = MagicMock()
|
||||
mock_show.id = 1
|
||||
mock_show.episode_number = 530
|
||||
mock_db.get_or_create_show.return_value = mock_show
|
||||
|
||||
poller = Poller(
|
||||
db=mock_db,
|
||||
soundcloud=mock_sc,
|
||||
soundcloud_user="nicktherat",
|
||||
show_day=2,
|
||||
show_hour=22,
|
||||
poll_interval=3600,
|
||||
)
|
||||
|
||||
await poller.poll_once()
|
||||
|
||||
mock_db.get_latest_episode_number.assert_not_called()
|
||||
mock_db.update_show_episode_number.assert_not_called()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_poll_once_full_refresh():
|
||||
mock_sc = AsyncMock()
|
||||
|
||||
Reference in New Issue
Block a user