import time
import requests
from py_progress.progress import ProgressBar
import math
import threading

class Proxy:
    def __init__(self, proxi_link):
        self.proxy_link = proxi_link

    def ping(self):
        try:
            response = requests.get("http://httpbin.org/ip", proxies=self.proxy_link, timeout=5)
            return True, response.json()
        except Exception as e:
            return False, e

    def test_speed(self, obj):
        start_time = time.time()
        response = requests.get("https://file-examples.net/wp-content/uploads/2024/02/file-sample_100kB.doc", proxies=self.proxy_link, timeout=10)
        end_time = time.time()
        obj.set_speed(self, 1 / (end_time - start_time))
        return 1 / (end_time - start_time)
    
    def __repr__(self):
        return f"proxy: {self.proxy_link["http"]}"

class ProxiesManager:
    def __init__(self, proxies_array):
        self.proxies_array = proxies_array

    def set_speed(self, obj, time_used):
        self.proxies_speed_array.append([obj, time_used])


    def test_speed(self, progress_func_update=None):
        self.proxies_speed_array = []
        pb = ProgressBar(len(self.proxies_array))
        for el in self.proxies_array:
            threading.Thread(target=el.test_speed, args=(self,)).start()
            pb.progress_with_time("")
            if progress_func_update is not None:
                threading.Thread(target=progress_func_update, args=(math.ceil((pb.procent / pb.all)  * 100), "find proxies")).start()

        while len(self.proxies_array) > len(self.proxies_speed_array):
            time.sleep(0.5)

        return self.proxies_speed_array
    
    def get_best_proxies(self, max_proxies=15, progress_func_update=None):
        proxies_speed_array = self.test_speed(progress_func_update=progress_func_update)

        for i in range(len(proxies_speed_array)):
            for j in range(len(proxies_speed_array) - 1):
                if proxies_speed_array[j][1] > proxies_speed_array[j + 1][1]:
                    proxies_speed_array[j], proxies_speed_array[j + 1] = proxies_speed_array[j + 1], proxies_speed_array[j]

        proxies_speed_array.reverse()
        current_proxies = proxies_speed_array[:max_proxies]

        mean_speed = 0
        for el in current_proxies:
            mean_speed += el[1]

        mean_speed /= len(current_proxies)
        only_proxies = [el[0] for el in current_proxies]
        return current_proxies, only_proxies, mean_speed

from bs4 import BeautifulSoup
import requests

def load_proxies(base_url="https://free-proxy-list.net/ru/uk-proxy.html"):
    html_data = requests.get(base_url).text
    soup = BeautifulSoup(html_data, 'html.parser')

    textarea = soup.find('textarea', class_='form-control')

    all_proxyes_raw = textarea.text
    all_proxyes_text: str = all_proxyes_raw[75:-1]
    all_proxyes = all_proxyes_text.split("\n")
    proxies = [Proxy({"http": f"http://{url}"}) for url in all_proxyes]

    return proxies

if __name__ == "__main__":
    pm = ProxiesManager(load_proxies())
    print(pm.get_best_proxies(10))
