Skip to content

Add YuTorah provider for streaming Torah shiurim#3429

Draft
russlevy wants to merge 20 commits intomusic-assistant:devfrom
russlevy:dev
Draft

Add YuTorah provider for streaming Torah shiurim#3429
russlevy wants to merge 20 commits intomusic-assistant:devfrom
russlevy:dev

Conversation

@russlevy
Copy link
Copy Markdown

Adds a new music provider for YuTorah Online, streaming over 400,000 Torah audio lectures via the official mobile app API.

Features:

  • Browse by series, teacher, or topic category
  • Search returns series (Podcasts), teachers (Artists), and individual shiurim (Tracks)
  • Login optional — unauthenticated users get a preview; authenticated users get full paginated episode lists and search
  • Breadcrumbs use human-readable name slugs (not raw numeric IDs)
  • Backward-compatible with any previously saved browse paths

Data model:

  • Series → Podcast / PodcastEpisode
  • Teacher → Artist / Track (top tracks)
  • Individual shiur → Track (search results)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 19, 2026

🔒 Dependency Security Report

✅ No dependency changes detected in this PR.

@russlevy
Copy link
Copy Markdown
Author

Label should be new-provider (I cannot add it)

Comment thread music_assistant/providers/yutorah/__init__.py Outdated
Comment thread music_assistant/providers/yutorah/__init__.py Outdated
Comment thread music_assistant/providers/yutorah/__init__.py Outdated
Comment thread music_assistant/providers/yutorah/__init__.py Outdated
Comment thread music_assistant/providers/yutorah/__init__.py Outdated
Comment thread music_assistant/providers/yutorah/__init__.py Outdated
Comment thread music_assistant/providers/yutorah/manifest.json Outdated
Comment thread music_assistant/providers/yutorah/manifest.json
Comment thread music_assistant/providers/yutorah/manifest.json Outdated
Comment thread music_assistant/providers/yutorah/__init__.py Outdated
Comment thread music_assistant/providers/yutorah/manifest.json Outdated
@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented Mar 20, 2026

Also having the whole provider in one file is too much. Please split this into init.py, constants.py, helpers.py and provider.py

@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented Mar 20, 2026

There is a bit to consider here. Marking as draft. Set it back to review required when it’s ready.

@OzGav OzGav marked this pull request as draft March 20, 2026 05:23
@russlevy
Copy link
Copy Markdown
Author

There is a bit to consider here. Marking as draft. Set it back to review required when it’s ready.

Should I mark it as ready when I'm done getting through everything? Just moving functions around right now

@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented Mar 20, 2026

As your resolve each comment then mark it as such by clicking the resolve conversation button. Yes once you think it is ready for review towards merging then click the “Ready for Review” button. Just don’t rush it.

@russlevy
Copy link
Copy Markdown
Author

As your resolve each comment then mark it as such by clicking the resolve conversation button. Yes once you think it is ready for review towards merging then click the “Ready for Review” button. Just don’t rush it.

OK great. My general practice has been to make the reviewer resolve when they are happy with the fix, but happy to do it too! Of course not rushing, going to spend a bit of time thinking through the whole podcast / teacher stuff. probably needs a bunch of testing too, when I'm happy with the result I'll mark it as ready for review.

@russlevy russlevy force-pushed the dev branch 2 times, most recently from 84c5673 to 58da8cb Compare March 20, 2026 09:12
@russlevy russlevy marked this pull request as ready for review March 22, 2026 19:03
apophisnow and others added 8 commits March 22, 2026 21:04
Co-authored-by: marcelveldt <6389780+marcelveldt@users.noreply.github.com>
…sic-assistant#3439)

* Clean up party plugin config options

Remove album art background config option and make party player
selection independent of guest access toggle so party mode works
without QR code enabled. Clean up karaoke mode label.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove QR code instruction text config options from party plugin

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Parallelize filesystem library sync for faster NFS ingestion

