From c1718bc0866a6b03707b79e1c65bce85051db809 Mon Sep 17 00:00:00 2001 From: sudacode Date: Fri, 21 Mar 2025 02:52:28 -0700 Subject: [PATCH] initial commit --- teppei/.gitignore | 2 ++ teppei/open.sh | 9 +++++ teppei/teppei.py | 92 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 teppei/.gitignore create mode 100755 teppei/open.sh create mode 100755 teppei/teppei.py diff --git a/teppei/.gitignore b/teppei/.gitignore new file mode 100644 index 0000000..a1948e3 --- /dev/null +++ b/teppei/.gitignore @@ -0,0 +1,2 @@ +env +.git diff --git a/teppei/open.sh b/teppei/open.sh new file mode 100755 index 0000000..4ce8bd5 --- /dev/null +++ b/teppei/open.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +EP="$1" +export FONTCONFIG_FILE="$HOME/.config/mpv/mpv-fonts.conf" +if mpv --profile=builtin-pseudo-gui --vid=1 --external-file=pod/cover.jpg "pod/Nihongo-Con-Teppei-E$EP.mp3"; then + echo "Finished playing Nihongo Con Teppei E$EP" +else + echo "Failed to play Nihongo Con Teppei E$EP" +fi diff --git a/teppei/teppei.py b/teppei/teppei.py new file mode 100755 index 0000000..fe2b932 --- /dev/null +++ b/teppei/teppei.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +import logging +from argparse import ArgumentParser + +from requests import get +from selenium import webdriver +from selenium.webdriver.chrome.options import Options +from selenium.webdriver.common.by import By +from selenium.webdriver.support import expected_conditions as EC +from selenium.webdriver.support.ui import WebDriverWait + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) +logger.setLevel(logging.INFO) + +AUDIO_BASE_URL = ( + "https://www.heypera.com/listen/nihongo-con-teppei-for-beginners/{}/next" +) +SUB_BASE_URL = "https://storage.googleapis.com/pera-transcripts/nihongo-con-teppei-for-beginners/transcripts/{}.vtt" + + +def get_audio_url(episode_num: int): + chrome_options = Options() + chrome_options.add_argument("--headless") + chrome_options.add_argument("--disable-gpu") + chrome_options.add_argument("--no-sandbox") + + driver = webdriver.Chrome(options=chrome_options) + + try: + driver.get(AUDIO_BASE_URL.format(episode_num)) + + # Wait for the audio element to be present + audio_element = WebDriverWait(driver, 10).until( + EC.presence_of_element_located((By.TAG_NAME, "audio")) + ) + audio_url = audio_element.get_attribute("src") + if audio_url: + logger.info(f"Audio URL: {audio_url}") + else: + logger.error("No audio URL found") + return audio_url + except Exception as e: + logger.error(f"Error: {e}") + raise e + finally: + driver.quit() + + +def get_sub_url(episode_num: int): + return SUB_BASE_URL.format(episode_num) + + +def download_file(url: str, filename: str): + response = get(url, timeout=10) + if response.status_code != 200: + logger.error(f"Failed to download {filename}") + return + with open(filename, "wb") as file: + file.write(response.content) + logger.info(f"Downloaded {filename}") + + +def parse_args(): + parser = ArgumentParser(description="Get the audio URL for a given episode number") + parser.add_argument( + "episode_num", type=int, help="The episode number to get the audio URL for" + ) + parser.add_argument( + "-d", "--download", action="store_true", help="Download the audio file" + ) + parser.add_argument("-o", "--output", help="Output directory name") + return parser.parse_args() + + +if __name__ == "__main__": + args = parse_args() + if args.episode_num < 1: + logger.error("Episode number must be greater than 0") + episode = args.episode_num + audio = get_audio_url(episode) + sub = get_sub_url(episode) + if args.download: + if args.output: + download_file(audio, f"{args.output}/Nihongo-Con-Teppei-E{episode:0>2}.mp3") + download_file(sub, f"{args.output}/Nihongo-Con-Teppei-E{episode:0>2}.vtt") + else: + download_file(audio, f"Nihongo-Con-Teppei-E{episode:0>2}.mp3") + download_file(sub, f"Nihongo-Con-Teppei-E{episode:0>2}.vtt") + else: + print(f"Audio URL: {audio}") + print(f"Subtitle URL: {sub}")