mirror of
https://github.com/dmunozv04/iSponsorBlockTV.git
synced 2025-12-09 21:46:45 +03:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d17e59bf0d | ||
|
|
205191f442 | ||
|
|
810cd5eec3 | ||
|
|
e2ace8629f | ||
|
|
e54ead26d2 | ||
|
|
49fba2f28f | ||
|
|
b1333a2f61 | ||
|
|
cfef219d32 | ||
|
|
338e0479ba | ||
|
|
bfefa94a7b | ||
|
|
783e3d4240 | ||
|
|
015f5a79c9 | ||
|
|
dc72db0609 | ||
|
|
8de38cc92b | ||
|
|
94ba642af1 | ||
|
|
6e09db9994 | ||
|
|
b56d7443d1 | ||
|
|
e92ba897c4 | ||
|
|
5214190fd0 | ||
|
|
d3341009a6 | ||
|
|
adc0f5b95d | ||
|
|
5dbd16ddd5 | ||
|
|
faa0379b89 | ||
|
|
fb3ed6b39a | ||
|
|
865f5469a2 | ||
|
|
daa7026221 |
14
.github/workflows/build_docker_images.yml
vendored
14
.github/workflows/build_docker_images.yml
vendored
@@ -25,12 +25,12 @@ jobs:
|
||||
steps:
|
||||
# Get the repository's code
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Generate docker tags
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/dmunozv04/isponsorblocktv, dmunozv04/isponsorblocktv
|
||||
tags: |
|
||||
@@ -42,29 +42,29 @@ jobs:
|
||||
|
||||
# https://github.com/docker/setup-qemu-action
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
# https://github.com/docker/setup-buildx-action
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to DockerHub
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Login to GHCR
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64, linux/arm64, linux/arm/v7
|
||||
|
||||
4
.github/workflows/release_pypi.yml
vendored
4
.github/workflows/release_pypi.yml
vendored
@@ -22,9 +22,9 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v3
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
- name: Install dependencies
|
||||
|
||||
2
.github/workflows/update_docker_readme.yml
vendored
2
.github/workflows/update_docker_readme.yml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
|
||||
# Update description
|
||||
- name: Update repo description
|
||||
uses: peter-evans/dockerhub-description@v3
|
||||
uses: peter-evans/dockerhub-description@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
10
Dockerfile
10
Dockerfile
@@ -16,12 +16,12 @@ COPY requirements.txt .
|
||||
|
||||
RUN apk add --no-cache gcc musl-dev && \
|
||||
pip install --upgrade pip wheel && \
|
||||
pip install --user -r requirements.txt && \
|
||||
pip install -r requirements.txt && \
|
||||
pip uninstall -y pip wheel && \
|
||||
apk del gcc musl-dev && \
|
||||
python3 -m compileall -b -f /root/.local/lib/python3.11/site-packages && \
|
||||
find /root/.local/lib/python3.11/site-packages -name "*.py" -type f -delete && \
|
||||
find /root/.local/lib/python3.11/ -name "__pycache__" -type d -exec rm -rf {} +
|
||||
python3 -m compileall -b -f /usr/local/lib/python3.11/site-packages && \
|
||||
find /usr/local/lib/python3.11/site-packages -name "*.py" -type f -delete && \
|
||||
find /usr/local/lib/python3.11/ -name "__pycache__" -type d -exec rm -rf {} +
|
||||
|
||||
FROM base
|
||||
|
||||
@@ -29,7 +29,7 @@ ENV PIP_NO_CACHE_DIR=off iSPBTV_docker=True iSPBTV_data_dir=data TERM=xterm-256c
|
||||
|
||||
COPY requirements.txt .
|
||||
|
||||
COPY --from=dep_installer /root/.local /root/.local
|
||||
COPY --from=dep_installer /usr/local /usr/local
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"skip_count_tracking": true,
|
||||
"mute_ads": true,
|
||||
"skip_ads": true,
|
||||
"autoplay": true,
|
||||
"apikey": "",
|
||||
"channel_whitelist": [
|
||||
{"id": "",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "iSponsorBlockTV"
|
||||
version = "2.0.7"
|
||||
version = "2.1.0"
|
||||
authors = [
|
||||
{"name" = "dmunozv04"}
|
||||
]
|
||||
|
||||
@@ -1,169 +1,195 @@
|
||||
import asyncio
|
||||
|
||||
import aiohttp
|
||||
|
||||
from . import api_helpers, ytlounge
|
||||
|
||||
|
||||
async def pair_device(web_session):
|
||||
try:
|
||||
lounge_controller = ytlounge.YtLoungeApi(
|
||||
"iSponsorBlockTV", web_session=web_session
|
||||
)
|
||||
pairing_code = input(
|
||||
"Enter pairing code (found in Settings - Link with TV code): "
|
||||
)
|
||||
pairing_code = int(
|
||||
pairing_code.replace("-", "").replace(" ", "")
|
||||
) # remove dashes and spaces
|
||||
print("Pairing...")
|
||||
paired = await lounge_controller.pair(pairing_code)
|
||||
if not paired:
|
||||
print("Failed to pair device")
|
||||
return
|
||||
device = {
|
||||
"screen_id": lounge_controller.auth.screen_id,
|
||||
"name": lounge_controller.screen_name,
|
||||
}
|
||||
print(f"Paired device: {device['name']}")
|
||||
return device
|
||||
except Exception as e:
|
||||
print(f"Failed to pair device: {e}")
|
||||
return
|
||||
|
||||
|
||||
def main(config, debug: bool) -> None:
|
||||
print("Welcome to the iSponsorBlockTV cli setup wizard")
|
||||
loop = asyncio.get_event_loop_policy().get_event_loop()
|
||||
web_session = aiohttp.ClientSession()
|
||||
if debug:
|
||||
loop.set_debug(True)
|
||||
asyncio.set_event_loop(loop)
|
||||
if hasattr(config, "atvs"):
|
||||
print(
|
||||
"The atvs config option is deprecated and has stopped working. Please read"
|
||||
" this for more information on how to upgrade to V2:"
|
||||
" \nhttps://github.com/dmunozv04/iSponsorBlockTV/wiki/Migrate-from-V1-to-V2"
|
||||
)
|
||||
if (
|
||||
input(
|
||||
"Do you want to remove the legacy 'atvs' entry (the app won't start"
|
||||
" with it present)? (y/n) "
|
||||
)
|
||||
== "y"
|
||||
):
|
||||
del config["atvs"]
|
||||
devices = config.devices
|
||||
while not input(f"Paired with {len(devices)} Device(s). Add more? (y/n) ") == "n":
|
||||
task = loop.create_task(pair_device(web_session))
|
||||
loop.run_until_complete(task)
|
||||
device = task.result()
|
||||
if device:
|
||||
devices.append(device)
|
||||
config.devices = devices
|
||||
|
||||
apikey = config.apikey
|
||||
if apikey:
|
||||
if input("API key already specified. Change it? (y/n) ") == "y":
|
||||
apikey = input("Enter your API key: ")
|
||||
else:
|
||||
if (
|
||||
input(
|
||||
"API key only needed for the channel whitelist function. Add it? (y/n) "
|
||||
)
|
||||
== "y"
|
||||
):
|
||||
print(
|
||||
"Get youtube apikey here:"
|
||||
" https://developers.google.com/youtube/registering_an_application"
|
||||
)
|
||||
apikey = input("Enter your API key: ")
|
||||
config.apikey = apikey
|
||||
|
||||
skip_categories = config.skip_categories
|
||||
if skip_categories:
|
||||
if input("Skip categories already specified. Change them? (y/n) ") == "y":
|
||||
categories = input(
|
||||
"Enter skip categories (space or comma sepparated) Options: [sponsor"
|
||||
" selfpromo exclusive_access interaction poi_highlight intro outro"
|
||||
" preview filler music_offtopic]:\n"
|
||||
)
|
||||
skip_categories = categories.replace(",", " ").split(" ")
|
||||
skip_categories = [
|
||||
x for x in skip_categories if x != ""
|
||||
] # Remove empty strings
|
||||
else:
|
||||
categories = input(
|
||||
"Enter skip categories (space or comma sepparated) Options: [sponsor,"
|
||||
" selfpromo, exclusive_access, interaction, poi_highlight, intro, outro,"
|
||||
" preview, filler, music_offtopic:\n"
|
||||
)
|
||||
skip_categories = categories.replace(",", " ").split(" ")
|
||||
skip_categories = [
|
||||
x for x in skip_categories if x != ""
|
||||
] # Remove empty strings
|
||||
config.skip_categories = skip_categories
|
||||
|
||||
channel_whitelist = config.channel_whitelist
|
||||
if (
|
||||
input("Do you want to whitelist any channels from being ad-blocked? (y/n) ")
|
||||
== "y"
|
||||
):
|
||||
if not apikey:
|
||||
print(
|
||||
"WARNING: You need to specify an API key to use this function,"
|
||||
" otherwise the program will fail to start.\nYou can add one by"
|
||||
" re-running this setup wizard."
|
||||
)
|
||||
api_helper = api_helpers.ApiHelper(config, web_session)
|
||||
while True:
|
||||
channel_info = {}
|
||||
channel = input('Enter a channel name or "/exit" to exit: ')
|
||||
if channel == "/exit":
|
||||
break
|
||||
|
||||
task = loop.create_task(
|
||||
api_helper.search_channels(channel, apikey, web_session)
|
||||
)
|
||||
loop.run_until_complete(task)
|
||||
results = task.result()
|
||||
if len(results) == 0:
|
||||
print("No channels found")
|
||||
continue
|
||||
|
||||
for i, item in enumerate(results):
|
||||
print(f"{i}: {item[1]} - Subs: {item[2]}")
|
||||
print("5: Enter a custom channel ID")
|
||||
print("6: Go back")
|
||||
|
||||
choice = -1
|
||||
choice = input("Select one option of the above [0-6]: ")
|
||||
while choice not in [str(x) for x in range(7)]:
|
||||
print("Invalid choice")
|
||||
choice = input("Select one option of the above [0-6]: ")
|
||||
|
||||
if choice == "5":
|
||||
channel_info["id"] = input("Enter a channel ID: ")
|
||||
channel_info["name"] = input("Enter the channel name: ")
|
||||
channel_whitelist.append(channel_info)
|
||||
continue
|
||||
if choice == "6":
|
||||
continue
|
||||
|
||||
channel_info["id"] = results[int(choice)][0]
|
||||
channel_info["name"] = results[int(choice)][1]
|
||||
channel_whitelist.append(channel_info)
|
||||
# Close web session asynchronously
|
||||
|
||||
config.channel_whitelist = channel_whitelist
|
||||
|
||||
config.skip_count_tracking = (
|
||||
not input(
|
||||
"Do you want to report skipped segments to sponsorblock. Only the segment"
|
||||
" UUID will be sent? (y/n) "
|
||||
)
|
||||
== "n"
|
||||
)
|
||||
print("Config finished")
|
||||
config.save()
|
||||
loop.run_until_complete(web_session.close())
|
||||
import asyncio
|
||||
|
||||
import aiohttp
|
||||
|
||||
from . import api_helpers, ytlounge
|
||||
|
||||
# Constants for user input prompts
|
||||
ATVS_REMOVAL_PROMPT = (
|
||||
"Do you want to remove the legacy 'atvs' entry (the app won't start"
|
||||
" with it present)? (y/N) "
|
||||
)
|
||||
PAIRING_CODE_PROMPT = "Enter pairing code (found in Settings - Link with TV code): "
|
||||
ADD_MORE_DEVICES_PROMPT = "Paired with {num_devices} Device(s). Add more? (y/N) "
|
||||
CHANGE_API_KEY_PROMPT = "API key already specified. Change it? (y/N) "
|
||||
ADD_API_KEY_PROMPT = (
|
||||
"API key only needed for the channel whitelist function. Add it? (y/N) "
|
||||
)
|
||||
ENTER_API_KEY_PROMPT = "Enter your API key: "
|
||||
CHANGE_SKIP_CATEGORIES_PROMPT = "Skip categories already specified. Change them? (y/N) "
|
||||
ENTER_SKIP_CATEGORIES_PROMPT = (
|
||||
"Enter skip categories (space or comma sepparated) Options: [sponsor,"
|
||||
" selfpromo, exclusive_access, interaction, poi_highlight, intro, outro,"
|
||||
" preview, filler, music_offtopic]:\n"
|
||||
)
|
||||
WHITELIST_CHANNELS_PROMPT = (
|
||||
"Do you want to whitelist any channels from being ad-blocked? (y/N) "
|
||||
)
|
||||
SEARCH_CHANNEL_PROMPT = 'Enter a channel name or "/exit" to exit: '
|
||||
SELECT_CHANNEL_PROMPT = "Select one option of the above [0-6]: "
|
||||
ENTER_CHANNEL_ID_PROMPT = "Enter a channel ID: "
|
||||
ENTER_CUSTOM_CHANNEL_NAME_PROMPT = "Enter the channel name: "
|
||||
REPORT_SKIPPED_SEGMENTS_PROMPT = (
|
||||
"Do you want to report skipped segments to sponsorblock. Only the segment"
|
||||
" UUID will be sent? (Y/n) "
|
||||
)
|
||||
MUTE_ADS_PROMPT = "Do you want to mute native YouTube ads automatically? (y/N) "
|
||||
SKIP_ADS_PROMPT = "Do you want to skip native YouTube ads automatically? (y/N) "
|
||||
AUTOPLAY_PROMPT = "Do you want to enable autoplay? (Y/n) "
|
||||
|
||||
|
||||
def get_yn_input(prompt):
|
||||
while choice := input(prompt):
|
||||
if choice.lower() in ["y", "n"]:
|
||||
return choice.lower()
|
||||
print("Invalid input. Please enter 'y' or 'n'.")
|
||||
|
||||
|
||||
async def pair_device():
|
||||
try:
|
||||
lounge_controller = ytlounge.YtLoungeApi("iSponsorBlockTV")
|
||||
pairing_code = input(PAIRING_CODE_PROMPT)
|
||||
pairing_code = int(
|
||||
pairing_code.replace("-", "").replace(" ", "")
|
||||
) # remove dashes and spaces
|
||||
print("Pairing...")
|
||||
paired = await lounge_controller.pair(pairing_code)
|
||||
if not paired:
|
||||
print("Failed to pair device")
|
||||
return
|
||||
device = {
|
||||
"screen_id": lounge_controller.auth.screen_id,
|
||||
"name": lounge_controller.screen_name,
|
||||
}
|
||||
print(f"Paired device: {device['name']}")
|
||||
return device
|
||||
except Exception as e:
|
||||
print(f"Failed to pair device: {e}")
|
||||
return
|
||||
|
||||
|
||||
def main(config, debug: bool) -> None:
|
||||
print("Welcome to the iSponsorBlockTV cli setup wizard")
|
||||
loop = asyncio.get_event_loop_policy().get_event_loop()
|
||||
web_session = aiohttp.ClientSession()
|
||||
if debug:
|
||||
loop.set_debug(True)
|
||||
asyncio.set_event_loop(loop)
|
||||
if hasattr(config, "atvs"):
|
||||
print(
|
||||
"The atvs config option is deprecated and has stopped working. Please read"
|
||||
" this for more information on how to upgrade to V2:"
|
||||
" \nhttps://github.com/dmunozv04/iSponsorBlockTV/wiki/Migrate-from-V1-to-V2"
|
||||
)
|
||||
choice = get_yn_input(ATVS_REMOVAL_PROMPT)
|
||||
if choice == "y":
|
||||
del config["atvs"]
|
||||
|
||||
devices = config.devices
|
||||
choice = get_yn_input(ADD_MORE_DEVICES_PROMPT.format(num_devices=len(devices)))
|
||||
while choice == "y":
|
||||
task = loop.create_task(pair_device())
|
||||
loop.run_until_complete(task)
|
||||
device = task.result()
|
||||
if device:
|
||||
devices.append(device)
|
||||
choice = get_yn_input(ADD_MORE_DEVICES_PROMPT.format(num_devices=len(devices)))
|
||||
config.devices = devices
|
||||
|
||||
apikey = config.apikey
|
||||
if apikey:
|
||||
choice = get_yn_input(CHANGE_API_KEY_PROMPT)
|
||||
if choice == "y":
|
||||
apikey = input(ENTER_API_KEY_PROMPT)
|
||||
else:
|
||||
choice = get_yn_input(ADD_API_KEY_PROMPT)
|
||||
if choice == "y":
|
||||
print(
|
||||
"Get youtube apikey here:"
|
||||
" https://developers.google.com/youtube/registering_an_application"
|
||||
)
|
||||
apikey = input(ENTER_API_KEY_PROMPT)
|
||||
config.apikey = apikey
|
||||
|
||||
skip_categories = config.skip_categories
|
||||
if skip_categories:
|
||||
choice = get_yn_input(CHANGE_SKIP_CATEGORIES_PROMPT)
|
||||
if choice == "y":
|
||||
categories = input(ENTER_SKIP_CATEGORIES_PROMPT)
|
||||
skip_categories = categories.replace(",", " ").split(" ")
|
||||
skip_categories = [
|
||||
x for x in skip_categories if x != ""
|
||||
] # Remove empty strings
|
||||
else:
|
||||
categories = input(ENTER_SKIP_CATEGORIES_PROMPT)
|
||||
skip_categories = categories.replace(",", " ").split(" ")
|
||||
skip_categories = [
|
||||
x for x in skip_categories if x != ""
|
||||
] # Remove empty strings
|
||||
config.skip_categories = skip_categories
|
||||
|
||||
channel_whitelist = config.channel_whitelist
|
||||
choice = get_yn_input(WHITELIST_CHANNELS_PROMPT)
|
||||
if choice == "y":
|
||||
if not apikey:
|
||||
print(
|
||||
"WARNING: You need to specify an API key to use this function,"
|
||||
" otherwise the program will fail to start.\nYou can add one by"
|
||||
" re-running this setup wizard."
|
||||
)
|
||||
api_helper = api_helpers.ApiHelper(config, web_session)
|
||||
while True:
|
||||
channel_info = {}
|
||||
channel = input(SEARCH_CHANNEL_PROMPT)
|
||||
if channel == "/exit":
|
||||
break
|
||||
|
||||
task = loop.create_task(
|
||||
api_helper.search_channels(channel, apikey, web_session)
|
||||
)
|
||||
loop.run_until_complete(task)
|
||||
results = task.result()
|
||||
if len(results) == 0:
|
||||
print("No channels found")
|
||||
continue
|
||||
|
||||
for i, item in enumerate(results):
|
||||
print(f"{i}: {item[1]} - Subs: {item[2]}")
|
||||
print("5: Enter a custom channel ID")
|
||||
print("6: Go back")
|
||||
|
||||
while choice := input(SELECT_CHANNEL_PROMPT):
|
||||
if choice in [str(x) for x in range(7)]:
|
||||
break
|
||||
print("Invalid choice")
|
||||
|
||||
if choice == "5":
|
||||
channel_info["id"] = input(ENTER_CHANNEL_ID_PROMPT)
|
||||
channel_info["name"] = input(ENTER_CUSTOM_CHANNEL_NAME_PROMPT)
|
||||
channel_whitelist.append(channel_info)
|
||||
continue
|
||||
if choice == "6":
|
||||
continue
|
||||
|
||||
channel_info["id"] = results[int(choice)][0]
|
||||
channel_info["name"] = results[int(choice)][1]
|
||||
channel_whitelist.append(channel_info)
|
||||
# Close web session asynchronously
|
||||
|
||||
config.channel_whitelist = channel_whitelist
|
||||
|
||||
choice = get_yn_input(REPORT_SKIPPED_SEGMENTS_PROMPT)
|
||||
config.skip_count_tracking = choice != "n"
|
||||
|
||||
choice = get_yn_input(MUTE_ADS_PROMPT)
|
||||
config.mute_ads = choice == "y"
|
||||
|
||||
choice = get_yn_input(SKIP_ADS_PROMPT)
|
||||
config.skip_ads = choice == "y"
|
||||
|
||||
choice = get_yn_input(AUTOPLAY_PROMPT)
|
||||
config.auto_play = choice != "n"
|
||||
|
||||
print("Config finished")
|
||||
config.save()
|
||||
loop.run_until_complete(web_session.close())
|
||||
|
||||
@@ -41,6 +41,7 @@ class Config:
|
||||
self.skip_count_tracking = True
|
||||
self.mute_ads = False
|
||||
self.skip_ads = False
|
||||
self.auto_play = True
|
||||
self.__load()
|
||||
|
||||
def validate(self):
|
||||
|
||||
@@ -52,13 +52,13 @@ class DeviceListener:
|
||||
# Main subscription loop
|
||||
async def loop(self):
|
||||
lounge_controller = self.lounge_controller
|
||||
while not lounge_controller.linked():
|
||||
try:
|
||||
self.logger.debug("Refreshing auth")
|
||||
await lounge_controller.refresh_auth()
|
||||
except:
|
||||
await asyncio.sleep(10)
|
||||
while not self.cancelled:
|
||||
while not lounge_controller.linked():
|
||||
try:
|
||||
self.logger.debug("Refreshing auth")
|
||||
await lounge_controller.refresh_auth()
|
||||
except:
|
||||
await asyncio.sleep(10)
|
||||
while not (await self.is_available()) and not self.cancelled:
|
||||
await asyncio.sleep(10)
|
||||
try:
|
||||
|
||||
@@ -363,3 +363,9 @@ MigrationScreen {
|
||||
width: 1fr;
|
||||
content-align: center middle;
|
||||
}
|
||||
|
||||
/* Autoplay */
|
||||
#autoplay-container{
|
||||
padding: 1;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@@ -850,6 +850,32 @@ class ChannelWhitelistManager(Vertical):
|
||||
self.app.push_screen(AddChannel(self.config), callback=self.new_channel)
|
||||
|
||||
|
||||
class AutoPlayManager(Vertical):
|
||||
"""Manager for autoplay, allows enabling/disabling autoplay."""
|
||||
|
||||
def __init__(self, config, **kwargs) -> None:
|
||||
super().__init__(**kwargs)
|
||||
self.config = config
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Label("Autoplay", classes="title")
|
||||
yield Label(
|
||||
"This feature allows you to enable/disable autoplay",
|
||||
classes="subtitle",
|
||||
id="autoplay-subtitle",
|
||||
)
|
||||
with Horizontal(id="autoplay-container"):
|
||||
yield Checkbox(
|
||||
value=self.config.auto_play,
|
||||
id="autoplay-switch",
|
||||
label="Enable autoplay",
|
||||
)
|
||||
|
||||
@on(Checkbox.Changed, "#autoplay-switch")
|
||||
def changed_skip(self, event: Checkbox.Changed):
|
||||
self.config.auto_play = event.checkbox.value
|
||||
|
||||
|
||||
class ISponsorBlockTVSetupMainScreen(Screen):
|
||||
"""Making this a separate screen to avoid a bug: https://github.com/Textualize/textual/issues/3221"""
|
||||
|
||||
@@ -886,6 +912,9 @@ class ISponsorBlockTVSetupMainScreen(Screen):
|
||||
yield ApiKeyManager(
|
||||
config=self.config, id="api-key-manager", classes="container"
|
||||
)
|
||||
yield AutoPlayManager(
|
||||
config=self.config, id="autoplay-manager", classes="container"
|
||||
)
|
||||
|
||||
def on_mount(self) -> None:
|
||||
if self.check_for_old_config_entries():
|
||||
|
||||
@@ -30,9 +30,11 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
||||
self.callback = None
|
||||
self.logger = logger
|
||||
self.shorts_disconnected = False
|
||||
self.auto_play = True
|
||||
if config:
|
||||
self.mute_ads = config.mute_ads
|
||||
self.skip_ads = config.skip_ads
|
||||
self.auto_play = config.auto_play
|
||||
|
||||
# Ensures that we still are subscribed to the lounge
|
||||
async def _watchdog(self):
|
||||
@@ -146,6 +148,8 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
||||
data = args[0]
|
||||
if data["reason"] == "disconnectedByUserScreenInitiated": # Short playing?
|
||||
self.shorts_disconnected = True
|
||||
elif event_type == "onAutoplayModeChanged":
|
||||
create_task(self.set_auto_play_mode(self.auto_play))
|
||||
|
||||
super()._process_event(event_id, event_type, args)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user