Replace the serial single-threaded sync loop with a two-phase approach:
- Phase 1: Enumerate files in an executor thread (fast metadata scan)
- Phase 2: Process changed files concurrently using TaskManager(16)

This replaces blocking parse_tags + run_coroutine_threadsafe(..).result()
calls with async_parse_tags, allowing up to 16 ffprobe processes to run
concurrently. For NFS mounts where each ffprobe has ~500ms latency,
this yields ~16x throughput improvement on tag parsing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Report sync progress percentage to frontend

Use update_current_task_progress_from_index during Phase 2 of library
sync so the frontend can display a progress bar instead of just text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: OzGav <gavnosp@hotmail.com>
Co-authored-by: OzGav <gavnosp@hotmail.com>
add YU shield icon for yutorah provider

fix: raise SetupFailedError on login failure

refactor: split into multiple files, require login

fix: remove LIBRARY_PODCASTS and get_library_podcasts override

small fixes

fix: split some files and pr review comments

small logical fixes
@russlevy russlevy requested review from OzGav and teancom March 22, 2026 19:17
Copy link
Copy Markdown
Author

@russlevy russlevy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be ready for re-review. I've tried to manually test every path as well too ensure it's working. As well, I felt that provider.py was going to be too big still, so I copied Apple Music and created a browse.py file. Finally, felt some of the functions were a bit unwieldy so broke them up into helper functions.

Comment thread music_assistant/providers/yutorah/browse.py Outdated
)


def _shiur_to_track(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think returning shiurim as Track objects in search results is right. A shiur has no artist and no album, so the track will appear incomplete in the search UI. More importantly, MA will treat it as a music track and attempt metadata enrichment — MusicBrainz lookups etc. — for content that is fundamentally a podcast episode. If SearchResults has no podcast_episodes field, should we raise a model enhancement request to add one rather than misusing Track?

@MarvinSchenkel thoughts on this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah agree with @OzGav here. Looking at this provider, it exclusively delivers podcasts / podcast episodes. I think we can remove any references to Artists and Tracks. Since there are not library_xxxx functions (because I don't think YuToarh has a library?), you can rely on browse endpoints so people can still browse the content by teacher for example.

Copy link
Copy Markdown
Author

@russlevy russlevy Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is the discoverability. Almost all of the episodes are standalone, and you may want to search for a specific topic to find it across different teachers and series. This is how it works on yutorah.org as well -- though there are teacher, and teacher / series pairs (which we are modeling as podcasts), the primary search is by class / shiur / episode

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then the fix is possibly to adjust the search to return results which match the teacher name as well as the podcast name. You can also implement different browse folders if there are topics that users might typically be interested in.

Comment thread music_assistant/providers/yutorah/provider.py Outdated
Comment thread music_assistant/providers/yutorah/browse.py
@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented Mar 23, 2026

There are a bunch of tests failing (although one looks unrelated to your code so ignore that)

@russlevy russlevy requested a review from OzGav March 23, 2026 07:03
},
)

async def get_artist_toptracks(self, prov_artist_id: str) -> list[Track]:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m still not sure about teachers as artists but on this particular method, it won’t get called as you haven’t added the relevant provider feature

@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented Mar 24, 2026

Please update the PR description with any changes made through this process. This will probably get looked at further next week.

teacher_name = shiur.get("teacherfullname") or ""
photo = shiur.get("PHOTO") or shiur.get("photo") or ""
if photo and not photo.startswith("http"):
photo = f"https://cdnyutorah.cachefly.net/_images/roshei_yeshiva/{photo}"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can move this into constants.py too

@MarvinSchenkel
Copy link
Copy Markdown
Contributor

Hey @russlevy, marking this PR as draft so we can keep on top of which PRs need our attention. Just flag it as 'ready for review' when you want us to have another look!

@MarvinSchenkel MarvinSchenkel marked this pull request as draft March 31, 2026 10:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants