mirror of
https://github.com/dmunozv04/iSponsorBlockTV.git
synced 2025-12-06 11:56:45 +03:00
Merge pull request #290 from dmunozv04/line-length-100
Change max line length to 100
This commit is contained in:
@@ -6,3 +6,4 @@ enabled = true
|
|||||||
|
|
||||||
[analyzers.meta]
|
[analyzers.meta]
|
||||||
runtime_version = "3.x.x"
|
runtime_version = "3.x.x"
|
||||||
|
max_line_length = 100
|
||||||
|
|||||||
@@ -29,5 +29,5 @@ files = ["requirements.txt"]
|
|||||||
requires = ["hatchling", "hatch-requirements-txt"]
|
requires = ["hatchling", "hatch-requirements-txt"]
|
||||||
build-backend = "hatchling.build"
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
[tool.black]
|
[tool.ruff]
|
||||||
line-length = 88
|
line-length = 100
|
||||||
|
|||||||
@@ -101,20 +101,14 @@ class ApiHelper:
|
|||||||
if channel_data["items"][0]["statistics"]["hiddenSubscriberCount"]:
|
if channel_data["items"][0]["statistics"]["hiddenSubscriberCount"]:
|
||||||
sub_count = "Hidden"
|
sub_count = "Hidden"
|
||||||
else:
|
else:
|
||||||
sub_count = int(
|
sub_count = int(channel_data["items"][0]["statistics"]["subscriberCount"])
|
||||||
channel_data["items"][0]["statistics"]["subscriberCount"]
|
|
||||||
)
|
|
||||||
sub_count = format(sub_count, "_")
|
sub_count = format(sub_count, "_")
|
||||||
|
|
||||||
channels.append(
|
channels.append((i["snippet"]["channelId"], i["snippet"]["channelTitle"], sub_count))
|
||||||
(i["snippet"]["channelId"], i["snippet"]["channelTitle"], sub_count)
|
|
||||||
)
|
|
||||||
return channels
|
return channels
|
||||||
|
|
||||||
@list_to_tuple # Convert list to tuple so it can be used as a key in the cache
|
@list_to_tuple # Convert list to tuple so it can be used as a key in the cache
|
||||||
@AsyncConditionalTTL(
|
@AsyncConditionalTTL(time_to_live=300, maxsize=10) # 5 minutes for non-locked segments
|
||||||
time_to_live=300, maxsize=10
|
|
||||||
) # 5 minutes for non-locked segments
|
|
||||||
async def get_segments(self, vid_id):
|
async def get_segments(self, vid_id):
|
||||||
if await self.is_whitelisted(vid_id):
|
if await self.is_whitelisted(vid_id):
|
||||||
return (
|
return (
|
||||||
@@ -132,9 +126,7 @@ class ApiHelper:
|
|||||||
}
|
}
|
||||||
headers = {"Accept": "application/json"}
|
headers = {"Accept": "application/json"}
|
||||||
url = constants.SponsorBlock_api + "skipSegments/" + vid_id_hashed
|
url = constants.SponsorBlock_api + "skipSegments/" + vid_id_hashed
|
||||||
async with self.web_session.get(
|
async with self.web_session.get(url, headers=headers, params=params) as response:
|
||||||
url, headers=headers, params=params
|
|
||||||
) as response:
|
|
||||||
response_json = await response.json()
|
response_json = await response.json()
|
||||||
if response.status != 200:
|
if response.status != 200:
|
||||||
response_text = await response.text()
|
response_text = await response.text()
|
||||||
|
|||||||
@@ -33,9 +33,7 @@ class AsyncConditionalTTL:
|
|||||||
def __init__(self, time_to_live, maxsize):
|
def __init__(self, time_to_live, maxsize):
|
||||||
super().__init__(maxsize=maxsize)
|
super().__init__(maxsize=maxsize)
|
||||||
|
|
||||||
self.time_to_live = (
|
self.time_to_live = datetime.timedelta(seconds=time_to_live) if time_to_live else None
|
||||||
datetime.timedelta(seconds=time_to_live) if time_to_live else None
|
|
||||||
)
|
|
||||||
|
|
||||||
self.maxsize = maxsize
|
self.maxsize = maxsize
|
||||||
|
|
||||||
|
|||||||
@@ -6,15 +6,12 @@ from . import api_helpers, ytlounge
|
|||||||
|
|
||||||
# Constants for user input prompts
|
# Constants for user input prompts
|
||||||
ATVS_REMOVAL_PROMPT = (
|
ATVS_REMOVAL_PROMPT = (
|
||||||
"Do you want to remove the legacy 'atvs' entry (the app won't start"
|
"Do you want to remove the legacy 'atvs' entry (the app won't start with it present)? (y/N) "
|
||||||
" with it present)? (y/N) "
|
|
||||||
)
|
)
|
||||||
PAIRING_CODE_PROMPT = "Enter pairing code (found in Settings - Link with TV code): "
|
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) "
|
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) "
|
CHANGE_API_KEY_PROMPT = "API key already specified. Change it? (y/N) "
|
||||||
ADD_API_KEY_PROMPT = (
|
ADD_API_KEY_PROMPT = "API key only needed for the channel whitelist function. Add it? (y/N) "
|
||||||
"API key only needed for the channel whitelist function. Add it? (y/N) "
|
|
||||||
)
|
|
||||||
ENTER_API_KEY_PROMPT = "Enter your API key: "
|
ENTER_API_KEY_PROMPT = "Enter your API key: "
|
||||||
CHANGE_SKIP_CATEGORIES_PROMPT = "Skip categories already specified. Change them? (y/N) "
|
CHANGE_SKIP_CATEGORIES_PROMPT = "Skip categories already specified. Change them? (y/N) "
|
||||||
ENTER_SKIP_CATEGORIES_PROMPT = (
|
ENTER_SKIP_CATEGORIES_PROMPT = (
|
||||||
@@ -22,9 +19,7 @@ ENTER_SKIP_CATEGORIES_PROMPT = (
|
|||||||
" selfpromo, exclusive_access, interaction, poi_highlight, intro, outro,"
|
" selfpromo, exclusive_access, interaction, poi_highlight, intro, outro,"
|
||||||
" preview, filler, music_offtopic]:\n"
|
" preview, filler, music_offtopic]:\n"
|
||||||
)
|
)
|
||||||
WHITELIST_CHANNELS_PROMPT = (
|
WHITELIST_CHANNELS_PROMPT = "Do you want to whitelist any channels from being ad-blocked? (y/N) "
|
||||||
"Do you want to whitelist any channels from being ad-blocked? (y/N) "
|
|
||||||
)
|
|
||||||
SEARCH_CHANNEL_PROMPT = 'Enter a channel name or "/exit" to exit: '
|
SEARCH_CHANNEL_PROMPT = 'Enter a channel name or "/exit" to exit: '
|
||||||
SELECT_CHANNEL_PROMPT = "Select one option of the above [0-6]: "
|
SELECT_CHANNEL_PROMPT = "Select one option of the above [0-6]: "
|
||||||
ENTER_CHANNEL_ID_PROMPT = "Enter a channel ID: "
|
ENTER_CHANNEL_ID_PROMPT = "Enter a channel ID: "
|
||||||
@@ -121,15 +116,11 @@ def main(config, debug: bool) -> None:
|
|||||||
if choice == "y":
|
if choice == "y":
|
||||||
categories = input(ENTER_SKIP_CATEGORIES_PROMPT)
|
categories = input(ENTER_SKIP_CATEGORIES_PROMPT)
|
||||||
skip_categories = categories.replace(",", " ").split(" ")
|
skip_categories = categories.replace(",", " ").split(" ")
|
||||||
skip_categories = [
|
skip_categories = [x for x in skip_categories if x != ""] # Remove empty strings
|
||||||
x for x in skip_categories if x != ""
|
|
||||||
] # Remove empty strings
|
|
||||||
else:
|
else:
|
||||||
categories = input(ENTER_SKIP_CATEGORIES_PROMPT)
|
categories = input(ENTER_SKIP_CATEGORIES_PROMPT)
|
||||||
skip_categories = categories.replace(",", " ").split(" ")
|
skip_categories = categories.replace(",", " ").split(" ")
|
||||||
skip_categories = [
|
skip_categories = [x for x in skip_categories if x != ""] # Remove empty strings
|
||||||
x for x in skip_categories if x != ""
|
|
||||||
] # Remove empty strings
|
|
||||||
config.skip_categories = skip_categories
|
config.skip_categories = skip_categories
|
||||||
|
|
||||||
channel_whitelist = config.channel_whitelist
|
channel_whitelist = config.channel_whitelist
|
||||||
@@ -148,9 +139,7 @@ def main(config, debug: bool) -> None:
|
|||||||
if channel == "/exit":
|
if channel == "/exit":
|
||||||
break
|
break
|
||||||
|
|
||||||
task = loop.create_task(
|
task = loop.create_task(api_helper.search_channels(channel, apikey, web_session))
|
||||||
api_helper.search_channels(channel, apikey, web_session)
|
|
||||||
)
|
|
||||||
loop.run_until_complete(task)
|
loop.run_until_complete(task)
|
||||||
results = task.result()
|
results = task.result()
|
||||||
if len(results) == 0:
|
if len(results) == 0:
|
||||||
|
|||||||
@@ -83,9 +83,7 @@ class Handler(ssdp.aio.SSDP):
|
|||||||
self.devices.append(headers["location"])
|
self.devices.append(headers["location"])
|
||||||
|
|
||||||
def request_received(self, request: ssdp.messages.SSDPRequest, addr):
|
def request_received(self, request: ssdp.messages.SSDPRequest, addr):
|
||||||
raise NotImplementedError(
|
raise NotImplementedError("Request received is not implemented, this is a client")
|
||||||
"Request received is not implemented, this is a client"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def find_youtube_app(web_session, url_location):
|
async def find_youtube_app(web_session, url_location):
|
||||||
@@ -121,9 +119,7 @@ async def discover(web_session):
|
|||||||
family, _ = network.get_best_family(bind, network.PORT)
|
family, _ = network.get_best_family(bind, network.PORT)
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
ip_address = get_ip()
|
ip_address = get_ip()
|
||||||
connect = loop.create_datagram_endpoint(
|
connect = loop.create_datagram_endpoint(handler, family=family, local_addr=(ip_address, None))
|
||||||
handler, family=family, local_addr=(ip_address, None)
|
|
||||||
)
|
|
||||||
transport, _ = await connect
|
transport, _ = await connect
|
||||||
|
|
||||||
target = network.MULTICAST_ADDRESS_IPV4, network.PORT
|
target = network.MULTICAST_ADDRESS_IPV4, network.PORT
|
||||||
|
|||||||
@@ -65,9 +65,7 @@ class Config:
|
|||||||
sys.exit()
|
sys.exit()
|
||||||
self.devices = [Device(i) for i in self.devices]
|
self.devices = [Device(i) for i in self.devices]
|
||||||
if not self.apikey and self.channel_whitelist:
|
if not self.apikey and self.channel_whitelist:
|
||||||
raise ValueError(
|
raise ValueError("No youtube API key found and channel whitelist is not empty")
|
||||||
"No youtube API key found and channel whitelist is not empty"
|
|
||||||
)
|
|
||||||
if not self.skip_categories:
|
if not self.skip_categories:
|
||||||
self.skip_categories = ["sponsor"]
|
self.skip_categories = ["sponsor"]
|
||||||
print("No categories found, using default: sponsor")
|
print("No categories found, using default: sponsor")
|
||||||
@@ -93,14 +91,8 @@ class Config:
|
|||||||
f"{github_wiki_base_url}/Installation#Docker"
|
f"{github_wiki_base_url}/Installation#Docker"
|
||||||
)
|
)
|
||||||
print(
|
print(
|
||||||
(
|
("This image has recently been updated to v2, and requires changes."),
|
||||||
"This image has recently been updated to v2, and requires"
|
("Please read this for more information on how to upgrade to V2:"),
|
||||||
" changes."
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"Please read this for more information on how to upgrade"
|
|
||||||
" to V2:"
|
|
||||||
),
|
|
||||||
f"{github_wiki_base_url}/Migrate-from-V1-to-V2",
|
f"{github_wiki_base_url}/Migrate-from-V1-to-V2",
|
||||||
)
|
)
|
||||||
print("Exiting in 10 seconds...")
|
print("Exiting in 10 seconds...")
|
||||||
@@ -134,15 +126,12 @@ class Config:
|
|||||||
@click.option(
|
@click.option(
|
||||||
"--data",
|
"--data",
|
||||||
"-d",
|
"-d",
|
||||||
default=lambda: os.getenv("iSPBTV_data_dir")
|
default=lambda: os.getenv("iSPBTV_data_dir") or user_data_dir("iSponsorBlockTV", "dmunozv04"),
|
||||||
or user_data_dir("iSponsorBlockTV", "dmunozv04"),
|
|
||||||
help="data directory",
|
help="data directory",
|
||||||
)
|
)
|
||||||
@click.option("--debug", is_flag=True, help="debug mode")
|
@click.option("--debug", is_flag=True, help="debug mode")
|
||||||
# legacy commands as arguments
|
# legacy commands as arguments
|
||||||
@click.option(
|
@click.option("--setup", is_flag=True, help="Setup the program graphically", hidden=True)
|
||||||
"--setup", is_flag=True, help="Setup the program graphically", hidden=True
|
|
||||||
)
|
|
||||||
@click.option(
|
@click.option(
|
||||||
"--setup-cli",
|
"--setup-cli",
|
||||||
is_flag=True,
|
is_flag=True,
|
||||||
@@ -159,9 +148,7 @@ def cli(ctx, data, debug, setup, setup_cli):
|
|||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
ctx.obj["logger"] = logger
|
ctx.obj["logger"] = logger
|
||||||
sh = logging.StreamHandler()
|
sh = logging.StreamHandler()
|
||||||
sh.setFormatter(
|
sh.setFormatter(logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
|
||||||
logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
|
||||||
)
|
|
||||||
logger.addHandler(sh)
|
logger.addHandler(sh)
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
@@ -211,9 +198,7 @@ pyapp_group.add_command(
|
|||||||
click.RichCommand("update", help="Update the package to the latest version")
|
click.RichCommand("update", help="Update the package to the latest version")
|
||||||
)
|
)
|
||||||
pyapp_group.add_command(
|
pyapp_group.add_command(
|
||||||
click.Command(
|
click.Command("remove", help="Remove the package, wiping the installation but not the data")
|
||||||
"remove", help="Remove the package, wiping the installation but not the data"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
pyapp_group.add_command(
|
pyapp_group.add_command(
|
||||||
click.RichCommand(
|
click.RichCommand(
|
||||||
|
|||||||
@@ -87,9 +87,7 @@ class DeviceListener:
|
|||||||
if state.videoId:
|
if state.videoId:
|
||||||
segments = await self.api_helper.get_segments(state.videoId)
|
segments = await self.api_helper.get_segments(state.videoId)
|
||||||
if state.state.value == 1: # Playing
|
if state.state.value == 1: # Playing
|
||||||
self.logger.info(
|
self.logger.info("Playing video %s with %d segments", state.videoId, len(segments))
|
||||||
"Playing video %s with %d segments", state.videoId, len(segments)
|
|
||||||
)
|
|
||||||
if segments: # If there are segments
|
if segments: # If there are segments
|
||||||
await self.time_to_segment(segments, state.currentTime, time_start)
|
await self.time_to_segment(segments, state.currentTime, time_start)
|
||||||
|
|
||||||
@@ -107,9 +105,7 @@ class DeviceListener:
|
|||||||
|
|
||||||
if is_within_start_range or is_beyond_current_position:
|
if is_within_start_range or is_beyond_current_position:
|
||||||
next_segment = segment
|
next_segment = segment
|
||||||
start_next_segment = (
|
start_next_segment = position if is_within_start_range else segment_start
|
||||||
position if is_within_start_range else segment_start
|
|
||||||
)
|
|
||||||
break
|
break
|
||||||
if start_next_segment:
|
if start_next_segment:
|
||||||
time_to_next = (
|
time_to_next = (
|
||||||
@@ -148,9 +144,7 @@ class DeviceListener:
|
|||||||
|
|
||||||
|
|
||||||
async def finish(devices, web_session, tcp_connector):
|
async def finish(devices, web_session, tcp_connector):
|
||||||
await asyncio.gather(
|
await asyncio.gather(*(device.cancel() for device in devices), return_exceptions=True)
|
||||||
*(device.cancel() for device in devices), return_exceptions=True
|
|
||||||
)
|
|
||||||
await web_session.close()
|
await web_session.close()
|
||||||
await tcp_connector.close()
|
await tcp_connector.close()
|
||||||
|
|
||||||
|
|||||||
@@ -122,9 +122,7 @@ class Channel(Element):
|
|||||||
if "name" in self.element_data:
|
if "name" in self.element_data:
|
||||||
self.element_name = self.element_data["name"]
|
self.element_name = self.element_data["name"]
|
||||||
else:
|
else:
|
||||||
self.element_name = (
|
self.element_name = f"Unnamed channel with id {self.element_data['channel_id']}"
|
||||||
f"Unnamed channel with id {self.element_data['channel_id']}"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ChannelRadio(RadioButton):
|
class ChannelRadio(RadioButton):
|
||||||
@@ -204,9 +202,7 @@ class ExitScreen(ModalWithClickExit):
|
|||||||
classes="button-100",
|
classes="button-100",
|
||||||
),
|
),
|
||||||
Button("Save", variant="success", id="exit-save", classes="button-100"),
|
Button("Save", variant="success", id="exit-save", classes="button-100"),
|
||||||
Button(
|
Button("Don't save", variant="error", id="exit-no-save", classes="button-100"),
|
||||||
"Don't save", variant="error", id="exit-no-save", classes="button-100"
|
|
||||||
),
|
|
||||||
Button("Cancel", variant="primary", id="exit-cancel", classes="button-100"),
|
Button("Cancel", variant="primary", id="exit-cancel", classes="button-100"),
|
||||||
id="dialog-exit",
|
id="dialog-exit",
|
||||||
)
|
)
|
||||||
@@ -255,19 +251,13 @@ class AddDevice(ModalWithClickExit):
|
|||||||
id="add-device-dial-button",
|
id="add-device-dial-button",
|
||||||
classes="button-switcher",
|
classes="button-switcher",
|
||||||
)
|
)
|
||||||
with ContentSwitcher(
|
with ContentSwitcher(id="add-device-switcher", initial="add-device-pin-container"):
|
||||||
id="add-device-switcher", initial="add-device-pin-container"
|
|
||||||
):
|
|
||||||
with Container(id="add-device-pin-container"):
|
with Container(id="add-device-pin-container"):
|
||||||
yield Input(
|
yield Input(
|
||||||
placeholder=(
|
placeholder=("Pairing Code (found in Settings - Link with TV code)"),
|
||||||
"Pairing Code (found in Settings - Link with TV code)"
|
|
||||||
),
|
|
||||||
id="pairing-code-input",
|
id="pairing-code-input",
|
||||||
validators=[
|
validators=[
|
||||||
Function(
|
Function(_validate_pairing_code, "Invalid pairing code format")
|
||||||
_validate_pairing_code, "Invalid pairing code format"
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
yield Input(
|
yield Input(
|
||||||
@@ -332,9 +322,7 @@ class AddDevice(ModalWithClickExit):
|
|||||||
|
|
||||||
@on(Input.Changed, "#pairing-code-input")
|
@on(Input.Changed, "#pairing-code-input")
|
||||||
def changed_pairing_code(self, event: Input.Changed):
|
def changed_pairing_code(self, event: Input.Changed):
|
||||||
self.query_one(
|
self.query_one("#add-device-pin-add-button").disabled = not event.validation_result.is_valid
|
||||||
"#add-device-pin-add-button"
|
|
||||||
).disabled = not event.validation_result.is_valid
|
|
||||||
|
|
||||||
@on(Input.Submitted, "#pairing-code-input")
|
@on(Input.Submitted, "#pairing-code-input")
|
||||||
@on(Button.Pressed, "#add-device-pin-add-button")
|
@on(Button.Pressed, "#add-device-pin-add-button")
|
||||||
@@ -382,9 +370,7 @@ class AddDevice(ModalWithClickExit):
|
|||||||
|
|
||||||
@on(SelectionList.SelectedChanged, "#dial-devices-list")
|
@on(SelectionList.SelectedChanged, "#dial-devices-list")
|
||||||
def changed_device_list(self, event: SelectionList.SelectedChanged):
|
def changed_device_list(self, event: SelectionList.SelectedChanged):
|
||||||
self.query_one(
|
self.query_one("#add-device-dial-add-button").disabled = not event.selection_list.selected
|
||||||
"#add-device-dial-add-button"
|
|
||||||
).disabled = not event.selection_list.selected
|
|
||||||
|
|
||||||
|
|
||||||
class AddChannel(ModalWithClickExit):
|
class AddChannel(ModalWithClickExit):
|
||||||
@@ -422,9 +408,7 @@ class AddChannel(ModalWithClickExit):
|
|||||||
classes="button-switcher",
|
classes="button-switcher",
|
||||||
)
|
)
|
||||||
yield Label(id="add-channel-info", classes="subtitle")
|
yield Label(id="add-channel-info", classes="subtitle")
|
||||||
with ContentSwitcher(
|
with ContentSwitcher(id="add-channel-switcher", initial="add-channel-search-container"):
|
||||||
id="add-channel-switcher", initial="add-channel-search-container"
|
|
||||||
):
|
|
||||||
with Vertical(id="add-channel-search-container"):
|
with Vertical(id="add-channel-search-container"):
|
||||||
if self.config.apikey:
|
if self.config.apikey:
|
||||||
with Grid(id="add-channel-search-inputs"):
|
with Grid(id="add-channel-search-inputs"):
|
||||||
@@ -432,9 +416,7 @@ class AddChannel(ModalWithClickExit):
|
|||||||
placeholder="Enter channel name",
|
placeholder="Enter channel name",
|
||||||
id="channel-name-input-search",
|
id="channel-name-input-search",
|
||||||
)
|
)
|
||||||
yield Button(
|
yield Button("Search", id="search-channel-button", variant="success")
|
||||||
"Search", id="search-channel-button", variant="success"
|
|
||||||
)
|
|
||||||
yield RadioSet(
|
yield RadioSet(
|
||||||
RadioButton(label="Search to see results", disabled=True),
|
RadioButton(label="Search to see results", disabled=True),
|
||||||
id="channel-search-results",
|
id="channel-search-results",
|
||||||
@@ -457,15 +439,12 @@ class AddChannel(ModalWithClickExit):
|
|||||||
)
|
)
|
||||||
with Vertical(id="add-channel-id-container"):
|
with Vertical(id="add-channel-id-container"):
|
||||||
yield Input(
|
yield Input(
|
||||||
placeholder=(
|
placeholder=("Enter channel ID (example: UCuAXFkgsw1L7xaCfnd5JJOw)"),
|
||||||
"Enter channel ID (example: UCuAXFkgsw1L7xaCfnd5JJOw)"
|
|
||||||
),
|
|
||||||
id="channel-id-input",
|
id="channel-id-input",
|
||||||
)
|
)
|
||||||
yield Input(
|
yield Input(
|
||||||
placeholder=(
|
placeholder=(
|
||||||
"Enter channel name (only used to display in the config"
|
"Enter channel name (only used to display in the config file)"
|
||||||
" file)"
|
|
||||||
),
|
),
|
||||||
id="channel-name-input-id",
|
id="channel-name-input-id",
|
||||||
)
|
)
|
||||||
@@ -491,9 +470,7 @@ class AddChannel(ModalWithClickExit):
|
|||||||
async def handle_search_channel(self) -> None:
|
async def handle_search_channel(self) -> None:
|
||||||
channel_name = self.query_one("#channel-name-input-search").value
|
channel_name = self.query_one("#channel-name-input-search").value
|
||||||
if not channel_name:
|
if not channel_name:
|
||||||
self.query_one("#add-channel-info").update(
|
self.query_one("#add-channel-info").update("[#ff0000]Please enter a channel name")
|
||||||
"[#ff0000]Please enter a channel name"
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
self.query_one("#search-channel-button").disabled = True
|
self.query_one("#search-channel-button").disabled = True
|
||||||
self.query_one("#add-channel-info").update("Searching...")
|
self.query_one("#add-channel-info").update("Searching...")
|
||||||
@@ -502,9 +479,7 @@ class AddChannel(ModalWithClickExit):
|
|||||||
try:
|
try:
|
||||||
channels_list = await self.api_helper.search_channels(channel_name)
|
channels_list = await self.api_helper.search_channels(channel_name)
|
||||||
except BaseException:
|
except BaseException:
|
||||||
self.query_one("#add-channel-info").update(
|
self.query_one("#add-channel-info").update("[#ff0000]Failed to search for channel")
|
||||||
"[#ff0000]Failed to search for channel"
|
|
||||||
)
|
|
||||||
self.query_one("#search-channel-button").disabled = False
|
self.query_one("#search-channel-button").disabled = False
|
||||||
return
|
return
|
||||||
for i in channels_list:
|
for i in channels_list:
|
||||||
@@ -517,9 +492,7 @@ class AddChannel(ModalWithClickExit):
|
|||||||
def handle_add_channel_search(self) -> None:
|
def handle_add_channel_search(self) -> None:
|
||||||
channel = self.query_one("#channel-search-results").pressed_button.channel_data
|
channel = self.query_one("#channel-search-results").pressed_button.channel_data
|
||||||
if not channel:
|
if not channel:
|
||||||
self.query_one("#add-channel-info").update(
|
self.query_one("#add-channel-info").update("[#ff0000]Please select a channel")
|
||||||
"[#ff0000]Please select a channel"
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
self.query_one("#add-channel-info").update("Adding...")
|
self.query_one("#add-channel-info").update("Adding...")
|
||||||
self.dismiss(channel)
|
self.dismiss(channel)
|
||||||
@@ -531,9 +504,7 @@ class AddChannel(ModalWithClickExit):
|
|||||||
channel_id = self.query_one("#channel-id-input").value
|
channel_id = self.query_one("#channel-id-input").value
|
||||||
channel_name = self.query_one("#channel-name-input-id").value
|
channel_name = self.query_one("#channel-name-input-id").value
|
||||||
if not channel_id:
|
if not channel_id:
|
||||||
self.query_one("#add-channel-info").update(
|
self.query_one("#add-channel-info").update("[#ff0000]Please enter a channel ID")
|
||||||
"[#ff0000]Please enter a channel ID"
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
if not channel_name:
|
if not channel_name:
|
||||||
channel_name = channel_id
|
channel_name = channel_id
|
||||||
@@ -624,9 +595,7 @@ class DevicesManager(Vertical):
|
|||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Label("Devices", classes="title")
|
yield Label("Devices", classes="title")
|
||||||
with Horizontal(id="add-device-button-container"):
|
with Horizontal(id="add-device-button-container"):
|
||||||
yield Button(
|
yield Button("Add Device", id="add-device", classes="button-100 button-small")
|
||||||
"Add Device", id="add-device", classes="button-100 button-small"
|
|
||||||
)
|
|
||||||
for device in self.devices:
|
for device in self.devices:
|
||||||
yield Device(device, tooltip="Click to edit")
|
yield Device(device, tooltip="Click to edit")
|
||||||
|
|
||||||
@@ -821,16 +790,14 @@ class ChannelWhitelistManager(Vertical):
|
|||||||
id="warning-no-key",
|
id="warning-no-key",
|
||||||
)
|
)
|
||||||
with Horizontal(id="add-channel-button-container"):
|
with Horizontal(id="add-channel-button-container"):
|
||||||
yield Button(
|
yield Button("Add Channel", id="add-channel", classes="button-100 button-small")
|
||||||
"Add Channel", id="add-channel", classes="button-100 button-small"
|
|
||||||
)
|
|
||||||
for channel in self.config.channel_whitelist:
|
for channel in self.config.channel_whitelist:
|
||||||
yield Channel(channel)
|
yield Channel(channel)
|
||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
self.app.query_one("#warning-no-key").display = (
|
self.app.query_one("#warning-no-key").display = (not self.config.apikey) and bool(
|
||||||
not self.config.apikey
|
self.config.channel_whitelist
|
||||||
) and bool(self.config.channel_whitelist)
|
)
|
||||||
|
|
||||||
def new_channel(self, channel: tuple) -> None:
|
def new_channel(self, channel: tuple) -> None:
|
||||||
if channel:
|
if channel:
|
||||||
@@ -842,18 +809,18 @@ class ChannelWhitelistManager(Vertical):
|
|||||||
channel_widget = Channel(channel_dict)
|
channel_widget = Channel(channel_dict)
|
||||||
self.mount(channel_widget)
|
self.mount(channel_widget)
|
||||||
channel_widget.focus(scroll_visible=True)
|
channel_widget.focus(scroll_visible=True)
|
||||||
self.app.query_one("#warning-no-key").display = (
|
self.app.query_one("#warning-no-key").display = (not self.config.apikey) and bool(
|
||||||
not self.config.apikey
|
self.config.channel_whitelist
|
||||||
) and bool(self.config.channel_whitelist)
|
)
|
||||||
|
|
||||||
@on(Button.Pressed, "#element-remove")
|
@on(Button.Pressed, "#element-remove")
|
||||||
def remove_channel(self, event: Button.Pressed):
|
def remove_channel(self, event: Button.Pressed):
|
||||||
channel_to_remove: Element = event.button.parent
|
channel_to_remove: Element = event.button.parent
|
||||||
self.config.channel_whitelist.remove(channel_to_remove.element_data)
|
self.config.channel_whitelist.remove(channel_to_remove.element_data)
|
||||||
channel_to_remove.remove()
|
channel_to_remove.remove()
|
||||||
self.app.query_one("#warning-no-key").display = (
|
self.app.query_one("#warning-no-key").display = (not self.config.apikey) and bool(
|
||||||
not self.config.apikey
|
self.config.channel_whitelist
|
||||||
) and bool(self.config.channel_whitelist)
|
)
|
||||||
|
|
||||||
@on(Button.Pressed, "#add-channel")
|
@on(Button.Pressed, "#add-channel")
|
||||||
def add_channel(self, event: Button.Pressed):
|
def add_channel(self, event: Button.Pressed):
|
||||||
@@ -902,9 +869,7 @@ class ISponsorBlockTVSetupMainScreen(Screen):
|
|||||||
yield Header()
|
yield Header()
|
||||||
yield Footer()
|
yield Footer()
|
||||||
with ScrollableContainer(id="setup-wizard"):
|
with ScrollableContainer(id="setup-wizard"):
|
||||||
yield DevicesManager(
|
yield DevicesManager(config=self.config, id="devices-manager", classes="container")
|
||||||
config=self.config, id="devices-manager", classes="container"
|
|
||||||
)
|
|
||||||
yield SkipCategoriesManager(
|
yield SkipCategoriesManager(
|
||||||
config=self.config, id="skip-categories-manager", classes="container"
|
config=self.config, id="skip-categories-manager", classes="container"
|
||||||
)
|
)
|
||||||
@@ -917,12 +882,8 @@ class ISponsorBlockTVSetupMainScreen(Screen):
|
|||||||
yield ChannelWhitelistManager(
|
yield ChannelWhitelistManager(
|
||||||
config=self.config, id="channel-whitelist-manager", classes="container"
|
config=self.config, id="channel-whitelist-manager", classes="container"
|
||||||
)
|
)
|
||||||
yield ApiKeyManager(
|
yield ApiKeyManager(config=self.config, id="api-key-manager", classes="container")
|
||||||
config=self.config, id="api-key-manager", classes="container"
|
yield AutoPlayManager(config=self.config, id="autoplay-manager", classes="container")
|
||||||
)
|
|
||||||
yield AutoPlayManager(
|
|
||||||
config=self.config, id="autoplay-manager", classes="container"
|
|
||||||
)
|
|
||||||
|
|
||||||
def on_mount(self) -> None:
|
def on_mount(self) -> None:
|
||||||
if self.check_for_old_config_entries():
|
if self.check_for_old_config_entries():
|
||||||
|
|||||||
@@ -18,9 +18,7 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
|||||||
api_helper=None,
|
api_helper=None,
|
||||||
logger=None,
|
logger=None,
|
||||||
):
|
):
|
||||||
super().__init__(
|
super().__init__(config.join_name if config else "iSponsorBlockTV", logger=logger)
|
||||||
config.join_name if config else "iSponsorBlockTV", logger=logger
|
|
||||||
)
|
|
||||||
self.auth.screen_id = screen_id
|
self.auth.screen_id = screen_id
|
||||||
self.auth.lounge_id_token = None
|
self.auth.lounge_id_token = None
|
||||||
self.api_helper = api_helper
|
self.api_helper = api_helper
|
||||||
@@ -96,9 +94,7 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
|||||||
self.logger.info("Ad can be skipped, skipping")
|
self.logger.info("Ad can be skipped, skipping")
|
||||||
create_task(self.skip_ad())
|
create_task(self.skip_ad())
|
||||||
create_task(self.mute(False, override=True))
|
create_task(self.mute(False, override=True))
|
||||||
elif (
|
elif self.mute_ads: # Seen multiple other adStates, assuming they are all ads
|
||||||
self.mute_ads
|
|
||||||
): # Seen multiple other adStates, assuming they are all ads
|
|
||||||
self.logger.info("Ad has started, muting")
|
self.logger.info("Ad has started, muting")
|
||||||
create_task(self.mute(True, override=True))
|
create_task(self.mute(True, override=True))
|
||||||
# Manages volume, useful since YouTube wants to know the volume
|
# Manages volume, useful since YouTube wants to know the volume
|
||||||
@@ -107,9 +103,7 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
|||||||
self.volume_state = args[0]
|
self.volume_state = args[0]
|
||||||
# Gets segments for the next video before it starts playing
|
# Gets segments for the next video before it starts playing
|
||||||
elif event_type == "autoplayUpNext":
|
elif event_type == "autoplayUpNext":
|
||||||
if len(args) > 0 and (
|
if len(args) > 0 and (vid_id := args[0]["videoId"]): # if video id is not empty
|
||||||
vid_id := args[0]["videoId"]
|
|
||||||
): # if video id is not empty
|
|
||||||
self.logger.info(f"Getting segments for next video: {vid_id}")
|
self.logger.info(f"Getting segments for next video: {vid_id}")
|
||||||
create_task(self.api_helper.get_segments(vid_id))
|
create_task(self.api_helper.get_segments(vid_id))
|
||||||
|
|
||||||
@@ -126,9 +120,7 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
|||||||
self.logger.info("Ad can be skipped, skipping")
|
self.logger.info("Ad can be skipped, skipping")
|
||||||
create_task(self.skip_ad())
|
create_task(self.skip_ad())
|
||||||
create_task(self.mute(False, override=True))
|
create_task(self.mute(False, override=True))
|
||||||
elif (
|
elif self.mute_ads: # Seen multiple other adStates, assuming they are all ads
|
||||||
self.mute_ads
|
|
||||||
): # Seen multiple other adStates, assuming they are all ads
|
|
||||||
self.logger.info("Ad has started, muting")
|
self.logger.info("Ad has started, muting")
|
||||||
create_task(self.mute(True, override=True))
|
create_task(self.mute(True, override=True))
|
||||||
|
|
||||||
@@ -151,9 +143,7 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
|||||||
elif event_type == "loungeScreenDisconnected":
|
elif event_type == "loungeScreenDisconnected":
|
||||||
if args: # Sometimes it's empty
|
if args: # Sometimes it's empty
|
||||||
data = args[0]
|
data = args[0]
|
||||||
if (
|
if data["reason"] == "disconnectedByUserScreenInitiated": # Short playing?
|
||||||
data["reason"] == "disconnectedByUserScreenInitiated"
|
|
||||||
): # Short playing?
|
|
||||||
self.shorts_disconnected = True
|
self.shorts_disconnected = True
|
||||||
elif event_type == "onAutoplayModeChanged":
|
elif event_type == "onAutoplayModeChanged":
|
||||||
create_task(self.set_auto_play_mode(self.auto_play))
|
create_task(self.set_auto_play_mode(self.auto_play))
|
||||||
|
|||||||
Reference in New Issue
Block a user