From d0eb50e39634772aafb6bad90ce65e299969567e Mon Sep 17 00:00:00 2001 From: Eric Froemling Date: Thu, 6 May 2021 11:57:18 -0500 Subject: [PATCH] Moving a bit of network functionality to efro package --- .efrocachemap | 76 +++++++++---------- assets/.asset_manifest_public.json | 2 + assets/Makefile | 2 + assets/src/ba_data/python/ba/_net.py | 68 +---------------- assets/src/ba_data/python/ba/internal.py | 3 +- .../python/bastd/ui/gather/manualtab.py | 2 +- .../python/bastd/ui/gather/publictab.py | 4 +- docs/ba_module.md | 2 +- tools/efro/net.py | 75 ++++++++++++++++++ 9 files changed, 124 insertions(+), 110 deletions(-) create mode 100644 tools/efro/net.py diff --git a/.efrocachemap b/.efrocachemap index 1e75210d..62471b39 100644 --- a/.efrocachemap +++ b/.efrocachemap @@ -429,11 +429,11 @@ "assets/build/ba_data/data/languages/czech.json": "https://files.ballistica.net/cache/ba1/e3/10/ace3a73616f1f36540e585e5bbce", "assets/build/ba_data/data/languages/danish.json": "https://files.ballistica.net/cache/ba1/3f/46/e4da3c1d2b0ebf916df55c608b28", "assets/build/ba_data/data/languages/dutch.json": "https://files.ballistica.net/cache/ba1/d1/07/37b7adc3dbec7328d26c5325f212", - "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/ca/61/d7ef5dcc21589508188ab3698d11", + "assets/build/ba_data/data/languages/english.json": "https://files.ballistica.net/cache/ba1/a0/78/7d4ef87f7f8c04f9684db7098b91", "assets/build/ba_data/data/languages/esperanto.json": "https://files.ballistica.net/cache/ba1/6e/fd/685a4e1da031474d47a1d9eb2731", "assets/build/ba_data/data/languages/french.json": "https://files.ballistica.net/cache/ba1/41/30/040a5038fccbfeaa28e85d3bc863", "assets/build/ba_data/data/languages/german.json": "https://files.ballistica.net/cache/ba1/bc/62/e8a3da4b4c09841edade01c5c921", - "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/5c/4e/866fedf81352bc09fd609c92bc7b", + "assets/build/ba_data/data/languages/gibberish.json": "https://files.ballistica.net/cache/ba1/3d/88/6ca54f6089c255f9e788c1878965", "assets/build/ba_data/data/languages/greek.json": "https://files.ballistica.net/cache/ba1/51/31/64479524c0ee990b3e97ffdca068", "assets/build/ba_data/data/languages/hindi.json": "https://files.ballistica.net/cache/ba1/32/a4/fae7a30ead18c6cb97db60dd9445", "assets/build/ba_data/data/languages/hungarian.json": "https://files.ballistica.net/cache/ba1/87/2d/027aa239eb66ea8f496562f4fd83", @@ -3932,40 +3932,40 @@ "assets/build/windows/Win32/ucrtbased.dll": "https://files.ballistica.net/cache/ba1/b5/85/f8b6d0558ddb87267f34254b1450", "assets/build/windows/Win32/vc_redist.x86.exe": "https://files.ballistica.net/cache/ba1/1c/e1/4a1a2eddda2f4aebd5f8b64ab08e", "assets/build/windows/Win32/vcruntime140d.dll": "https://files.ballistica.net/cache/ba1/50/8d/bc2600ac9491f1b14d659709451f", - "build/prefab/full/linux_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/e2/d6/e2556690b03b2b9d8ee58f03a7ec", - "build/prefab/full/linux_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/30/e4/eb49c35987c272644a5f4611efd2", - "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/4f/b4/cc038f8efb182a4e2dcfdcef8a63", - "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ab/00/247128e73b68ec204d18e5b5f979", - "build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/18/9f/66ee828947d9de9c4ef09eb65e74", - "build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/c6/ea/6c872204b650e8618c57c32c1822", - "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/63/3a/436e0c6ecda801ce385f9b6bfe79", - "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/89/f2/f43d5450e0e630ebb0e5e6ad3aea", - "build/prefab/full/mac_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/13/36/5a458cf3bce7aff5f542dd50b141", - "build/prefab/full/mac_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ac/9b/15186f78478a5eb6c9b5e38de49f", - "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/6c/32/d9c4f8fdb48b291af3b620e175f2", - "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/b5/2d/be628abf9d6d8a5d4b411082090e", - "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ba/6c/51f5429352da929bc58f882970fd", - "build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/22/f1/da5267d4b859bf97d7eaa58df19a", - "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/e0/a6/23b31d28a621dd77a3045ea1731b", - "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/c9/7e/04c68bfd4e805cf95d682c3bb8f9", - "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/a7/ad/696efc028b073f79010f234698f6", - "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/4c/83/bdaaf33c2b0e14d42d5cf0fb21aa", - "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/cd/72/e3f3aff99f639f95bba6a9cfc1d7", - "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/23/29/769002cf7a590457fa34ee1c8f5a", - "build/prefab/lib/linux_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f4/59/16c01f646c16bb480a197aa9e6e3", - "build/prefab/lib/linux_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/81/73/a321fe4aa721d07f2a44257967cf", - "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/99/99/2adf5a22923eed3f8b5667ee8220", - "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/69/1f/37262b454458ff84c6d31dedb582", - "build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/27/98/a2429918bb561f1cc47ea77107c5", - "build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3d/3a/c747993afbf4c1ed1c5e8b0e5d5a", - "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/46/21/31fe300afbf7d9da766c04064919", - "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/f8/bd/2b05dbfd98cd55cedf924b639765", - "build/prefab/lib/mac_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/9f/92/8b198e3bf31f5e5d9ec6a14e8c31", - "build/prefab/lib/mac_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ff/c0/806391f8bf542f95515dde44125b", - "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/5f/05/cd421a73b0228daab509bef68146", - "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/e0/16/64a54c6ed0868cceb2391b75cf20", - "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/08/76/cb4648160a1a698ffd17d2a4b4c1", - "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ad/b5/39a8f6289c0e7298329082d1576e", - "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/89/86/0abb381fe2c25609900b3cb6d1da", - "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ec/be/4a78a060e2b64d7d7692d14b3266" + "build/prefab/full/linux_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/6c/92/62596fae6b7a41b6ae34541471a0", + "build/prefab/full/linux_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/ea/33/271afcf89a0742c3a2912ccf8c8f", + "build/prefab/full/linux_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/59/df/62ff99accbab10fa88fae24286fc", + "build/prefab/full/linux_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/77/8b/9733a0fb7f1fb1a88c566c1ec091", + "build/prefab/full/linux_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/21/62/b84beb830b5c6002caacdb0ccf25", + "build/prefab/full/linux_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/42/88/1fbd73b85c88124ee85c04124a13", + "build/prefab/full/linux_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/dd/97/bbbc468df82e2170efc4953d29d2", + "build/prefab/full/linux_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/ec/45/5ecff4b145a403cb787e95fbf192", + "build/prefab/full/mac_arm64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/eb/00/f13590d9c58bf497b3c12a317381", + "build/prefab/full/mac_arm64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d4/3c/c7179fc098cdf88a57f06b7042f7", + "build/prefab/full/mac_arm64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/0a/9a/9eba085afa5b1acf7c47ab1a8696", + "build/prefab/full/mac_arm64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/59/9b/34ed91c0e277d3dbdbcaf442e6e1", + "build/prefab/full/mac_x86_64/debug/ballisticacore": "https://files.ballistica.net/cache/ba1/ea/64/c3cb2d9d2c07c3e430e456f483f0", + "build/prefab/full/mac_x86_64/release/ballisticacore": "https://files.ballistica.net/cache/ba1/d3/fc/f1c2e576de1114540f93e01c16bf", + "build/prefab/full/mac_x86_64_server/debug/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/2f/82/38e501b63caebfdd65b767767053", + "build/prefab/full/mac_x86_64_server/release/dist/ballisticacore_headless": "https://files.ballistica.net/cache/ba1/1f/12/7607755cb18668958af9d66398fc", + "build/prefab/full/windows_x86/debug/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/1f/ef/174da4a4f0ca9232e17598da64e9", + "build/prefab/full/windows_x86/release/BallisticaCore.exe": "https://files.ballistica.net/cache/ba1/18/0d/cfcd95e124eb780c6d17a528a7ef", + "build/prefab/full/windows_x86_server/debug/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/d2/4f/24a4b1257297029dee9c25a49e65", + "build/prefab/full/windows_x86_server/release/dist/ballisticacore_headless.exe": "https://files.ballistica.net/cache/ba1/88/5f/31611fa40ca63d1d6c51f709e3f0", + "build/prefab/lib/linux_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/fa/c6/b1b2902968963e82bbf908fb7c59", + "build/prefab/lib/linux_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/93/f3/6257ac124adfbb3223e21a469dfb", + "build/prefab/lib/linux_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/4a/25/0709a07a4d2087aee7cc6d287554", + "build/prefab/lib/linux_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/73/3b/16a1320aa890d20b89bd79745199", + "build/prefab/lib/linux_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/1a/2e/3ca0cf49524b8a74692651530c16", + "build/prefab/lib/linux_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/c4/b1/e608ae94f9311a54d7991b647af9", + "build/prefab/lib/linux_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/34/12/a60180d4dd396c45ae6e90df8821", + "build/prefab/lib/linux_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/52/be/df2354e5ef22c71cd06c17f42575", + "build/prefab/lib/mac_arm64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/ac/4e/ec856c1731b69979069c4c6ef9b4", + "build/prefab/lib/mac_arm64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/05/5b/e0d07e619735cfcffa1577c60ecd", + "build/prefab/lib/mac_arm64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/7e/f5/bfcf734627a14c392421e2f131c6", + "build/prefab/lib/mac_arm64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/40/7c/d8ae58487df75e5627b41a09544e", + "build/prefab/lib/mac_x86_64/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/80/e0/3f051f0f83a009cac88638f64c6f", + "build/prefab/lib/mac_x86_64/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/3c/04/58ec8769cfb9afb087633dabeab4", + "build/prefab/lib/mac_x86_64_server/debug/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/00/fe/e44f2e87223f51c1ad0af56bcd05", + "build/prefab/lib/mac_x86_64_server/release/libballisticacore_internal.a": "https://files.ballistica.net/cache/ba1/58/b5/e0e1386ce107037e5e82ebdef7fb" } \ No newline at end of file diff --git a/assets/.asset_manifest_public.json b/assets/.asset_manifest_public.json index 671f9cd0..f5f69652 100644 --- a/assets/.asset_manifest_public.json +++ b/assets/.asset_manifest_public.json @@ -497,6 +497,7 @@ "ba_data/python/efro/__pycache__/dataclassio.cpython-38.opt-1.pyc", "ba_data/python/efro/__pycache__/error.cpython-38.opt-1.pyc", "ba_data/python/efro/__pycache__/json.cpython-38.opt-1.pyc", + "ba_data/python/efro/__pycache__/net.cpython-38.opt-1.pyc", "ba_data/python/efro/__pycache__/terminal.cpython-38.opt-1.pyc", "ba_data/python/efro/__pycache__/util.cpython-38.opt-1.pyc", "ba_data/python/efro/call.py", @@ -517,6 +518,7 @@ "ba_data/python/efro/entity/util.py", "ba_data/python/efro/error.py", "ba_data/python/efro/json.py", + "ba_data/python/efro/net.py", "ba_data/python/efro/terminal.py", "ba_data/python/efro/util.py", "server/__pycache__/ballisticacore_server.cpython-38.opt-1.pyc", diff --git a/assets/Makefile b/assets/Makefile index 1032b7bf..95395c7b 100644 --- a/assets/Makefile +++ b/assets/Makefile @@ -650,6 +650,7 @@ SCRIPT_TARGETS_PY_PUBLIC_TOOLS = \ build/ba_data/python/efro/entity/util.py \ build/ba_data/python/efro/error.py \ build/ba_data/python/efro/json.py \ + build/ba_data/python/efro/net.py \ build/ba_data/python/efro/terminal.py \ build/ba_data/python/efro/util.py @@ -671,6 +672,7 @@ SCRIPT_TARGETS_PYC_PUBLIC_TOOLS = \ build/ba_data/python/efro/entity/__pycache__/util.cpython-38.opt-1.pyc \ build/ba_data/python/efro/__pycache__/error.cpython-38.opt-1.pyc \ build/ba_data/python/efro/__pycache__/json.cpython-38.opt-1.pyc \ + build/ba_data/python/efro/__pycache__/net.cpython-38.opt-1.pyc \ build/ba_data/python/efro/__pycache__/terminal.cpython-38.opt-1.pyc \ build/ba_data/python/efro/__pycache__/util.cpython-38.opt-1.pyc diff --git a/assets/src/ba_data/python/ba/_net.py b/assets/src/ba_data/python/ba/_net.py index 28254f53..ea12d48a 100644 --- a/assets/src/ba_data/python/ba/_net.py +++ b/assets/src/ba_data/python/ba/_net.py @@ -28,72 +28,6 @@ class NetworkSubsystem: self.region_pings: Dict[str, float] = {} -def is_urllib_network_error(exc: BaseException) -> bool: - """Is the provided exception a network-related error? - - This should be passed an exception which resulted from opening or - reading a urllib Request. It should return True for any errors that - could conceivably arise due to unavailable/poor network connections, - firewall/connectivity issues, etc. These issues can often be safely - ignored or presented to the user as general 'network-unavailable' - states. - """ - import urllib.request - import urllib.error - import http.client - import errno - import socket - if isinstance( - exc, - (urllib.error.URLError, ConnectionError, http.client.IncompleteRead, - http.client.BadStatusLine, socket.timeout)): - return True - if isinstance(exc, OSError): - if exc.errno == 10051: # Windows unreachable network error. - return True - if exc.errno in { - errno.ETIMEDOUT, - errno.EHOSTUNREACH, - errno.ENETUNREACH, - }: - return True - return False - - -def is_udp_network_error(exc: BaseException) -> bool: - """Is the provided exception a network-related error? - - This should be passed an exception which resulted from creating and - using a socket.SOCK_DGRAM type socket. It should return True for any - errors that could conceivably arise due to unavailable/poor network - connections, firewall/connectivity issues, etc. These issues can often - be safely ignored or presented to the user as general - 'network-unavailable' states. - """ - import errno - if isinstance(exc, ConnectionRefusedError): - return True - if isinstance(exc, OSError): - if exc.errno == 10051: # Windows unreachable network error. - return True - if exc.errno in { - errno.EADDRNOTAVAIL, - errno.ETIMEDOUT, - errno.EHOSTUNREACH, - errno.ENETUNREACH, - errno.EINVAL, - errno.EPERM, - errno.EACCES, - # Windows 'invalid argument' error. - 10022, - # Windows 'a socket operation was attempted to' - # 'an unreachable network' error. - 10051, - }: - return True - return False - - def get_ip_address_type(addr: str) -> socket.AddressFamily: """Return socket.AF_INET6 or socket.AF_INET4 for the provided address.""" import socket @@ -167,6 +101,8 @@ class MasterServerCallThread(threading.Thread): import urllib.request import urllib.error import json + + from efro.net import is_urllib_network_error from ba import _general try: self._data = _general.utf8_all(self._data) diff --git a/assets/src/ba_data/python/ba/internal.py b/assets/src/ba_data/python/ba/internal.py index 97771622..26fae04e 100644 --- a/assets/src/ba_data/python/ba/internal.py +++ b/assets/src/ba_data/python/ba/internal.py @@ -26,8 +26,7 @@ from ba._messages import PlayerProfilesChangedMessage from ba._multiteamsession import DEFAULT_TEAM_COLORS, DEFAULT_TEAM_NAMES from ba._music import do_play_music from ba._net import (master_server_get, master_server_post, - get_ip_address_type, is_urllib_network_error, - is_udp_network_error, DEFAULT_REQUEST_TIMEOUT_SECONDS) + get_ip_address_type, DEFAULT_REQUEST_TIMEOUT_SECONDS) from ba._powerup import get_default_powerup_distribution from ba._profile import (get_player_profile_colors, get_player_profile_icon, get_player_colors) diff --git a/assets/src/ba_data/python/bastd/ui/gather/manualtab.py b/assets/src/ba_data/python/bastd/ui/gather/manualtab.py index 80ab5981..02963a79 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/manualtab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/manualtab.py @@ -633,7 +633,7 @@ class ManualGatherTab(GatherTab): from_other_thread=True, ) except Exception as exc: - from ba.internal import is_udp_network_error + from efro.net import is_udp_network_error if is_udp_network_error(exc): ba.pushcall(ba.Call( _safe_set_text, self._checking_state_text, diff --git a/assets/src/ba_data/python/bastd/ui/gather/publictab.py b/assets/src/ba_data/python/bastd/ui/gather/publictab.py index 05fc7953..a2198579 100644 --- a/assets/src/ba_data/python/bastd/ui/gather/publictab.py +++ b/assets/src/ba_data/python/bastd/ui/gather/publictab.py @@ -219,7 +219,7 @@ class AddrFetchThread(threading.Thread): sock.close() ba.pushcall(ba.Call(self._call, val), from_other_thread=True) except Exception as exc: - from ba.internal import is_udp_network_error + from efro.net import is_udp_network_error # Ignore expected network errors; log others. if is_udp_network_error(exc): pass @@ -271,7 +271,7 @@ class PingThread(threading.Thread): ping if accessible else None), from_other_thread=True) except Exception as exc: - from ba.internal import is_udp_network_error + from efro.net import is_udp_network_error if is_udp_network_error(exc): pass else: diff --git a/docs/ba_module.md b/docs/ba_module.md index cd73497f..12a4f5a1 100644 --- a/docs/ba_module.md +++ b/docs/ba_module.md @@ -1,5 +1,5 @@ -

