prim-ctrl 0.8.3__tar.gz → 0.8.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {prim_ctrl-0.8.3 → prim_ctrl-0.8.5}/PKG-INFO +1 -1
- {prim_ctrl-0.8.3 → prim_ctrl-0.8.5}/prim_ctrl/__main__.py +46 -21
- {prim_ctrl-0.8.3 → prim_ctrl-0.8.5}/pyproject.toml +1 -1
- {prim_ctrl-0.8.3 → prim_ctrl-0.8.5}/LICENSE +0 -0
- {prim_ctrl-0.8.3 → prim_ctrl-0.8.5}/README.md +0 -0
- {prim_ctrl-0.8.3 → prim_ctrl-0.8.5}/prim_ctrl/__init__.py +0 -0
|
@@ -44,13 +44,19 @@ class LevelFormatter(logging.Formatter):
|
|
|
44
44
|
return self.formatters.get(record.levelno, self.default_formatter).format(record)
|
|
45
45
|
|
|
46
46
|
class Logger(logging.Logger):
|
|
47
|
+
timestamp: bool = False
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def setConfiguration(timestamp: bool):
|
|
51
|
+
Logger.timestamp = timestamp
|
|
52
|
+
|
|
47
53
|
def __init__(self, name, level = logging.NOTSET):
|
|
48
54
|
super().__init__(name, level)
|
|
49
|
-
self.
|
|
55
|
+
self.addHandler(logging.StreamHandler(sys.stderr))
|
|
56
|
+
self.configure()
|
|
50
57
|
|
|
51
|
-
def
|
|
52
|
-
|
|
53
|
-
handler.setFormatter(
|
|
58
|
+
def configure(self):
|
|
59
|
+
formatter = (
|
|
54
60
|
LevelFormatter(
|
|
55
61
|
{
|
|
56
62
|
logging.WARNING: '%(asctime)s %(message)s',
|
|
@@ -58,7 +64,7 @@ class Logger(logging.Logger):
|
|
|
58
64
|
logging.DEBUG: '%(asctime)s %(levelname)s %(message)s',
|
|
59
65
|
},
|
|
60
66
|
'%(asctime)s %(name)s: %(levelname)s: %(message)s')
|
|
61
|
-
if timestamp else
|
|
67
|
+
if Logger.timestamp else
|
|
62
68
|
LevelFormatter(
|
|
63
69
|
{
|
|
64
70
|
logging.WARNING: '%(message)s',
|
|
@@ -67,9 +73,16 @@ class Logger(logging.Logger):
|
|
|
67
73
|
},
|
|
68
74
|
'%(name)s: %(levelname)s: %(message)s')
|
|
69
75
|
)
|
|
70
|
-
self.
|
|
71
|
-
|
|
72
|
-
|
|
76
|
+
for handler in self.handlers:
|
|
77
|
+
handler.setFormatter(formatter)
|
|
78
|
+
|
|
79
|
+
class MainLogger(Logger):
|
|
80
|
+
def __init__(self, name, level = logging.NOTSET):
|
|
81
|
+
super().__init__(name, level)
|
|
82
|
+
self.exitcode = 0
|
|
83
|
+
|
|
84
|
+
def setConfiguration(self, level: int):
|
|
85
|
+
self.setLevel(level)
|
|
73
86
|
|
|
74
87
|
def exception_or_error(self, e: Exception):
|
|
75
88
|
if self.level == logging.NOTSET or self.level == logging.DEBUG:
|
|
@@ -109,7 +122,7 @@ class LazyStr:
|
|
|
109
122
|
self.result = str(self.func)
|
|
110
123
|
return self.result
|
|
111
124
|
|
|
112
|
-
logger =
|
|
125
|
+
logger = MainLogger(Path(sys.argv[0]).name)
|
|
113
126
|
|
|
114
127
|
########
|
|
115
128
|
|
|
@@ -727,8 +740,10 @@ class Funnel(Pingable):
|
|
|
727
740
|
self.external_port = external_port
|
|
728
741
|
self.external_url = f'https://{machine_name}.{tailscale.tailnet}:{external_port}{local_path}'
|
|
729
742
|
self.local_tailscale = local_tailscale
|
|
743
|
+
self.external_public_dns_resolver_address = None
|
|
730
744
|
self.external_public_dns_resolver = None
|
|
731
|
-
self.
|
|
745
|
+
self.external_tailscale_dns_resolver_addresses = None
|
|
746
|
+
self.external_tailscale_dns_resolver = None
|
|
732
747
|
|
|
733
748
|
async def wait_for(self, available: bool, timeout: float):
|
|
734
749
|
self._sleepcounter = 0
|
|
@@ -737,25 +752,33 @@ class Funnel(Pingable):
|
|
|
737
752
|
async def ping(self, availability_hint: bool | None = None):
|
|
738
753
|
logger.debug("Resolving DNS for %s (%s:%s)", LazyStr(self.get_class_name), self.external_name, self.external_port)
|
|
739
754
|
# first try at Tailscale's DNSs, if they don't know, we should not resolve at a public DNS and cache nxdomain for 5 minutes
|
|
740
|
-
if self.
|
|
755
|
+
if self.external_tailscale_dns_resolver_addresses is None:
|
|
741
756
|
resolvers = [await self.local_tailscale.external_tailscale_dns_resolver()]
|
|
742
757
|
resolvers.extend(await self._external_tailscale_dns_resolvers())
|
|
743
|
-
self.
|
|
758
|
+
self.external_tailscale_dns_resolver_addresses = resolvers
|
|
759
|
+
resolver = self.external_tailscale_dns_resolver
|
|
760
|
+
if resolver is None:
|
|
761
|
+
resolver = ExternalDnsResolver(self.external_tailscale_dns_resolver_addresses[0])
|
|
744
762
|
try:
|
|
745
|
-
_answer = await
|
|
763
|
+
_answer = await resolver.resolve(self.external_name, self.external_port)
|
|
746
764
|
except Exception as e:
|
|
747
|
-
logger.debug("Resolving at Tailscale's external DNS %s has failed: %s", self.
|
|
765
|
+
logger.debug("Resolving at Tailscale's external DNS %s has failed: %s", self.external_tailscale_dns_resolver_addresses[0], LazyStr(exception_repr, e))
|
|
748
766
|
# move current resolver to the end of the list
|
|
749
|
-
self.
|
|
767
|
+
self.external_tailscale_dns_resolver_addresses.append(self.external_tailscale_dns_resolver_addresses.pop(0))
|
|
750
768
|
return False
|
|
769
|
+
self.external_tailscale_dns_resolver = resolver
|
|
751
770
|
# then try at a public DNS
|
|
752
|
-
if self.
|
|
753
|
-
self.
|
|
771
|
+
if self.external_public_dns_resolver_address is None:
|
|
772
|
+
self.external_public_dns_resolver_address = await self.local_tailscale.external_public_dns_resolver()
|
|
773
|
+
resolver = self.external_public_dns_resolver
|
|
774
|
+
if resolver is None:
|
|
775
|
+
resolver = ExternalDnsResolver(self.external_public_dns_resolver_address)
|
|
754
776
|
try:
|
|
755
|
-
_answer = await
|
|
777
|
+
_answer = await resolver.resolve(self.external_name, self.external_port)
|
|
756
778
|
except Exception as e:
|
|
757
779
|
logger.debug("Resolving at public external DNS has failed: %s", LazyStr(exception_repr, e))
|
|
758
780
|
return False
|
|
781
|
+
self.external_public_dns_resolver = resolver
|
|
759
782
|
return True
|
|
760
783
|
|
|
761
784
|
async def _sleep_while_wait(self, available: bool):
|
|
@@ -1158,9 +1181,11 @@ class Control:
|
|
|
1158
1181
|
|
|
1159
1182
|
@staticmethod
|
|
1160
1183
|
def prepare(args: argparse.Namespace):
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
logger.
|
|
1184
|
+
Logger.setConfiguration(args.timestamp or args.debug)
|
|
1185
|
+
logging.setLoggerClass(Logger)
|
|
1186
|
+
logger.setConfiguration(
|
|
1187
|
+
logging.DEBUG if args.debug else logging.WARNING if args.silent else logging.INFO) #NOSONAR(S3358)
|
|
1188
|
+
logger.configure()
|
|
1164
1189
|
|
|
1165
1190
|
if args.accept_cellular and args.intent != 'start':
|
|
1166
1191
|
raise ValueError("The --accept-cellular options can be enabled only for the start intent")
|
|
@@ -3,7 +3,7 @@ packages = [{include = "prim_ctrl"}]
|
|
|
3
3
|
|
|
4
4
|
[project]
|
|
5
5
|
name = "prim-ctrl"
|
|
6
|
-
version = "0.8.
|
|
6
|
+
version = "0.8.5"
|
|
7
7
|
description = "Primitive Ctrl - Remote control of your phone's Primitive FTPd Android SFTP server and optionally Tailscale VPN."
|
|
8
8
|
license = "Apache-2.0"
|
|
9
9
|
authors = [
|
|
File without changes
|
|
File without changes
|
|
File without changes
|