General fixes to make deepsource happier

This commit is contained in:
dmunozv04
2023-11-05 17:56:51 +01:00
parent 138d8bd51c
commit 28b6ac3218
7 changed files with 62 additions and 54 deletions

View File

@@ -1,8 +1,7 @@
from cache import AsyncTTL, AsyncLRU from cache import AsyncLRU
from .conditional_ttl_cache import AsyncConditionalTTL from .conditional_ttl_cache import AsyncConditionalTTL
from . import constants, dial_client from . import constants, dial_client
from hashlib import sha256 from hashlib import sha256
from asyncio import create_task
from aiohttp import ClientSession from aiohttp import ClientSession
import html import html
@@ -39,17 +38,17 @@ class ApiHelper:
return return
for i in data["items"]: for i in data["items"]:
if (i["id"]["kind"] != "youtube#video"): if i["id"]["kind"] != "youtube#video":
continue continue
title_api = html.unescape(i["snippet"]["title"]) title_api = html.unescape(i["snippet"]["title"])
artist_api = html.unescape(i["snippet"]["channelTitle"]) artist_api = html.unescape(i["snippet"]["channelTitle"])
if title_api == title and artist_api == artist: if title_api == title and artist_api == artist:
return (i["id"]["videoId"], i["snippet"]["channelId"]) return i["id"]["videoId"], i["snippet"]["channelId"]
return return
@AsyncLRU(maxsize=100) @AsyncLRU(maxsize=100)
async def is_whitelisted(self, vid_id): async def is_whitelisted(self, vid_id):
if (self.apikey and self.channel_whitelist): if self.apikey and self.channel_whitelist:
channel_id = await self.__get_channel_id(vid_id) channel_id = await self.__get_channel_id(vid_id)
# check if channel id is in whitelist # check if channel id is in whitelist
for i in self.channel_whitelist: for i in self.channel_whitelist:
@@ -66,7 +65,7 @@ class ApiHelper:
if "error" in data: if "error" in data:
return return
data = data["items"][0] data = data["items"][0]
if (data["kind"] != "youtube#video"): if data["kind"] != "youtube#video":
return return
return data["snippet"]["channelId"] return data["snippet"]["channelId"]
@@ -114,9 +113,11 @@ class ApiHelper:
url = constants.SponsorBlock_api + "skipSegments/" + vid_id_hashed url = constants.SponsorBlock_api + "skipSegments/" + vid_id_hashed
async with self.web_session.get(url, headers=headers, params=params) as response: async with self.web_session.get(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()
print(f"Error getting segments for video {vid_id}, hashed as {vid_id_hashed}. Code: {response.status} - {response_text}") print(
f"Error getting segments for video {vid_id}, hashed as {vid_id_hashed}. "
f"Code: {response.status} - {response_text}")
return ([], True) return ([], True)
for i in response_json: for i in response_json:
if str(i["videoID"]) == str(vid_id): if str(i["videoID"]) == str(vid_id):
@@ -124,7 +125,8 @@ class ApiHelper:
break break
return self.process_segments(response_json) return self.process_segments(response_json)
def process_segments(self, response): @staticmethod
def process_segments(response):
segments = [] segments = []
ignore_ttl = True ignore_ttl = True
try: try:
@@ -153,7 +155,8 @@ class ApiHelper:
return (segments, ignore_ttl) return (segments, ignore_ttl)
async def mark_viewed_segments(self, UUID): async def mark_viewed_segments(self, UUID):
"""Marks the segments as viewed in the SponsorBlock API, if skip_count_tracking is enabled. Lets the contributor know that someone skipped the segment (thanks)""" """Marks the segments as viewed in the SponsorBlock API, if skip_count_tracking is enabled.
Lets the contributor know that someone skipped the segment (thanks)"""
if self.skip_count_tracking: if self.skip_count_tracking:
for i in UUID: for i in UUID:
url = constants.SponsorBlock_api + "viewedVideoSponsorTime/" url = constants.SponsorBlock_api + "viewedVideoSponsorTime/"

View File

@@ -1,10 +1,9 @@
import json
import asyncio import asyncio
import sys
import aiohttp import aiohttp
from . import api_helpers, ytlounge from . import api_helpers, ytlounge
async def pair_device(loop):
async def pair_device():
try: try:
lounge_controller = ytlounge.YtLoungeApi("iSponsorBlockTV") lounge_controller = ytlounge.YtLoungeApi("iSponsorBlockTV")
pairing_code = input("Enter pairing code (found in Settings - Link with TV code): ") pairing_code = input("Enter pairing code (found in Settings - Link with TV code): ")
@@ -24,6 +23,7 @@ async def pair_device(loop):
print(f"Failed to pair device: {e}") print(f"Failed to pair device: {e}")
return return
def main(config, debug: bool) -> None: def main(config, debug: bool) -> None:
print("Welcome to the iSponsorBlockTV cli setup wizard") print("Welcome to the iSponsorBlockTV cli setup wizard")
loop = asyncio.get_event_loop_policy().get_event_loop() loop = asyncio.get_event_loop_policy().get_event_loop()
@@ -31,12 +31,14 @@ def main(config, debug: bool) -> None:
loop.set_debug(True) loop.set_debug(True)
asyncio.set_event_loop(loop) asyncio.set_event_loop(loop)
if hasattr(config, "atvs"): 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") 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": 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"] del config["atvs"]
devices = config.devices devices = config.devices
while not input(f"Paired with {len(devices)} Device(s). Add more? (y/n) ") == "n": while not input(f"Paired with {len(devices)} Device(s). Add more? (y/n) ") == "n":
task = loop.create_task(pair_device(loop)) task = loop.create_task(pair_device())
loop.run_until_complete(task) loop.run_until_complete(task)
device = task.result() device = task.result()
if device: if device:
@@ -61,13 +63,15 @@ def main(config, debug: bool) -> None:
if skip_categories: if skip_categories:
if input("Skip categories already specified. Change them? (y/n) ") == "y": if input("Skip categories already specified. Change them? (y/n) ") == "y":
categories = input( categories = input(
"Enter skip categories (space or comma sepparated) Options: [sponsor selfpromo exclusive_access interaction poi_highlight intro outro preview filler music_offtopic]:\n" "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 = categories.replace(",", " ").split(" ")
skip_categories = [x for x in skip_categories if x != ''] # Remove empty strings skip_categories = [x for x in skip_categories if x != ''] # Remove empty strings
else: else:
categories = input( categories = input(
"Enter skip categories (space or comma sepparated) Options: [sponsor, selfpromo, exclusive_access, interaction, poi_highlight, intro, outro, preview, filler, music_offtopic:\n" "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 = categories.replace(",", " ").split(" ")
skip_categories = [x for x in skip_categories if x != ''] # Remove empty strings skip_categories = [x for x in skip_categories if x != ''] # Remove empty strings
@@ -75,16 +79,19 @@ def main(config, debug: bool) -> None:
channel_whitelist = config.channel_whitelist channel_whitelist = config.channel_whitelist
if input("Do you want to whitelist any channels from being ad-blocked? (y/n) ") == "y": if input("Do you want to whitelist any channels from being ad-blocked? (y/n) ") == "y":
if(not apikey): 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.") 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.")
web_session = aiohttp.ClientSession() web_session = aiohttp.ClientSession()
api_helper = api_helpers.ApiHelper(config, web_session)
while True: while True:
channel_info = {} channel_info = {}
channel = input("Enter a channel name or \"/exit\" to exit: ") channel = input("Enter a channel name or \"/exit\" to exit: ")
if channel == "/exit": if channel == "/exit":
break break
task = loop.create_task(api_helpers.search_channels(channel, apikey, web_session)) task = loop.create_task(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:
@@ -118,6 +125,7 @@ def main(config, debug: bool) -> None:
config.channel_whitelist = channel_whitelist 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" 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") print("Config finished")
config.save() config.save()

View File

@@ -1,24 +1,19 @@
"""Send out a M-SEARCH request and listening for responses.""" """Send out a M-SEARCH request and listening for responses."""
import asyncio import asyncio
import socket import socket
import aiohttp
import ssdp import ssdp
from ssdp import network from ssdp import network
import xmltodict import xmltodict
''' '''Redistribution and use of the DIAL DIscovery And Launch protocol specification (the “DIAL Specification”),
Redistribution and use of the DIAL DIscovery And Launch protocol specification (the “DIAL Specification”), with or without modification, with or without modification, are permitted provided that the following conditions are met: ● Redistributions of the
are permitted provided that the following conditions are met: DIAL Specification must retain the above copyright notice, this list of conditions and the following disclaimer. ●
Redistributions of the DIAL Specification must retain the above copyright notice, this list of conditions and the following Redistributions of implementations of the DIAL Specification in source code form must retain the above copyright
disclaimer. notice, this list of conditions and the following disclaimer. ● Redistributions of implementations of the DIAL
● Redistributions of implementations of the DIAL Specification in source code form must retain the above copyright notice, this Specification in binary form must include the above copyright notice. ● The DIAL mark, the NETFLIX mark and the names
list of conditions and the following disclaimer. of contributors to the DIAL Specification may not be used to endorse or promote specifications, software, products,
● Redistributions of implementations of the DIAL Specification in binary form must include the above copyright notice. or any other materials derived from the DIAL Specification without specific prior written permission. The DIAL mark
● The DIAL mark, the NETFLIX mark and the names of contributors to the DIAL Specification may not be used to endorse or is owned by Netflix and information on licensing the DIAL mark is available at www.dial-multiscreen.org.'''
promote specifications, software, products, or any other materials derived from the DIAL Specification without specific prior
written permission. The DIAL mark is owned by Netflix and information on licensing the DIAL mark is available at
www.dial-multiscreen.org.'''
''' '''
MIT License MIT License
@@ -44,6 +39,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.''' SOFTWARE.'''
'''Modified code from https://github.com/codingjoe/ssdp/blob/main/ssdp/__main__.py''' '''Modified code from https://github.com/codingjoe/ssdp/blob/main/ssdp/__main__.py'''
def get_ip(): def get_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(0) s.settimeout(0)
@@ -69,6 +65,7 @@ class Handler(ssdp.aio.SSDP):
def __call__(self): def __call__(self):
return self return self
def response_received(self, response: ssdp.messages.SSDPResponse, addr): def response_received(self, response: ssdp.messages.SSDPResponse, addr):
headers = response.headers headers = response.headers
headers = {k.lower(): v for k, v in headers} headers = {k.lower(): v for k, v in headers}

View File

@@ -43,7 +43,8 @@ class Config:
def validate(self): def validate(self):
if hasattr(self, "atvs"): if hasattr(self, "atvs"):
print( 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", "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",
) )
print("Exiting in 10 seconds...") print("Exiting in 10 seconds...")
time.sleep(10) time.sleep(10)

View File

@@ -3,8 +3,6 @@ import aiohttp
import time import time
import logging import logging
from . import api_helpers, ytlounge from . import api_helpers, ytlounge
from .constants import youtube_client_blacklist
import traceback
class DeviceListener: class DeviceListener:
@@ -115,7 +113,7 @@ class DeviceListener:
self.cancelled = True self.cancelled = True
try: try:
self.task.cancel() self.task.cancel()
except Exception as e: except Exception:
pass pass
@@ -141,7 +139,7 @@ def main(config, debug):
tasks.append(loop.create_task(device.refresh_auth_loop())) tasks.append(loop.create_task(device.refresh_auth_loop()))
try: try:
loop.run_forever() loop.run_forever()
except KeyboardInterrupt as e: except KeyboardInterrupt:
print("Keyboard interrupt detected, cancelling tasks and exiting...") print("Keyboard interrupt detected, cancelling tasks and exiting...")
loop.run_until_complete(finish(devices)) loop.run_until_complete(finish(devices))
finally: finally:

View File

@@ -4,10 +4,10 @@ import aiohttp
import pyytlounge import pyytlounge
from .constants import youtube_client_blacklist from .constants import youtube_client_blacklist
# Temporary imports # Temporary imports
from pyytlounge.api import api_base from pyytlounge.api import api_base
from pyytlounge.wrapper import NotLinkedException, desync from pyytlounge.wrapper import NotLinkedException, desync
create_task = asyncio.create_task create_task = asyncio.create_task
@@ -30,7 +30,7 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
await asyncio.sleep(35) # YouTube sends at least a message every 30 seconds (no-op or any other) await asyncio.sleep(35) # YouTube sends at least a message every 30 seconds (no-op or any other)
try: try:
self.subscribe_task.cancel() self.subscribe_task.cancel()
except Exception as e: except Exception:
pass pass
# Subscribe to the lounge and start the watchdog # Subscribe to the lounge and start the watchdog
@@ -54,7 +54,8 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
pass pass
finally: finally:
self.subscribe_task_watchdog = asyncio.create_task(self._watchdog()) self.subscribe_task_watchdog = asyncio.create_task(self._watchdog())
# A bunch of events useful to detect ads playing, and the next video before it starts playing (that way we can get the segments) # A bunch of events useful to detect ads playing, and the next video before it starts playing (that way we
# can get the segments)
if event_type == "onStateChange": if event_type == "onStateChange":
data = args[0] data = args[0]
# print(data) # print(data)