last updated on 2021-05-05 for Ballistica version 1.6.0 build 20357

+

last updated on 2021-05-06 for Ballistica version 1.6.1 build 20361

This page documents the Python classes and functions in the 'ba' module, which are the ones most relevant to modding in Ballistica. If you come across something you feel should be included here or could be better explained, please let me know. Happy modding!


diff --git a/tools/efro/net.py b/tools/efro/net.py new file mode 100644 index 00000000..2c8bda21 --- /dev/null +++ b/tools/efro/net.py @@ -0,0 +1,75 @@ +# Released under the MIT License. See LICENSE for details. +# +"""Network related functionality.""" +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + pass + + +def is_urllib_network_error(exc: BaseException) -> bool: + """Is the provided exception a network-related error? + + This should be passed an exception which resulted from opening or + reading a urllib Request. It should return True for any errors that + could conceivably arise due to unavailable/poor network connections, + firewall/connectivity issues, etc. These issues can often be safely + ignored or presented to the user as general 'network-unavailable' + states. + """ + import urllib.request + import urllib.error + import http.client + import errno + import socket + if isinstance( + exc, + (urllib.error.URLError, ConnectionError, http.client.IncompleteRead, + http.client.BadStatusLine, socket.timeout)): + return True + if isinstance(exc, OSError): + if exc.errno == 10051: # Windows unreachable network error. + return True + if exc.errno in { + errno.ETIMEDOUT, + errno.EHOSTUNREACH, + errno.ENETUNREACH, + }: + return True + return False + + +def is_udp_network_error(exc: BaseException) -> bool: + """Is the provided exception a network-related error? + + This should be passed an exception which resulted from creating and + using a socket.SOCK_DGRAM type socket. It should return True for any + errors that could conceivably arise due to unavailable/poor network + connections, firewall/connectivity issues, etc. These issues can often + be safely ignored or presented to the user as general + 'network-unavailable' states. + """ + import errno + if isinstance(exc, ConnectionRefusedError): + return True + if isinstance(exc, OSError): + if exc.errno == 10051: # Windows unreachable network error. + return True + if exc.errno in { + errno.EADDRNOTAVAIL, + errno.ETIMEDOUT, + errno.EHOSTUNREACH, + errno.ENETUNREACH, + errno.EINVAL, + errno.EPERM, + errno.EACCES, + # Windows 'invalid argument' error. + 10022, + # Windows 'a socket operation was attempted to' + # 'an unreachable network' error. + 10051, + }: + return True + return False