Last active
March 22, 2025 11:38
-
-
Save st1vms/52f3a974c7a60c06ea0b4a726974dd04 to your computer and use it in GitHub Desktop.
Revisions
-
st1vms revised this gist
Nov 6, 2023 . 1 changed file with 3 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -48,19 +48,18 @@ def get_free_tier_ratings() -> list[tuple[str, float]] | None: print("Error retrieving stats...") return None tiers = __free_tiers() ret = [] for entry in stats["LogicalServers"]: if not "Domain" in entry or not "Load" in entry: continue domain: str = entry["Domain"] load = entry["Load"] if domain.split(".")[0] in tiers: ret.append((domain, load)) return sorted(ret, key=lambda x: x[1]) def __main() -> None: -
st1vms revised this gist
Nov 6, 2023 . 1 changed file with 4 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -56,14 +56,14 @@ def get_free_tier_ratings() -> list[tuple[str, float]] | None: domain: str = entry["Domain"] load = entry["Load"] if domain.split(".")[0] in __free_tiers(): ret.append((domain, load)) ret = sorted(ret, key=lambda x: x[1]) return ret def __main() -> None: """Main""" i = 0 while not i: @@ -82,7 +82,7 @@ def main() -> None: print(f"{rate[0]} -> {rate[1]}%") def __free_tiers() -> set: """Embedded ProtonVPN free tiers domain names.""" return { "node-jp-26", @@ -278,4 +278,4 @@ def free_tiers() -> set: if __name__ == "__main__": __main() -
st1vms created this gist
Nov 6, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,281 @@ """Auto retrieve ProtonVPN free-tiers load ratings""" from requests import get as http_get # Taken from https://account.protonvpn.com/downloads # Open dev-tools and look for GET requests to /api/vpn/logicals endpoint # Copy the entire cookie header value into this string __COOKIE_STRING = "" # Also copy the x-pm-uid header value from that same GET request into this string __X_PM_UID_STRING = "" # Also copy your browser User Agent into this string __USER_AGENT = "" def __get_json_stats() -> dict | None: url = "https://account.protonvpn.com/api/vpn/logicals" headers = { "Host": "account.protonvpn.com", "User-Agent": __USER_AGENT, "Accept": "application/vnd.protonmail.v1+json", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Referer": "https://account.protonvpn.com/downloads", "x-pm-appversion": "[email protected]", "DNT": "1", "Connection": "keep-alive", "x-pm-uid": __X_PM_UID_STRING, "Cookie": __COOKIE_STRING, "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", "TE": "trailers", } res = http_get(url, headers=headers, timeout=5) if res.status_code == 200: return res.json() return None def get_free_tier_ratings() -> list[tuple[str, float]] | None: """Retrieves list of tuples, containing ordered domain names with their load number""" stats = __get_json_stats() if not stats or not "LogicalServers" in stats: print("Error retrieving stats...") return None ret = [] for entry in stats["LogicalServers"]: if not "Domain" in entry or not "Load" in entry: continue domain: str = entry["Domain"] load = entry["Load"] if domain.split(".")[0] in free_tiers(): ret.append((domain, load)) ret = sorted(ret, key=lambda x: x[1]) return ret def main() -> None: """Main""" i = 0 while not i: try: i = int(input("\nHow many results you want to get?\n>>").strip()) if i <= 0: i = 0 print("\nMust be a positive value!") continue except ValueError: i = 0 continue ratings = get_free_tier_ratings() for rate in ratings[:i]: print(f"{rate[0]} -> {rate[1]}%") def free_tiers() -> set: """Embedded ProtonVPN free tiers domain names.""" return { "node-jp-26", "node-nl-141", "node-nl-93", "node-nl-182", "node-us-198", "node-nl-161", "node-us-91", "node-us-61", "node-nl-139", "node-us-145", "node-nl-172", "node-us-175", "node-us-162", "node-nl-185", "node-nl-06", "node-nl-113", "node-nl-83", "node-ro-07", "node-nl-02", "node-nl-191", "node-nl-132", "node-nl-187", "node-nl-162", "node-nl-81", "node-jp-28", "node-nl-134", "node-us-128", "node-nl-199", "node-nl-124", "node-nl-123", "node-nl-163", "node-nl-189", "node-nl-98", "node-us-151", "node-nl-110", "node-nl-128", "node-jp-13", "node-nl-203", "node-nl-97", "node-us-159", "node-us-141", "node-us-72", "node-nl-180", "node-us-155", "node-nl-158", "node-nl-200", "node-nl-156", "node-us-191", "node-jp-19", "node-nl-72", "node-jp-24", "node-nl-196", "node-us-147", "node-nl-149", "node-nl-140", "node-pl-12", "node-nl-71", "node-nl-148", "node-nl-05", "node-us-137", "node-ro-04", "node-nl-94", "node-nl-95", "node-jp-15", "node-nl-130", "node-nl-178", "node-jp-18", "node-nl-68", "node-nl-105", "node-jp-16", "node-ro-03", "node-nl-74", "node-us-54", "node-nl-57", "node-us-146", "node-nl-76", "node-us-184", "node-ro-06", "node-nl-159", "node-nl-181", "node-nl-193", "node-nl-111", "node-jp-27", "node-nl-129", "node-us-154", "node-nl-117", "node-nl-150", "node-nl-109", "node-nl-108", "node-nl-142", "node-nl-133", "node-us-136", "node-us-193", "node-nl-170", "node-us-148", "node-nl-173", "node-nl-92", "node-jp-22", "node-us-70", "node-nl-79", "node-nl-186", "node-us-163", "node-nl-101", "node-us-73", "node-us-131", "node-us-55", "node-nl-197", "node-nl-96", "node-us-133", "node-nl-126", "node-jp-21", "node-us-47", "node-nl-184", "node-us-62", "node-nl-152", "node-nl-147", "node-nl-188", "node-us-45", "node-us-156", "node-nl-106", "node-us-196", "node-us-76", "node-us-60", "node-us-71", "node-nl-70", "node-nl-179", "node-us-152", "node-nl-201", "node-nl-102", "node-nl-127", "node-us-149", "node-jp-25", "node-nl-164", "node-nl-198", "node-nl-175", "node-us-142", "node-nl-137", "node-us-170", "node-nl-69", "node-us-132", "node-nl-114", "node-us-180", "node-us-150", "node-nl-90", "node-nl-125", "node-ro-05", "node-nl-154", "node-jp-20", "node-nl-75", "node-us-56", "node-pl-13", "node-nl-77", "node-nl-115", "node-nl-82", "node-nl-169", "node-nl-195", "node-nl-176", "node-pl-11", "node-nl-78", "node-nl-177", "node-nl-116", "node-nl-91", "node-nl-103", "node-us-78", "node-pl-10", "node-nl-153", "node-nl-138", "node-us-81", "node-nl-118", "node-nl-183", "node-us-138", "node-us-140", "node-jp-23", "node-us-139", "node-jp-11", "node-nl-190", "node-nl-160", "node-nl-04", "node-us-153", "node-nl-155", "node-nl-104", "node-nl-157", "node-nl-171", "node-pl-09", "node-us-157", "node-nl-73", "node-nl-192", "node-nl-03", "node-nl-131", } if __name__ == "__main__": main()