added config for piped

This commit is contained in:
Hellow2 2023-06-19 14:32:32 +02:00
parent 3cba909c05
commit 0fb8a25094
12 changed files with 274 additions and 127 deletions

View File

@ -67,9 +67,9 @@ if __name__ == "__main__":
) )
parser.add_argument( parser.add_argument(
"--invidious", "--frontend",
"-i", "-f",
help="Set a good and fast invidious instance from your homecountry, to reduce the latency.", help="Set a good and fast invidious/piped instance from your homecountry, to reduce the latency.",
action="store_true" action="store_true"
) )
@ -102,9 +102,9 @@ if __name__ == "__main__":
os.remove(music_kraken.shared.CONFIG_FILE) os.remove(music_kraken.shared.CONFIG_FILE)
music_kraken.read() music_kraken.read()
if arguments.invidious: if arguments.frontend:
from .cli.options import invidious from .cli.options.frontend import set_frontend
invidious() set_frontend()
exit() exit()
# getting the genre # getting the genre

View File

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

View File

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

View File

@ -0,0 +1,181 @@
from typing import Dict, List
import requests
from dataclasses import dataclass
from collections import defaultdict
from ...objects import Country
from ...utils import config, write
from ...connection import Connection
@dataclass
class Instance:
"""
Attributes which influence the quality of an instance:
- users
"""
name: str
uri: str
regions: List[Country]
users: int = 0
def __str__(self) -> str:
return f"{self.name} with {self.users} users."
class FrontendInstance:
SETTING_NAME = "placeholder"
def __init__(self) -> None:
self.region_instances: Dict[Country, List[Instance]] = defaultdict(list)
self.all_instances: List[Instance] = []
def add_instance(self, instance: Instance):
self.all_instances.append(instance)
for region in instance.regions:
self.region_instances[region].append(instance)
def fetch(self, silent: bool = False):
if not silent:
print(f"Downloading {type(self).__name__} instances...")
def set_instance(self, instance: Instance):
config.set_name_to_value(self.SETTING_NAME, instance.uri)
write()
def _choose_country(self) -> List[Instance]:
print("Input the country code, an example would be \"US\"")
print('\n'.join(f'{region.name} ({region.alpha_2})' for region in self.region_instances))
print()
available_instances = set(i.alpha_2 for i in self.region_instances)
chosen_region = ""
while chosen_region not in available_instances:
chosen_region = input("nearest country: ").strip().upper()
return self.region_instances[Country.by_alpha_2(chosen_region)]
def choose(self, silent: bool = False):
instances = self.all_instances if silent else self._choose_country()
instances.sort(key=lambda x: x.users, reverse=True)
if silent:
self.set_instance(instances[0])
return
# output the options
print("Choose your instance (input needs to be a digit):")
for i, instance in enumerate(instances):
print(f"{i}) {instance}")
print()
# ask for index
index = ""
while not index.isdigit() or int(index) >= len(instances):
index = input("> ").strip()
instance = instances[int(index)]
print()
print(f"Setting the instance to {instance}")
self.set_instance(instance)
class Invidious(FrontendInstance):
SETTING_NAME = "invidious_instance"
def __init__(self) -> None:
self.connection = Connection(host="https://api.invidious.io/")
self.endpoint = "https://api.invidious.io/instances.json"
super().__init__()
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"]
instance = Instance(
name=all_instance_data[0],
uri=instance_data["uri"],
regions=[Country.by_alpha_2(region)],
users=stats["usage"]["users"]["total"]
)
self.add_instance(instance)
def fetch(self, silent: bool):
print("jhdflashfö")
r = self.connection.get(self.endpoint)
if r is None:
return
for instance in r.json():
self._process_instance(all_instance_data=instance)
class Piped(FrontendInstance):
SETTING_NAME = "piped_instance"
def __init__(self) -> None:
self.connection = Connection(host="https://raw.githubusercontent.com")
super().__init__()
def process_instance(self, instance_data: str):
cells = instance_data.split(" | ")
instance = Instance(
name=cells[0].strip(),
uri=cells[1].strip(),
regions=[Country.by_emoji(flag) for flag in cells[2].split(", ")]
)
self.add_instance(instance)
def fetch(self, silent: bool = False):
r = self.connection.get("https://raw.githubusercontent.com/wiki/TeamPiped/Piped-Frontend/Instances.md")
if r is None:
return
process = False
for line in r.content.decode("utf-8").split("\n"):
line = line.strip()
if line != "" and process:
self.process_instance(line)
if line.startswith("---"):
process = True
class FrontendSelection:
def __init__(self):
self.invidious = Invidious()
self.piped = Piped()
def choose(self, silent: bool = False):
self.invidious.fetch(silent)
self.invidious.choose(silent)
self.piped.fetch(silent)
self.piped.choose(silent)
def set_frontend(silent: bool = False):
shell = FrontendSelection()
shell.choose(silent=silent)

