Initial Commit
This commit is contained in:
60
unshackle/core/proxies/hola.py
Normal file
60
unshackle/core/proxies/hola.py
Normal file
@@ -0,0 +1,60 @@
|
||||
import random
|
||||
import re
|
||||
import subprocess
|
||||
from typing import Optional
|
||||
|
||||
from unshackle.core import binaries
|
||||
from unshackle.core.proxies.proxy import Proxy
|
||||
|
||||
|
||||
class Hola(Proxy):
|
||||
def __init__(self):
|
||||
"""
|
||||
Proxy Service using Hola's direct connections via the hola-proxy project.
|
||||
https://github.com/Snawoot/hola-proxy
|
||||
"""
|
||||
self.binary = binaries.HolaProxy
|
||||
if not self.binary:
|
||||
raise EnvironmentError("hola-proxy executable not found but is required for the Hola proxy provider.")
|
||||
|
||||
self.countries = self.get_countries()
|
||||
|
||||
def __repr__(self) -> str:
|
||||
countries = len(self.countries)
|
||||
|
||||
return f"{countries} Countr{['ies', 'y'][countries == 1]}"
|
||||
|
||||
def get_proxy(self, query: str) -> Optional[str]:
|
||||
"""
|
||||
Get an HTTP proxy URI for a Datacenter ('direct') or Residential ('lum') Hola server.
|
||||
|
||||
TODO: - Add ability to select 'lum' proxies (residential proxies).
|
||||
- Return and use Proxy Authorization
|
||||
"""
|
||||
query = query.lower()
|
||||
|
||||
p = subprocess.check_output(
|
||||
[self.binary, "-country", query, "-list-proxies"], stderr=subprocess.STDOUT
|
||||
).decode()
|
||||
|
||||
if "Transaction error: temporary ban detected." in p:
|
||||
raise ConnectionError("Hola banned your IP temporarily from it's services. Try change your IP.")
|
||||
|
||||
username, password, proxy_authorization = re.search(
|
||||
r"Login: (.*)\nPassword: (.*)\nProxy-Authorization: (.*)", p
|
||||
).groups()
|
||||
|
||||
servers = re.findall(r"(zagent.*)", p)
|
||||
proxies = []
|
||||
for server in servers:
|
||||
host, ip_address, direct, peer, hola, trial, trial_peer, vendor = server.split(",")
|
||||
proxies.append(f"http://{username}:{password}@{ip_address}:{peer}")
|
||||
|
||||
proxy = random.choice(proxies)
|
||||
return proxy
|
||||
|
||||
def get_countries(self) -> list[dict[str, str]]:
|
||||
"""Get a list of available Countries."""
|
||||
p = subprocess.check_output([self.binary, "-list-countries"]).decode("utf8")
|
||||
|
||||
return [{code: name} for country in p.splitlines() for (code, name) in [country.split(" - ", maxsplit=1)]]
|
||||
Reference in New Issue
Block a user