added a module to easily config the invidious instance

This commit is contained in:
Hellow2 2023-06-13 11:45:02 +02:00
parent 6cd54724d2
commit f0fa05dc92
6 changed files with 127 additions and 10 deletions

View File

@ -65,6 +65,13 @@ if __name__ == "__main__":
help="Resets the config file to the default one.", help="Resets the config file to the default one.",
action="store_true" action="store_true"
) )
parser.add_argument(
"--invidious",
"-i",
help="Set a good and fast invidious instance from your homecountry, to reduce the latency.",
action="store_true"
)
arguments = parser.parse_args() arguments = parser.parse_args()
@ -94,6 +101,11 @@ if __name__ == "__main__":
if os.path.exists(music_kraken.shared.CONFIG_FILE): if os.path.exists(music_kraken.shared.CONFIG_FILE):
os.remove(music_kraken.shared.CONFIG_FILE) os.remove(music_kraken.shared.CONFIG_FILE)
music_kraken.read() music_kraken.read()
if arguments.invidious:
from .cli.options import invidious
invidious()
exit()
# getting the genre # getting the genre
genre: str = arguments.genre genre: str = arguments.genre

View File

@ -1 +1,2 @@
from .download.shell import Shell from .download.shell import Shell
from .options import invidious

View File

@ -0,0 +1,4 @@
from .invidious.shell import InvidiousShell
def invidious():
shell = InvidiousShell()

View File

@ -0,0 +1,102 @@
from typing import Dict, List
import requests
from dataclasses import dataclass
from collections import defaultdict
from ....utils import config, write
from ....utils import exception
INSTANCES_ENDPOINT = "https://api.invidious.io/instances.json"
@dataclass
class Instance:
"""
Attributes which influence the quality of an instance:
- users
"""
name: str
uri: str
region: str
users: int
def __str__(self) -> str:
return f"{self.name} with {self.users} users."
class InvidiousShell:
def __init__(self):
self.region_flags = dict()
self.region_instances: Dict[str, List[Instance]] = defaultdict(list)
self.download_instances()
self.region = self.get_country()
print()
self.choose_instance()
def process_instance(self, all_instance_data: dict):
instance_data = all_instance_data[1]
stats = instance_data["stats"]
if not instance_data["api"]:
return
if instance_data["type"] != "https":
return
region = instance_data["region"]
flag = instance_data["flag"]
self.region_flags[region] = flag
instance = Instance(
name=all_instance_data[0],
uri=instance_data["uri"],
region=region,
users=stats["usage"]["users"]["total"]
)
self.region_instances[region].append(instance)
def download_instances(self):
print("Download idonvidious instances...")
r = requests.get(INSTANCES_ENDPOINT)
for instance in r.json():
self.process_instance(all_instance_data=instance)
def get_country(self):
print("Input the country code, an example would be \"US\"")
print(f"({' | '.join(f'{region}-{flag}' for region, flag in self.region_flags.items())})")
chosen_region = ""
while chosen_region.upper() not in self.region_instances:
chosen_region = input("nearest country: ").strip().upper()
return chosen_region
def choose_instance(self):
instance_list = self.region_instances[self.region]
instance_list.sort(key=lambda x: x.users, reverse=True)
# output the options
print("Choose your instance (input needs to be a digit):")
for i, instance in enumerate(instance_list):
print(f"{i}) {instance}")
print()
# ask for index
index = ""
while not index.isdigit() or int(index) >= len(instance_list):
index = input("> ").strip()
instance = instance_list[int(index)]
print()
print(f"Setting the instance to {instance}")
config.set_name_to_value("invidious_instance", instance.uri)
write()

View File

@ -19,7 +19,7 @@ class UrlStringAttribute(StringAttribute):
def validate(self, value: str): def validate(self, value: str):
v = value.strip() v = value.strip()
url = re.match(URL_PATTERN, v) url = re.match(URL_PATTERN, v)
if v != url: if url is None:
raise SettingValueError( raise SettingValueError(
setting_name=self.name, setting_name=self.name,
setting_value=v, setting_value=v,
@ -64,18 +64,14 @@ class ConnectionSection(Section):
) )
# INVIDIOUS INSTANCES LIST # INVIDIOUS INSTANCES LIST
self.INVIDIOUS_INSTANCE = UrlListAttribute( self.INVIDIOUS_INSTANCE = UrlStringAttribute(
name="invidious_instances", name="invidious_instance",
description="This is a List, where you can define the invidious instances,\n" description="This is a List, where you can define the invidious instances,\n"
"the youtube downloader should use.\n" "the youtube downloader should use.\n"
"Here is a list of active ones: https://docs.invidious.io/instances/\n" "Here is a list of active ones: https://docs.invidious.io/instances/\n"
"Instances that use cloudflare or have source code changes could cause issues.\n" "Instances that use cloudflare or have source code changes could cause issues.\n"
"Hidden instances (.onion) will only work, when setting 'tor=true'.", "Hidden instances (.onion) will only work, when setting 'tor=true'.",
value=[ value="https://yt.artemislena.eu/"
"https://yt.artemislena.eu/",
"https://watch.thekitty.zone/",
"https://y.com.sb/"
]
) )
# INVIDIOUS PROXY # INVIDIOUS PROXY
self.INVIDIOUS_PROXY_VIDEOS = BoolAttribute( self.INVIDIOUS_PROXY_VIDEOS = BoolAttribute(
@ -88,7 +84,9 @@ class ConnectionSection(Section):
self.USE_TOR, self.USE_TOR,
self.TOR_PORT, self.TOR_PORT,
self.CHUNK_SIZE, self.CHUNK_SIZE,
self.SHOW_DOWNLOAD_ERRORS_THRESHOLD self.SHOW_DOWNLOAD_ERRORS_THRESHOLD,
self.INVIDIOUS_INSTANCE,
self.INVIDIOUS_PROXY_VIDEOS
] ]
super().__init__() super().__init__()