vault_report.podcasts

Documentation for eth_defi.vault_report.podcasts Python module.

Latest Trading Strategy podcast episodes for the monthly vault report.

The Trading Strategy podcast publishes each episode as a blog post on Ghost. The website lists every post whose title contains “episode” (src/routes/podcast/+page.ts in the frontend), and this module uses the same rule through the Ghost Content API.

Each episode post follows the same template, which this module reads:

  • the first paragraph is the promotion text, e.g. “Listen to our latest episode featuring Yearn and learn why …”;

  • it links to the episode on Spotify (open.spotify.com/episode/...) and YouTube (youtu.be/... or youtube.com/watch?v=...);

  • it links to the guest’s page on the website, e.g. tradingstrategy.ai/vaults/curators/yearn or tradingstrategy.ai/vaults/protocols/frankencoin, whose slug names the guest’s logo in eth_defi/data/vaults/formatted_logos.

Module Attributes

PODCAST_PAGE_URL

The podcast index page on the website

PODCAST_FILTER

Ghost NQL filter matching the website's podcast rule: the title contains "episode", case-insensitively

LATEST_PODCAST_COUNT

Number of episodes in the report

PODCAST_SERVICES

Link label of each listening service, by its icon name in assets/podcast

Functions

clean_episode_link(url)

Remove share-tracking parameters from a Spotify or YouTube link.

fetch_latest_podcast_episodes(client[, count])

Fetch the latest podcast episodes from the blog.

icon_image_key(service)

Key of a listening service icon in the podcast image mapping, e.g.

logo_image_key(slug)

Key of a guest logo in the podcast image mapping, see render_podcast_episodes().

parse_podcast_episode(post)

Read an episode's promotion text, links and guest from its blog post.

render_podcast_episodes(episodes, images)

Render the podcast episode list for the post.

Classes

PodcastEpisode

One podcast episode, read from its blog post.

PODCAST_PAGE_URL = 'https://tradingstrategy.ai/podcast'

The podcast index page on the website

PODCAST_FILTER = "title:~'episode'"

Ghost NQL filter matching the website’s podcast rule: the title contains “episode”, case-insensitively

LATEST_PODCAST_COUNT = 4

Number of episodes in the report

PODCAST_SERVICES = {'spotify': 'Listen on Spotify', 'youtube': 'Watch on YouTube'}

Link label of each listening service, by its icon name in assets/podcast

logo_image_key(slug)

Key of a guest logo in the podcast image mapping, see render_podcast_episodes().

Guest logos and service icons share one mapping from key to uploaded image URL, so each kind of image has its own key prefix.

Parameters

slug (str) – Curator or protocol slug of the guest, e.g. yearn.

Returns

Mapping key, e.g. logo:yearn.

Return type

str

icon_image_key(service)

Key of a listening service icon in the podcast image mapping, e.g. icon:youtube.

Guest logos and service icons share one mapping from key to uploaded image URL, so each kind of image has its own key prefix.

Parameters

service (str) – Listening service icon name, a key of PODCAST_SERVICES.

Returns

Mapping key, e.g. icon:youtube.

Return type

str

Spotify episode link

YouTube watch link; embeds are skipped because they only play inside a page

Link to the guest’s curator or protocol page on the website

class PodcastEpisode

Bases: object

One podcast episode, read from its blog post.

title: str

Post title, e.g. Episode #13: Yearn

url: str

Blog post URL

published_at: Optional[datetime.datetime]

Publication time, naive UTC

promotion: str

First paragraph of the post, plain text

spotify_url: Optional[str]

Episode on Spotify, or None if the post has no link

youtube_url: Optional[str]

Episode on YouTube, or None if the post has no link

logo_slug: Optional[str]

Curator or protocol slug of the guest, for its logo, or None

property guest: str

Guest name from the title, e.g. Yearn from Episode #13: Yearn.

__init__(title, url, published_at, promotion, spotify_url, youtube_url, logo_slug)
Parameters
Return type

None

Remove share-tracking parameters from a Spotify or YouTube link.

Spotify links need no query string. YouTube links keep only the v video id of youtube.com/watch links.

Parameters

url (str) – Link from the post, e.g. https://youtu.be/abc?si=xyz&ref=example.ghost.io.

Returns

E.g. https://youtu.be/abc.

Return type

str

parse_podcast_episode(post)

Read an episode’s promotion text, links and guest from its blog post.

Episode posts are written by hand in Ghost from one template (see the module docstring), so this reads them with regular expressions over the rendered HTML rather than a structured field: Ghost has no custom fields for the listening links. A post that strays from the template still produces an episode, with the missing parts as None; the Latest podcasts section then leaves out that link or logo, and a warning tells the operator which post to fix in Ghost.

Parameters

post (eth_defi.vault_report.ghost.GhostPost) – Episode post with its HTML body, from fetch_latest_posts().

Returns

Parsed episode. Links that are missing from the post are None.

Return type

eth_defi.vault_report.podcasts.PodcastEpisode

fetch_latest_podcast_episodes(client, count=4)

Fetch the latest podcast episodes from the blog.

Parameters
Returns

Episodes, newest first.

Return type

list[eth_defi.vault_report.podcasts.PodcastEpisode]

render_podcast_episodes(episodes, images)

Render the podcast episode list for the post.

Each episode is a table row with the guest’s logo, the episode title linked to its blog post, the promotion text and the YouTube and Spotify links, each with the service’s icon. A table keeps the logo beside the text in Ghost and in newsletter email clients. The website stylesheet controls layout through podcast-episodes, podcast-episode-description and podcast-episode-links, matching the editor’s published markup.

Parameters
Returns

HTML table.

Return type

str