View File

@ -1,101 +0,0 @@
from typing import Dict, List
import requests
from dataclasses import dataclass
from collections import defaultdict
from ....utils import config, write
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

@ -16,3 +16,5 @@ from .song import (
from .formatted_text import FormattedText from .formatted_text import FormattedText
from .collection import Collection from .collection import Collection
from .country import Country

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
from .encyclopaedia_metallum import EncyclopaediaMetallum from .encyclopaedia_metallum import EncyclopaediaMetallum
from .musify import Musify from .musify import Musify
from .youtube import YouTube from .youtube.youtube import YouTube
from .abstract import Page, INDEPENDENT_DB_OBJECTS from .abstract import Page, INDEPENDENT_DB_OBJECTS

View File

View File

@ -5,9 +5,9 @@ from enum import Enum
import sponsorblock import sponsorblock
from sponsorblock.errors import HTTPException, NotFoundException from sponsorblock.errors import HTTPException, NotFoundException
from ..objects import Source, DatabaseObject, Song, Target from ...objects import Source, DatabaseObject, Song, Target
from .abstract import Page from ..abstract import Page
from ..objects import ( from ...objects import (
Artist, Artist,
Source, Source,
SourcePages, SourcePages,
@ -18,9 +18,9 @@ from ..objects import (
FormattedText, FormattedText,
ID3Timestamp ID3Timestamp
) )
from ..connection import Connection from ...connection import Connection
from ..utils.support_classes import DownloadResult from ...utils.support_classes import DownloadResult
from ..utils.shared import YOUTUBE_LOGGER, INVIDIOUS_INSTANCE, BITRATE, ENABLE_SPONSOR_BLOCK from ...utils.shared import YOUTUBE_LOGGER, INVIDIOUS_INSTANCE, BITRATE, ENABLE_SPONSOR_BLOCK
""" """

View File

@ -67,18 +67,22 @@ class ConnectionSection(Section):
# INVIDIOUS INSTANCES LIST # INVIDIOUS INSTANCES LIST
self.INVIDIOUS_INSTANCE = UrlStringAttribute( self.INVIDIOUS_INSTANCE = UrlStringAttribute(
name="invidious_instance", name="invidious_instance",
description="This is a List, where you can define the invidious instances,\n" description="This is an attribute, 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="https://yt.artemislena.eu/" value="https://yt.artemislena.eu/"
) )
# INVIDIOUS PROXY
self.INVIDIOUS_PROXY_VIDEOS = BoolAttribute( self.PIPED_INSTANCE = UrlStringAttribute(
name="invidious_proxy_video", name="piped_instance",
value="false", description="This is an attribute, where you can define the pioed instances,\n"
description="Downloads the videos using the given instances." "the youtube downloader should use.\n"
"Here is a list of active ones: https://github.com/TeamPiped/Piped/wiki/Instances\n"
"Instances that use cloudflare or have source code changes could cause issues.\n"
"Hidden instances (.onion) will only work, when setting 'tor=true'.",
value="https://pipedapi.kavin.rocks"
) )
self.SPONSOR_BLOCK = BoolAttribute( self.SPONSOR_BLOCK = BoolAttribute(
@ -93,7 +97,7 @@ class ConnectionSection(Section):
self.CHUNK_SIZE, self.CHUNK_SIZE,
self.SHOW_DOWNLOAD_ERRORS_THRESHOLD, self.SHOW_DOWNLOAD_ERRORS_THRESHOLD,
self.INVIDIOUS_INSTANCE, self.INVIDIOUS_INSTANCE,
self.INVIDIOUS_PROXY_VIDEOS, self.PIPED_INSTANCE,
self.SPONSOR_BLOCK self.SPONSOR_BLOCK
] ]