From 292c9d18c72a869a2a463219369e05c50a9ea232 Mon Sep 17 00:00:00 2001 From: Crussader <75786691+Crussader@users.noreply.github.com> Date: Tue, 26 Oct 2021 21:00:54 +0400 Subject: [PATCH] Update utils.py i have added `NodeAlgorithims` i have copied them from wavelink and its a handy feature, and can improve and introduce more algorithims. --- pomice/utils.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/pomice/utils.py b/pomice/utils.py index a8be0b2..066e12c 100644 --- a/pomice/utils.py +++ b/pomice/utils.py @@ -20,19 +20,38 @@ DEALINGS IN THE SOFTWARE. import random import time -from typing import Union +from typing import Union, List from discord import AutoShardedClient, Client from discord.ext.commands import AutoShardedBot, Bot +from pomice.exceptions import OptionNotToggled + +from pomice.pool import NodePool __all__ = [ 'ExponentialBackoff', 'NodeStats', - 'ClientType' + 'ClientType', + 'NodeAlgorithims', + 'if_toggled' ] ClientType = Union[AutoShardedBot, AutoShardedClient, Bot, Client] +def if_toggled(option): + + def wrapper(func): + + def inner(*args, **kwargs): + _option = NodePool._config.get(option, None) + if not _option: + raise OptionNotToggled(f"The `{option}` was not Toggled for the Feature `{func.__name__}`.") + + return func(*args, **kwargs) + + return inner + + return wrapper class ExponentialBackoff: @@ -85,3 +104,53 @@ class NodeStats: def __repr__(self) -> str: return f'' + +class NodeAlgorithims: + """Class that Contains Algorithims for searching Nodes or get extact Players regardless of their Node""" + + def __init__(self, data : dict) -> None: + self.nodes = data.get("nodes", []) + self.first = self.nodes[0] if self.nodes else None + + @classmethod + def base(cls, nodes): + return cls({'nodes' : random.choice(nodes)}) + + @classmethod + def best_nodes(cls, nodes, ping_wise=False, least_player=False): + """Returns Best Node Based on the Number of Players it has""" + if not ping_wise: + + return cls( + {'nodes' : sorted(nodes, key=lambda node: node.player_count) + if least_player else nodes + }) + else: + if not (nodes:= [ + node for node in nodes + if (node.latency < 50 or 100 >= node.latency <= 20) + ]): + return None + + return cls( + {'nodes' : sorted(nodes, key=lambda node: node.player_count) + if least_player else nodes + }) + + + @classmethod + def closest_nodes(cls, nodes, region,least_players = False): + """Returns Closest Node, mainly by checking the if the Regions are Equal + Best to Pass the Exact Region you want. + """ + if not (nodes:=[ + n for n in nodes + if n.region.lower() == region.lower() + ]): + return None + + return cls( + {'nodes': sorted(nodes, key=lambda node: node.player_count)[0] + if least_players else nodes[0] + }) +