536 lines
23 KiB
Diff
536 lines
23 KiB
Diff
From 94f6109dfcc34952b00179526b84a6d82eb24e34 Mon Sep 17 00:00:00 2001
|
|
From: cgarz <20268068+cgarz@users.noreply.github.com>
|
|
Date: Fri, 31 Jan 2025 06:06:00 +0000
|
|
Subject: [PATCH 01/16] added replacement read_until and leftover buffer
|
|
|
|
---
|
|
scripts/python/module/PyNUT.py.in | 14 ++++++++++++++
|
|
1 file changed, 14 insertions(+)
|
|
|
|
diff --git a/scripts/python/module/PyNUT.py.in b/scripts/python/module/PyNUT.py.in
|
|
index 6838fc373a..484df8b25a 100644
|
|
--- a/scripts/python/module/PyNUT.py.in
|
|
+++ b/scripts/python/module/PyNUT.py.in
|
|
@@ -84,6 +84,7 @@ class PyNUTClient :
|
|
__password = None
|
|
__timeout = None
|
|
__srv_handler = None
|
|
+ __recv_leftover = b''
|
|
|
|
__version = "1.6.0"
|
|
__release = "2023-01-18"
|
|
@@ -122,6 +123,19 @@ timeout : Timeout used to wait for network response
|
|
except :
|
|
pass
|
|
|
|
+ def __read_until(self, finished_reading_data):
|
|
+ data = self.__recv_leftover
|
|
+ while (data_end_index := data.find(finished_reading_data)) == -1:
|
|
+ data += self.__srv_handler.recv(50) # nut_telnetlib.py uses 50
|
|
+ data_end_index += len(finished_reading_data)
|
|
+
|
|
+ if data_end_index == len(data):
|
|
+ self.__recv_leftover = b''
|
|
+ else:
|
|
+ self.__recv_leftover = data[data_end_index:]
|
|
+ data = data[:data_end_index]
|
|
+ return data
|
|
+
|
|
def __connect( self ) :
|
|
""" Connects to the defined server
|
|
|
|
|
|
From 60a7ca19a87491be7b58f693977ea5a365290842 Mon Sep 17 00:00:00 2001
|
|
From: cgarz <20268068+cgarz@users.noreply.github.com>
|
|
Date: Fri, 31 Jan 2025 06:14:33 +0000
|
|
Subject: [PATCH 02/16] switch to socket send and replacement read_until
|
|
|
|
---
|
|
scripts/python/module/PyNUT.py.in | 107 ++++++++++++++----------------
|
|
1 file changed, 51 insertions(+), 56 deletions(-)
|
|
|
|
diff --git a/scripts/python/module/PyNUT.py.in b/scripts/python/module/PyNUT.py.in
|
|
index 484df8b25a..18f43954ca 100644
|
|
--- a/scripts/python/module/PyNUT.py.in
|
|
+++ b/scripts/python/module/PyNUT.py.in
|
|
@@ -55,8 +55,16 @@
|
|
# 2023-01-18 Jim Klimov <jimklimov+nut@gmail.com> - Version 1.6.0
|
|
# Added CheckUPSAvailable() method originally by Michal Hlavinka
|
|
# from 2013-01-07 RedHat/Fedora packaging
|
|
+#
|
|
+# 2024-07-01 Jim Klimov <jimklimov+nut@gmail.com> - Version 1.7.0
|
|
+# Re-arranged dependency on telnetlib module (deprecated/removed
|
|
+# since Python 3.11/3.13), so we can fall back on a privately
|
|
+# stashed copy until a better solution is developed.
|
|
+#
|
|
+# 2025-01-31 cgar <github.com/cgarz> - Version 1.8.0
|
|
+# Removed telnetlib dependency. Switched to using socket directly.
|
|
|
|
-import telnetlib
|
|
+import socket
|
|
|
|
class PyNUTError( Exception ) :
|
|
""" Base class for custom exceptions """
|
|
@@ -119,7 +113,7 @@ timeout : Timeout used to wait for network response
|
|
def __del__( self ) :
|
|
""" Class destructor method """
|
|
try :
|
|
- self.__srv_handler.write( b"LOGOUT\n" )
|
|
+ self.__srv_handler.send( b"LOGOUT\n" )
|
|
except :
|
|
pass
|
|
|
|
@@ -145,23 +139,24 @@ if something goes wrong.
|
|
if self.__debug :
|
|
print( "[DEBUG] Connecting to host" )
|
|
|
|
- self.__srv_handler = telnetlib.Telnet( self.__host, self.__port )
|
|
+ self.__srv_handler = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
|
+ self.__srv_handler.connect( (self.__host, self.__port) )
|
|
|
|
if self.__login != None :
|
|
- self.__srv_handler.write( ("USERNAME %s\n" % self.__login).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n", self.__timeout )
|
|
+ self.__srv_handler.send( ("USERNAME %s\n" % self.__login).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if result[:2] != b"OK" :
|
|
raise PyNUTError( result.replace( b"\n", b"" ).decode('ascii') )
|
|
|
|
if self.__password != None :
|
|
- self.__srv_handler.write( ("PASSWORD %s\n" % self.__password).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n", self.__timeout )
|
|
+ self.__srv_handler.send( ("PASSWORD %s\n" % self.__password).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if result[:2] != b"OK" :
|
|
if result == b"ERR INVALID-ARGUMENT\n" :
|
|
# Quote the password (if it has whitespace etc)
|
|
# TODO: Escape special chard like NUT does?
|
|
- self.__srv_handler.write( ("PASSWORD \"%s\"\n" % self.__password).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n", self.__timeout )
|
|
+ self.__srv_handler.send( ("PASSWORD \"%s\"\n" % self.__password).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if result[:2] != b"OK" :
|
|
raise PyNUTError( result.replace( b"\n", b"" ).decode('ascii') )
|
|
else:
|
|
@@ -179,12 +174,12 @@ which is of little concern for Python2 but is important in Python3
|
|
if self.__debug :
|
|
print( "[DEBUG] GetUPSList from server" )
|
|
|
|
- self.__srv_handler.write( b"LIST UPS\n" )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
- if result != b"BEGIN LIST UPS\n" :
|
|
+ self.__srv_handler.send( b"LIST UPS\n" )
|
|
+ result = self.__read_until( b"\n" )
|
|
+ if result != b"BEGIN LIST UPS\n":
|
|
raise PyNUTError( result.replace( b"\n", b"" ).decode('ascii') )
|
|
|
|
- result = self.__srv_handler.read_until( b"END LIST UPS\n" )
|
|
+ result = self.__read_until( b"END LIST UPS\n" )
|
|
ups_list = {}
|
|
|
|
for line in result.split( b"\n" ) :
|
|
@@ -219,13 +214,13 @@ available vars.
|
|
if self.__debug :
|
|
print( "[DEBUG] GetUPSVars called..." )
|
|
|
|
- self.__srv_handler.write( ("LIST VAR %s\n" % ups).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("LIST VAR %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if result != ("BEGIN LIST VAR %s\n" % ups).encode('ascii') :
|
|
raise PyNUTError( result.replace( b"\n", b"" ).decode('ascii') )
|
|
|
|
ups_vars = {}
|
|
- result = self.__srv_handler.read_until( ("END LIST VAR %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( ("END LIST VAR %s\n" % ups).encode('ascii') )
|
|
offset = len( ("VAR %s " % ups ).encode('ascii') )
|
|
end_offset = 0 - ( len( ("END LIST VAR %s\n" % ups).encode('ascii') ) + 1 )
|
|
|
|
@@ -245,12 +240,12 @@ The result is True (reachable) or False (unreachable)
|
|
if self.__debug :
|
|
print( "[DEBUG] CheckUPSAvailable called..." )
|
|
|
|
- self.__srv_handler.write( ("LIST CMD %s\n" % ups).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("LIST CMD %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if result != ("BEGIN LIST CMD %s\n" % ups).encode('ascii') :
|
|
return False
|
|
|
|
- self.__srv_handler.read_until( ("END LIST CMD %s\n" % ups).encode('ascii') )
|
|
+ self.__read_until( ("END LIST CMD %s\n" % ups).encode('ascii') )
|
|
return True
|
|
|
|
def GetUPSCommands( self, ups="" ) :
|
|
@@ -262,13 +257,13 @@ of the command as value
|
|
if self.__debug :
|
|
print( "[DEBUG] GetUPSCommands called..." )
|
|
|
|
- self.__srv_handler.write( ("LIST CMD %s\n" % ups).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("LIST CMD %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if result != ("BEGIN LIST CMD %s\n" % ups).encode('ascii') :
|
|
raise PyNUTError( result.replace( b"\n", b"" ).decode('ascii') )
|
|
|
|
ups_cmds = {}
|
|
- result = self.__srv_handler.read_until( ("END LIST CMD %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( ("END LIST CMD %s\n" % ups).encode('ascii') )
|
|
offset = len( ("CMD %s " % ups).encode('ascii') )
|
|
end_offset = 0 - ( len( ("END LIST CMD %s\n" % ups).encode('ascii') ) + 1 )
|
|
|
|
@@ -277,8 +272,8 @@ of the command as value
|
|
|
|
# For each var we try to get the available description
|
|
try :
|
|
- self.__srv_handler.write( ("GET CMDDESC %s %s\n" % ( ups, var )).encode('ascii') )
|
|
- temp = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("GET CMDDESC %s %s\n" % ( ups, var )).encode('ascii') )
|
|
+ temp = self.__read_until( b"\n" )
|
|
if temp[:7] != b"CMDDESC" :
|
|
raise PyNUTError
|
|
else :
|
|
@@ -299,12 +294,12 @@ The result is presented as a dictionary containing 'key->val' pairs
|
|
if self.__debug :
|
|
print( "[DEBUG] GetUPSVars from '%s'..." % ups )
|
|
|
|
- self.__srv_handler.write( ("LIST RW %s\n" % ups).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("LIST RW %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if ( result != ("BEGIN LIST RW %s\n" % ups).encode('ascii') ) :
|
|
raise PyNUTError( result.replace( b"\n", b"" ).decode('ascii') )
|
|
|
|
- result = self.__srv_handler.read_until( ("END LIST RW %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( ("END LIST RW %s\n" % ups).encode('ascii') )
|
|
offset = len( ("VAR %s" % ups).encode('ascii') )
|
|
end_offset = 0 - ( len( ("END LIST RW %s\n" % ups).encode('ascii') ) + 1 )
|
|
rw_vars = {}
|
|
@@ -327,8 +322,8 @@ The variable must be a writable value (cf GetRWVars) and you must have the prope
|
|
rights to set it (maybe login/password).
|
|
"""
|
|
|
|
- self.__srv_handler.write( ("SET VAR %s %s %s\n" % ( ups, var, value )).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("SET VAR %s %s %s\n" % ( ups, var, value )).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if ( result == b"OK\n" ) :
|
|
return( "OK" )
|
|
else :
|
|
@@ -343,8 +338,8 @@ Returns OK on success or raises an error
|
|
if self.__debug :
|
|
print( "[DEBUG] RunUPSCommand called..." )
|
|
|
|
- self.__srv_handler.write( ("INSTCMD %s %s\n" % ( ups, command )).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("INSTCMD %s %s\n" % ( ups, command )).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if ( result == b"OK\n" ) :
|
|
return( "OK" )
|
|
else :
|
|
@@ -369,12 +364,12 @@ of connection.
|
|
print( "[DEBUG] DeviceLogin: %s is not a valid UPS" % ups )
|
|
raise PyNUTError( "ERR UNKNOWN-UPS" )
|
|
|
|
- self.__srv_handler.write( ("LOGIN %s\n" % ups).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("LOGIN %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if ( result.startswith( ("User %s@" % self.__login).encode('ascii')) and result.endswith (("[%s]\n" % ups).encode('ascii')) ):
|
|
# User dummy-user@127.0.0.1 logged into UPS [dummy]
|
|
# Read next line then
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ result = self.__read_until( b"\n" )
|
|
if ( result == b"OK\n" ) :
|
|
return( "OK" )
|
|
else :
|
|
@@ -392,13 +387,13 @@ NOTE: API changed since NUT 2.8.0 to replace MASTER with PRIMARY
|
|
if self.__debug :
|
|
print( "[DEBUG] PRIMARY called..." )
|
|
|
|
- self.__srv_handler.write( ("PRIMARY %s\n" % ups).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("PRIMARY %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if ( result != b"OK PRIMARY-GRANTED\n" ) :
|
|
if self.__debug :
|
|
print( "[DEBUG] Retrying: MASTER called..." )
|
|
- self.__srv_handler.write( ("MASTER %s\n" % ups).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("MASTER %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if ( result != b"OK MASTER-GRANTED\n" ) :
|
|
if self.__debug :
|
|
print( "[DEBUG] Primary level functions are not available" )
|
|
@@ -406,8 +401,8 @@ NOTE: API changed since NUT 2.8.0 to replace MASTER with PRIMARY
|
|
|
|
if self.__debug :
|
|
print( "[DEBUG] FSD called..." )
|
|
- self.__srv_handler.write( ("FSD %s\n" % ups).encode('ascii') )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( ("FSD %s\n" % ups).encode('ascii') )
|
|
+ result = self.__read_until( b"\n" )
|
|
if ( result == b"OK FSD-SET\n" ) :
|
|
return( "OK" )
|
|
else :
|
|
@@ -420,8 +415,8 @@ NOTE: API changed since NUT 2.8.0 to replace MASTER with PRIMARY
|
|
if self.__debug :
|
|
print( "[DEBUG] HELP called..." )
|
|
|
|
- self.__srv_handler.write( b"HELP\n" )
|
|
- return self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( b"HELP\n" )
|
|
+ return self.__read_until( b"\n" )
|
|
|
|
def ver(self) :
|
|
""" Send VER command
|
|
@@ -430,8 +425,8 @@ NOTE: API changed since NUT 2.8.0 to replace MASTER with PRIMARY
|
|
if self.__debug :
|
|
print( "[DEBUG] VER called..." )
|
|
|
|
- self.__srv_handler.write( b"VER\n" )
|
|
- return self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( b"VER\n" )
|
|
+ return self.__read_until( b"\n" )
|
|
|
|
def ListClients( self, ups = None ) :
|
|
""" Returns the list of connected clients from the NUT server
|
|
@@ -449,12 +444,12 @@ The result is a dictionary containing 'key->val' pairs of 'UPSName' and a list o
|
|
raise PyNUTError( "ERR UNKNOWN-UPS" )
|
|
|
|
if ups:
|
|
- self.__srv_handler.write( ("LIST CLIENT %s\n" % ups).encode('ascii') )
|
|
+ self.__srv_handler.send( ("LIST CLIENT %s\n" % ups).encode('ascii') )
|
|
else:
|
|
# NOTE: Currently NUT does not support just listing all clients
|
|
# (not providing an "ups" argument) => NUT_ERR_INVALID_ARGUMENT
|
|
- self.__srv_handler.write( b"LIST CLIENT\n" )
|
|
- result = self.__srv_handler.read_until( b"\n" )
|
|
+ self.__srv_handler.send( b"LIST CLIENT\n" )
|
|
+ result = self.__read_until( b"\n" )
|
|
if ( (ups and result != ("BEGIN LIST CLIENT %s\n" % ups).encode('ascii')) or (ups is None and result != b"BEGIN LIST CLIENT\n") ):
|
|
if ups is None and (result == b"ERR INVALID-ARGUMENT\n") :
|
|
# For ups==None, list all upses, list their clients
|
|
@@ -472,11 +467,11 @@ The result is a dictionary containing 'key->val' pairs of 'UPSName' and a list o
|
|
|
|
raise PyNUTError( result.replace( b"\n", b"" ).decode('ascii') )
|
|
|
|
- if ups :
|
|
- result = self.__srv_handler.read_until( ("END LIST CLIENT %s\n" % ups).encode('ascii') )
|
|
+ if ups:
|
|
+ result = self.__read_until( ("END LIST CLIENT %s\n" % ups).encode('ascii') )
|
|
else:
|
|
# Should not get here with current NUT:
|
|
- result = self.__srv_handler.read_until( b"END LIST CLIENT\n" )
|
|
+ result = self.__read_until( b"END LIST CLIENT\n" )
|
|
ups_list = {}
|
|
|
|
for line in result.split( b"\n" ):
|
|
|
|
From 1209078c62ad4b6138029f59b33dff4008235ad5 Mon Sep 17 00:00:00 2001
|
|
From: cgarz <20268068+cgarz@users.noreply.github.com>
|
|
Date: Fri, 31 Jan 2025 06:19:16 +0000
|
|
Subject: [PATCH 03/16] Switch to socket timeout, fix its init argument
|
|
|
|
---
|
|
scripts/python/module/PyNUT.py.in | 3 ++-
|
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/scripts/python/module/PyNUT.py.in b/scripts/python/module/PyNUT.py.in
|
|
index 18f43954ca..66e4b6c0d6 100644
|
|
--- a/scripts/python/module/PyNUT.py.in
|
|
+++ b/scripts/python/module/PyNUT.py.in
|
|
@@ -105,7 +105,7 @@ timeout : Timeout used to wait for network response
|
|
self.__port = port
|
|
self.__login = login
|
|
self.__password = password
|
|
- self.__timeout = 5
|
|
+ self.__timeout = timeout
|
|
|
|
self.__connect()
|
|
|
|
@@ -141,6 +141,7 @@ if something goes wrong.
|
|
|
|
self.__srv_handler = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
|
self.__srv_handler.connect( (self.__host, self.__port) )
|
|
+ self.__srv_handler.settimeout( self.__timeout )
|
|
|
|
if self.__login != None :
|
|
self.__srv_handler.send( ("USERNAME %s\n" % self.__login).encode('ascii') )
|
|
|
|
From 7ee628f920bd11dd5565b0e10cbfa6fd54aa23c8 Mon Sep 17 00:00:00 2001
|
|
From: cgarz <20268068+cgarz@users.noreply.github.com>
|
|
Date: Tue, 4 Feb 2025 22:27:01 +0000
|
|
Subject: [PATCH 04/16] Remove walrus op for older python compatibility.
|
|
|
|
---
|
|
scripts/python/module/PyNUT.py.in | 8 ++++++--
|
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/scripts/python/module/PyNUT.py.in b/scripts/python/module/PyNUT.py.in
|
|
index 66e4b6c0d6..ced5231193 100644
|
|
--- a/scripts/python/module/PyNUT.py.in
|
|
+++ b/scripts/python/module/PyNUT.py.in
|
|
@@ -119,8 +119,12 @@ timeout : Timeout used to wait for network response
|
|
|
|
def __read_until(self, finished_reading_data):
|
|
data = self.__recv_leftover
|
|
- while (data_end_index := data.find(finished_reading_data)) == -1:
|
|
- data += self.__srv_handler.recv(50) # nut_telnetlib.py uses 50
|
|
+ while True:
|
|
+ data_end_index = data.find(finished_reading_data)
|
|
+ if data_end_index == -1:
|
|
+ data += self.__srv_handler.recv(50) # nut_telnetlib.py uses 50
|
|
+ else:
|
|
+ break
|
|
data_end_index += len(finished_reading_data)
|
|
|
|
if data_end_index == len(data):
|
|
|
|
From 9f81e81af3f8bed3fb1e501b5c0b8f638f28f125 Mon Sep 17 00:00:00 2001
|
|
From: cgarz <20268068+cgarz@users.noreply.github.com>
|
|
Date: Fri, 7 Feb 2025 08:45:40 +0000
|
|
Subject: [PATCH 05/16] Use socket create_connection instead of connect,
|
|
Handles choosing IPv4 and IPv6 automatically.
|
|
|
|
---
|
|
scripts/python/module/PyNUT.py.in | 7 ++++---
|
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/scripts/python/module/PyNUT.py.in b/scripts/python/module/PyNUT.py.in
|
|
index ced5231193..b815c4af73 100644
|
|
--- a/scripts/python/module/PyNUT.py.in
|
|
+++ b/scripts/python/module/PyNUT.py.in
|
|
@@ -143,9 +143,10 @@ if something goes wrong.
|
|
if self.__debug :
|
|
print( "[DEBUG] Connecting to host" )
|
|
|
|
- self.__srv_handler = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
|
- self.__srv_handler.connect( (self.__host, self.__port) )
|
|
- self.__srv_handler.settimeout( self.__timeout )
|
|
+ self.__srv_handler = socket.create_connection(
|
|
+ (self.__host, self.__port),
|
|
+ self.__timeout
|
|
+ )
|
|
|
|
if self.__login != None :
|
|
self.__srv_handler.send( ("USERNAME %s\n" % self.__login).encode('ascii') )
|
|
|
|
From cf0ea3e447f3d97237ba8575202437a59355bd3a Mon Sep 17 00:00:00 2001
|
|
From: cgarz <20268068+cgarz@users.noreply.github.com>
|
|
Date: Fri, 7 Feb 2025 08:47:38 +0000
|
|
Subject: [PATCH 06/16] Update PyNUT changelog, bump version to 1.8.0
|
|
|
|
---
|
|
scripts/python/module/PyNUT.py.in | 6 ++++--
|
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/scripts/python/module/PyNUT.py.in b/scripts/python/module/PyNUT.py.in
|
|
index b815c4af73..0e136d3669 100644
|
|
--- a/scripts/python/module/PyNUT.py.in
|
|
+++ b/scripts/python/module/PyNUT.py.in
|
|
@@ -74,8 +82,8 @@ class PyNUTClient :
|
|
__srv_handler = None
|
|
__recv_leftover = b''
|
|
|
|
- __version = "1.6.0"
|
|
- __release = "2023-01-18"
|
|
+ __version = "1.8.0"
|
|
+ __release = "2025-02-07"
|
|
|
|
|
|
def __init__( self, host="127.0.0.1", port=3493, login=None, password=None, debug=False, timeout=5 ) :
|
|
|
|
|
|
From 0488ec573943468fb0e0570c396b66c2dfcc35d9 Mon Sep 17 00:00:00 2001
|
|
From: cgarz <20268068+cgarz@users.noreply.github.com>
|
|
Date: Fri, 7 Feb 2025 08:57:21 +0000
|
|
Subject: [PATCH 12/16] Update setup.py.in, remove install_requires lib
|
|
|
|
---
|
|
scripts/python/module/setup.py.in | 5 -----
|
|
1 file changed, 5 deletions(-)
|
|
|
|
diff --git a/scripts/python/module/setup.py.in b/scripts/python/module/setup.py.in
|
|
index 10ada3ecd6..d520c960f9 100644
|
|
--- a/scripts/python/module/setup.py.in
|
|
+++ b/scripts/python/module/setup.py.in
|
|
@@ -30,7 +30,6 @@ setup(
|
|
#data_files = [('', ['tox.ini'])],
|
|
#scripts = ['PyNUTClient/test_nutclient.py', 'PyNUTClient/__init__.py'],
|
|
python_requires = '>=2.6',
|
|
- # install_requires = ['telnetlib'], # NOTE: telnetlib.py is part of Python core for tested 2.x and 3.x versions, not something 'pip' can download
|
|
keywords = ['pypi', 'cicd', 'python', 'nut', 'Network UPS Tools'],
|
|
classifiers = [
|
|
"Development Status :: 5 - Production/Stable",
|
|
|
|
From 6d671b039e6df10091f6219ed9ae7169bf25c6e5 Mon Sep 17 00:00:00 2001
|
|
From: Jim Klimov <jimklimov+nut@gmail.com>
|
|
Date: Fri, 7 Feb 2025 12:24:14 +0100
|
|
Subject: [PATCH 14/16] configure.ac: restore nut_with_pynut_py* checks from
|
|
v2.8.2, but test for "socket" instead of "telnetlib" module [#2183]
|
|
|
|
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
|
|
---
|
|
configure.ac | 38 ++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 38 insertions(+)
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 07febb3cb8..8d278d8085 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -2384,7 +2384,7 @@ if test x"${nut_with_pynut}" != xno \
|
|
if test -n "${PYTHON2}" \
|
|
&& (command -v ${PYTHON2} || which ${PYTHON2}) >/dev/null 2>/dev/null \
|
|
; then
|
|
- if ${PYTHON2} -c "import telnetlib" \
|
|
+ if ${PYTHON2} -c "import socket" \
|
|
; then
|
|
nut_with_pynut_py2="yes"
|
|
fi
|
|
@@ -2393,7 +2393,7 @@ if test x"${nut_with_pynut}" != xno \
|
|
if test -n "${PYTHON3}" \
|
|
&& (command -v ${PYTHON3} || which ${PYTHON3}) >/dev/null 2>/dev/null \
|
|
; then
|
|
- if ${PYTHON3} -c "import telnetlib" \
|
|
+ if ${PYTHON3} -c "import socket" \
|
|
; then
|
|
nut_with_pynut_py3="yes"
|
|
fi
|
|
@@ -2404,7 +2404,7 @@ if test x"${nut_with_pynut}" != xno \
|
|
&& (command -v ${PYTHON} || which ${PYTHON}) >/dev/null 2>/dev/null \
|
|
&& test "${PYTHON}" != "${PYTHON2}" -a "${PYTHON}" != "${PYTHON3}" \
|
|
; then
|
|
- if ${PYTHON} -c "import telnetlib" \
|
|
+ if ${PYTHON} -c "import socket" \
|
|
; then
|
|
nut_with_pynut_py="yes"
|
|
fi
|
|
|
|
From c5540c43d28d7bfcae9426b92a44a805d7ac27bd Mon Sep 17 00:00:00 2001
|
|
From: Jim Klimov <jimklimov+nut@gmail.com>
|
|
Date: Fri, 7 Feb 2025 15:32:34 +0100
|
|
Subject: [PATCH 16/16] tests/NIT/nit.sh: update comment about use of two
|
|
explicit localhost IPv4/6 addresses, not a name, for upsd.conf
|
|
|
|
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
|
|
---
|
|
tests/NIT/nit.sh | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/tests/NIT/nit.sh b/tests/NIT/nit.sh
|
|
index befec52803..cf0a98bb7f 100755
|
|
--- a/tests/NIT/nit.sh
|
|
+++ b/tests/NIT/nit.sh
|
|
@@ -363,8 +363,8 @@ EOF
|
|
fi
|
|
|
|
# Some systems listining on symbolic "localhost" actually
|
|
- # only bind to IPv6, and Python telnetlib resolves IPv4
|
|
- # and fails its connection tests. Others fare well with
|
|
+ # only bind to IPv6, and some (Python) client might resolve
|
|
+ # IPv4 and fail its connection tests. Others fare well with
|
|
# both addresses in one command.
|
|
for LH in 127.0.0.1 '::1' ; do
|
|
if (
|