From 80ec17183ef444751ad40a77ac5e5f3a84f76c69 Mon Sep 17 00:00:00 2001 From: Arturo Date: Tue, 18 Oct 2022 15:22:54 -0400 Subject: [PATCH 1/3] :sparkles:(issue-150) additional connect_data --- zk/base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zk/base.py b/zk/base.py index e4aa247..078ac0e 100644 --- a/zk/base.py +++ b/zk/base.py @@ -356,7 +356,7 @@ def __encode_time(self, t): ) return d - def connect(self): + def connect(self, connect_data=b''): """ connect to the device @@ -370,7 +370,7 @@ def connect(self): self.__create_socket() self.__session_id = 0 self.__reply_id = const.USHRT_MAX - 1 - cmd_response = self.__send_command(const.CMD_CONNECT) + cmd_response = self.__send_command(const.CMD_CONNECT, connect_data) self.__session_id = self.__header[2] if cmd_response.get('code') == const.CMD_ACK_UNAUTH: if self.verbose: print ("try auth") From 1979cf5ad678df124e3ea12939d3f9b3b0ca74e7 Mon Sep 17 00:00:00 2001 From: Arturo Date: Tue, 18 Oct 2022 16:46:05 -0400 Subject: [PATCH 2/3] :bug:(issue-150) add recv retry --- zk/base.py | 958 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 596 insertions(+), 362 deletions(-) diff --git a/zk/base.py b/zk/base.py index 078ac0e..fbaab87 100644 --- a/zk/base.py +++ b/zk/base.py @@ -13,7 +13,7 @@ def safe_cast(val, to_type, default=None): - #https://stackoverflow.com/questions/6330071/safe-casting-in-python + # https://stackoverflow.com/questions/6330071/safe-casting-in-python try: return to_type(val) except (ValueError, TypeError): @@ -29,31 +29,23 @@ def make_commkey(key, session_id, ticks=50): session_id = int(session_id) k = 0 for i in range(32): - if (key & (1 << i)): - k = (k << 1 | 1) + if key & (1 << i): + k = k << 1 | 1 else: k = k << 1 k += session_id - k = pack(b'I', k) - k = unpack(b'BBBB', k) + k = pack(b"I", k) + k = unpack(b"BBBB", k) k = pack( - b'BBBB', - k[0] ^ ord('Z'), - k[1] ^ ord('K'), - k[2] ^ ord('S'), - k[3] ^ ord('O')) - k = unpack(b'HH', k) - k = pack(b'HH', k[1], k[0]) - - B = 0xff & ticks - k = unpack(b'BBBB', k) - k = pack( - b'BBBB', - k[0] ^ B, - k[1] ^ B, - B, - k[3] ^ B) + b"BBBB", k[0] ^ ord("Z"), k[1] ^ ord("K"), k[2] ^ ord("S"), k[3] ^ ord("O") + ) + k = unpack(b"HH", k) + k = pack(b"HH", k[1], k[0]) + + B = 0xFF & ticks + k = unpack(b"BBBB", k) + k = pack(b"BBBB", k[0] ^ B, k[1] ^ B, B, k[3] ^ B) return k @@ -77,15 +69,18 @@ def test_ping(self): :return: bool """ import subprocess, platform + # Ping parameters as function of OS - ping_str = "-n 1" if platform.system().lower()=="windows" else "-c 1 -W 5" + ping_str = "-n 1" if platform.system().lower() == "windows" else "-c 1 -W 5" args = "ping " + " " + ping_str + " " + self.ip - need_sh = False if platform.system().lower()=="windows" else True + need_sh = False if platform.system().lower() == "windows" else True # Ping - return subprocess.call(args, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=need_sh) == 0 + return ( + subprocess.call( + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=need_sh + ) + == 0 + ) def test_tcp(self): """ @@ -110,7 +105,18 @@ class ZK(object): """ ZK main class """ - def __init__(self, ip, port=4370, timeout=60, password=0, force_udp=False, ommit_ping=False, verbose=False, encoding='UTF-8'): + + def __init__( + self, + ip, + port=4370, + timeout=60, + password=0, + force_udp=False, + ommit_ping=False, + verbose=False, + encoding="UTF-8", + ): """ Construct a new 'ZK' object. @@ -128,7 +134,7 @@ def __init__(self, ip, port=4370, timeout=60, password=0, force_udp=False, ommit self.__sock = socket(AF_INET, SOCK_DGRAM) self.__sock.settimeout(timeout) self.__timeout = timeout - self.__password = password # passint + self.__password = password # passint self.__session_id = 0 self.__reply_id = const.USHRT_MAX - 1 self.__data_recv = None @@ -156,8 +162,8 @@ def __init__(self, ip, port=4370, timeout=60, password=0, force_udp=False, ommit self.users_av = 0 self.rec_av = 0 self.next_uid = 1 - self.next_user_id='1' - self.user_packet_size = 28 # default zk6 + self.next_user_id = "1" + self.user_packet_size = 28 # default zk6 self.end_live_capture = False def __nonzero__(self): @@ -180,21 +186,23 @@ def __create_tcp_top(self, packet): witch the complete packet set top header """ length = len(packet) - top = pack('= const.USHRT_MAX: reply_id -= const.USHRT_MAX - buf = pack('<4H', command, checksum, session_id, reply_id) + buf = pack("<4H", command, checksum, session_id, reply_id) return buf + command_string def __create_checksum(self, p): @@ -205,7 +213,7 @@ def __create_checksum(self, p): l = len(p) checksum = 0 while l > 1: - checksum += unpack('H', pack('BB', p[0], p[1]))[0] + checksum += unpack("H", pack("BB", p[0], p[1]))[0] p = p[2:] if checksum > const.USHRT_MAX: checksum -= const.USHRT_MAX @@ -221,27 +229,34 @@ def __create_checksum(self, p): while checksum < 0: checksum += const.USHRT_MAX - return pack('H', checksum) + return pack("H", checksum) def __test_tcp_top(self, packet): """ return size! """ - if len(packet)<=8: + if len(packet) <= 8: + if self.verbose: + print("incomplete response? " + codecs.encode(packet, "hex")) return 0 - tcp_header = unpack('= 80: - fields = unpack('20i', self.__data[:80]) + fields = unpack("20i", self.__data[:80]) self.users = fields[4] self.fingers = fields[6] self.records = fields[8] - self.dummy = fields[10] #??? + self.dummy = fields[10] # ??? self.cards = fields[12] self.fingers_cap = fields[14] self.users_cap = fields[15] @@ -673,8 +703,10 @@ def read_sizes(self): self.users_av = fields[18] self.rec_av = fields[19] self.__data = self.__data[80:] - if len(self.__data) >= 12: #face info - fields = unpack('3i', self.__data[:12]) #dirty hack! we need more information + if len(self.__data) >= 12: # face info + fields = unpack( + "3i", self.__data[:12] + ) # dirty hack! we need more information self.faces = fields[0] self.faces_cap = fields[2] return True @@ -690,20 +722,21 @@ def unlock(self, time=3): :return: bool """ command = const.CMD_UNLOCK - command_string = pack("I",int(time)*10) + command_string = pack("I", int(time) * 10) cmd_response = self.__send_command(command, command_string) - if cmd_response.get('status'): + if cmd_response.get("status"): return True else: raise ZKErrorResponse("Can't open door") + def get_lock_state(self): - ''' + """ :return: boolean thanks to https://github.com/icarome/pyzk/ - ''' + """ command = const.CMD_DOORSTATE_RRQ cmd_response = self.__send_command(command) - if cmd_response.get('status'): + if cmd_response.get("status"): return True else: return False @@ -712,12 +745,22 @@ def __str__(self): """ for debug """ - return "ZK %s://%s:%s users[%i]:%i/%i fingers:%i/%i, records:%i/%i faces:%i/%i" % ( - "tcp" if self.tcp else "udp", self.__address[0], self.__address[1], - self.user_packet_size, self.users, self.users_cap, - self.fingers, self.fingers_cap, - self.records, self.rec_cap, - self.faces, self.faces_cap + return ( + "ZK %s://%s:%s users[%i]:%i/%i fingers:%i/%i, records:%i/%i faces:%i/%i" + % ( + "tcp" if self.tcp else "udp", + self.__address[0], + self.__address[1], + self.user_packet_size, + self.users, + self.users_cap, + self.fingers, + self.fingers_cap, + self.records, + self.rec_cap, + self.faces, + self.faces_cap, + ) ) def restart(self): @@ -728,7 +771,7 @@ def restart(self): """ command = const.CMD_RESTART cmd_response = self.__send_command(command) - if cmd_response.get('status'): + if cmd_response.get("status"): self.is_connect = False self.next_uid = 1 return True @@ -742,9 +785,13 @@ def write_lcd(self, line_number, text): :param text: text to write """ command = const.CMD_WRITE_LCD - command_string = pack(b'= 28: - uid, privilege, password, name, card, group_id, timezone, user_id = unpack(' max_uid: max_uid = uid - password = (password.split(b'\x00')[0]).decode(self.encoding, errors='ignore') - name = (name.split(b'\x00')[0]).decode(self.encoding, errors='ignore').strip() + ( + uid, + privilege, + password, + name, + card, + group_id, + timezone, + user_id, + ) = unpack(" max_uid: + max_uid = uid + password = (password.split(b"\x00")[0]).decode( + self.encoding, errors="ignore" + ) + name = ( + (name.split(b"\x00")[0]) + .decode(self.encoding, errors="ignore") + .strip() + ) group_id = str(group_id) user_id = str(user_id) - #TODO: check card value and find in ver8 + # TODO: check card value and find in ver8 if not name: name = "NN-%s" % user_id user = User(uid, name, privilege, password, group_id, user_id, card) users.append(user) - if self.verbose: print("[6]user:",uid, privilege, password, name, card, group_id, timezone, user_id) + if self.verbose: + print( + "[6]user:", + uid, + privilege, + password, + name, + card, + group_id, + timezone, + user_id, + ) userdata = userdata[28:] else: while len(userdata) >= 72: - uid, privilege, password, name, card, group_id, user_id = unpack(' max_uid: max_uid = uid + uid, privilege, password, name, card, group_id, user_id = unpack( + " max_uid: + max_uid = uid if not name: name = "NN-%s" % user_id user = User(uid, name, privilege, password, group_id, user_id, card) @@ -1170,7 +1305,7 @@ def cancel_capture(self): """ command = const.CMD_CANCELCAPTURE cmd_response = self.__send_command(command) - return bool(cmd_response.get('status')) + return bool(cmd_response.get("status")) def verify_user(self): """ @@ -1180,7 +1315,7 @@ def verify_user(self): """ command = const.CMD_STARTVERIFY cmd_response = self.__send_command(command) - if cmd_response.get('status'): + if cmd_response.get("status"): return True else: raise ZKErrorResponse("Cant Verify") @@ -1190,20 +1325,20 @@ def reg_event(self, flags): reg events """ command = const.CMD_REG_EVENT - command_string = pack ("I", flags) + command_string = pack("I", flags) cmd_response = self.__send_command(command, command_string) - if not cmd_response.get('status'): + if not cmd_response.get("status"): raise ZKErrorResponse("cant' reg events %i" % flags) def set_sdk_build_1(self): command = const.CMD_OPTIONS_WRQ command_string = b"SDKBuild=1" cmd_response = self.__send_command(command, command_string) - if not cmd_response.get('status'): + if not cmd_response.get("status"): return False return True - def enroll_user(self, uid=0, temp_id=0, user_id=''): + def enroll_user(self, uid=0, temp_id=0, user_id=""): """ start enroll user @@ -1214,86 +1349,105 @@ def enroll_user(self, uid=0, temp_id=0, user_id=''): """ command = const.CMD_STARTENROLL done = False - if not user_id: + if not user_id: users = self.get_users() - users = list(filter(lambda x: x.uid==uid, users)) + users = list(filter(lambda x: x.uid == uid, users)) if len(users) >= 1: user_id = users[0].user_id else: return False if self.tcp: - command_string = pack('<24sbb',str(user_id).encode(), temp_id, 1) + command_string = pack("<24sbb", str(user_id).encode(), temp_id, 1) else: - command_string = pack(' 16: - res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] - if self.verbose: print("res %i" % res) + res = unpack("H", data_recv.ljust(24, b"\x00")[16:18])[0] + if self.verbose: + print("res %i" % res) if res == 0 or res == 6 or res == 4: - if self.verbose: print ("posible timeout o reg Fallido") + if self.verbose: + print("posible timeout o reg Fallido") break else: if len(data_recv) > 8: - res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] - if self.verbose: print("res %i" % res) + res = unpack("H", data_recv.ljust(16, b"\x00")[8:10])[0] + if self.verbose: + print("res %i" % res) if res == 6 or res == 4: - if self.verbose: print ("posible timeout") + if self.verbose: + print("posible timeout") break - if self.verbose: print ("A:%i esperando 2do regevent" % attempts) + if self.verbose: + print("A:%i esperando 2do regevent" % attempts) data_recv = self.__sock.recv(1032) self.__ack_ok() - if self.verbose: print (codecs.encode(data_recv, 'hex')) + if self.verbose: + print(codecs.encode(data_recv, "hex")) if self.tcp: if len(data_recv) > 8: - res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] - if self.verbose: print("res %i" % res) + res = unpack("H", data_recv.ljust(24, b"\x00")[16:18])[0] + if self.verbose: + print("res %i" % res) if res == 6 or res == 4: - if self.verbose: print ("posible timeout o reg Fallido") + if self.verbose: + print("posible timeout o reg Fallido") break elif res == 0x64: - if self.verbose: print ("ok, continue?") + if self.verbose: + print("ok, continue?") attempts -= 1 else: if len(data_recv) > 8: - res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] - if self.verbose: print("res %i" % res) + res = unpack("H", data_recv.ljust(16, b"\x00")[8:10])[0] + if self.verbose: + print("res %i" % res) if res == 6 or res == 4: - if self.verbose: print ("posible timeout o reg Fallido") + if self.verbose: + print("posible timeout o reg Fallido") break elif res == 0x64: - if self.verbose: print ("ok, continue?") + if self.verbose: + print("ok, continue?") attempts -= 1 if attempts == 0: data_recv = self.__sock.recv(1032) self.__ack_ok() - if self.verbose: print (codecs.encode(data_recv, 'hex')) + if self.verbose: + print(codecs.encode(data_recv, "hex")) if self.tcp: - res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] + res = unpack("H", data_recv.ljust(24, b"\x00")[16:18])[0] else: - res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] - if self.verbose: print("res %i" % res) + res = unpack("H", data_recv.ljust(16, b"\x00")[8:10])[0] + if self.verbose: + print("res %i" % res) if res == 5: - if self.verbose: print ("finger duplicate") + if self.verbose: + print("finger duplicate") if res == 6 or res == 4: - if self.verbose: print ("posible timeout") - if res == 0: - size = unpack("H", data_recv.ljust(16,b"\x00")[10:12])[0] - pos = unpack("H", data_recv.ljust(16,b"\x00")[12:14])[0] - if self.verbose: print("enroll ok", size, pos) + if self.verbose: + print("posible timeout") + if res == 0: + size = unpack("H", data_recv.ljust(16, b"\x00")[10:12])[0] + pos = unpack("H", data_recv.ljust(16, b"\x00")[12:14])[0] + if self.verbose: + print("enroll ok", size, pos) done = True self.__sock.settimeout(self.__timeout) - self.reg_event(0) # TODO: test + self.reg_event(0) # TODO: test self.cancel_capture() self.verify_user() return done @@ -1308,46 +1462,54 @@ def live_capture(self, new_timeout=10): self.verify_user() if not self.is_enabled: self.enable_device() - if self.verbose: print ("start live_capture") + if self.verbose: + print("start live_capture") self.reg_event(const.EF_ATTLOG) self.__sock.settimeout(new_timeout) self.end_live_capture = False while not self.end_live_capture: try: - if self.verbose: print ("esperando event") + if self.verbose: + print("esperando event") data_recv = self.__sock.recv(1032) self.__ack_ok() if self.tcp: - size = unpack('= 12: if len(data) == 12: - user_id, status, punch, timehex = unpack('= 52: - user_id, status, punch, timehex, _other = unpack('<24sBB6s20s', data[:52]) + user_id, status, punch, timehex, _other = unpack( + "<24sBB6s20s", data[:52] + ) data = data[52:] if isinstance(user_id, int): user_id = str(user_id) else: - user_id = (user_id.split(b'\x00')[0]).decode(errors='ignore') + user_id = (user_id.split(b"\x00")[0]).decode(errors="ignore") timestamp = self.__decode_timehex(timehex) tuser = list(filter(lambda x: x.user_id == user_id, users)) if not tuser: @@ -1356,12 +1518,15 @@ def live_capture(self, new_timeout=10): uid = tuser[0].uid yield Attendance(user_id, timestamp, status, punch, uid) except timeout: - if self.verbose: print ("time out") - yield None # return to keep watching + if self.verbose: + print("time out") + yield None # return to keep watching except (KeyboardInterrupt, SystemExit): - if self.verbose: print ("break") + if self.verbose: + print("break") break - if self.verbose: print ("exit gracefully") + if self.verbose: + print("exit gracefully") self.__sock.settimeout(self.__timeout) self.reg_event(0) if not was_enabled: @@ -1374,96 +1539,124 @@ def clear_data(self): :return: bool """ command = const.CMD_CLEAR_DATA - command_string = b'' + command_string = b"" cmd_response = self.__send_command(command, command_string) - if cmd_response.get('status'): + if cmd_response.get("status"): self.next_uid = 1 return True else: raise ZKErrorResponse("can't clear data") def __recieve_tcp_data(self, data_recv, size): - """ data_recv, raw tcp packet - must analyze tcp_length + """data_recv, raw tcp packet + must analyze tcp_length - must return data, broken - """ + must return data, broken + """ data = [] tcp_length = self.__test_tcp_top(data_recv) - if self.verbose: print ("tcp_length {}, size {}".format(tcp_length, size)) + if self.verbose: + print("tcp_length {}, size {}".format(tcp_length, size)) if tcp_length <= 0: - if self.verbose: print ("Incorrect tcp packet") + if self.verbose: + print("Incorrect tcp packet") return None, b"" if (tcp_length - 8) < size: - if self.verbose: print ("tcp length too small... retrying") + if self.verbose: + print("tcp length too small... retrying") resp, bh = self.__recieve_tcp_data(data_recv, tcp_length - 8) data.append(resp) size -= len(resp) - if self.verbose: print ("new tcp DATA packet to fill misssing {}".format(size)) - data_recv = bh + self.__sock.recv(size + 16 ) - if self.verbose: print ("new tcp DATA starting with {} bytes".format(len(data_recv))) + if self.verbose: + print("new tcp DATA packet to fill misssing {}".format(size)) + data_recv = bh + self.__sock.recv(size + 16) + if self.verbose: + print("new tcp DATA starting with {} bytes".format(len(data_recv))) resp, bh = self.__recieve_tcp_data(data_recv, size) data.append(resp) - if self.verbose: print ("for misssing {} recieved {} with extra {}".format(size, len(resp), len(bh))) - return b''.join(data), bh + if self.verbose: + print( + "for misssing {} recieved {} with extra {}".format( + size, len(resp), len(bh) + ) + ) + return b"".join(data), bh recieved = len(data_recv) - if self.verbose: print ("recieved {}, size {}".format(recieved, size)) - response = unpack('HHHH', data_recv[8:16])[0] + if self.verbose: + print("recieved {}, size {}".format(recieved, size)) + response = unpack("HHHH", data_recv[8:16])[0] if recieved >= (size + 32): if response == const.CMD_DATA: resp = data_recv[16 : size + 16] - if self.verbose: print ("resp complete len {}".format(len(resp))) - return resp, data_recv[size + 16:] + if self.verbose: + print("resp complete len {}".format(len(resp))) + return resp, data_recv[size + 16 :] else: - if self.verbose: print("incorrect response!!! {}".format(response)) + if self.verbose: + print("incorrect response!!! {}".format(response)) return None, b"" else: - if self.verbose: print ("try DATA incomplete (actual valid {})".format(recieved-16)) - data.append(data_recv[16 : size + 16 ]) + if self.verbose: + print("try DATA incomplete (actual valid {})".format(recieved - 16)) + data.append(data_recv[16 : size + 16]) size -= recieved - 16 broken_header = b"" if size < 0: broken_header = data_recv[size:] - if self.verbose: print ("broken", (broken_header).encode('hex')) + if self.verbose: + print("broken", (broken_header).encode("hex")) if size > 0: data_recv = self.__recieve_raw_data(size) data.append(data_recv) - return b''.join(data), broken_header + return b"".join(data), broken_header def __recieve_raw_data(self, size): - """ partial data ? """ + """partial data ?""" data = [] - if self.verbose: print ("expecting {} bytes raw data".format(size)) + if self.verbose: + print("expecting {} bytes raw data".format(size)) while size > 0: data_recv = self.__sock.recv(size) recieved = len(data_recv) - if self.verbose: print ("partial recv {}".format(recieved)) - if recieved < 100 and self.verbose: print (" recv {}".format(codecs.encode(data_recv, 'hex'))) + if self.verbose: + print("partial recv {}".format(recieved)) + if recieved < 100 and self.verbose: + print(" recv {}".format(codecs.encode(data_recv, "hex"))) data.append(data_recv) size -= recieved - if self.verbose: print ("still need {}".format(size)) - return b''.join(data) + if self.verbose: + print("still need {}".format(size)) + return b"".join(data) def __recieve_chunk(self): - """ recieve a chunk """ + """recieve a chunk""" if self.__response == const.CMD_DATA: if self.tcp: - if self.verbose: print ("_rc_DATA! is {} bytes, tcp length is {}".format(len(self.__data), self.__tcp_length)) + if self.verbose: + print( + "_rc_DATA! is {} bytes, tcp length is {}".format( + len(self.__data), self.__tcp_length + ) + ) if len(self.__data) < (self.__tcp_length - 8): need = (self.__tcp_length - 8) - len(self.__data) - if self.verbose: print ("need more data: {}".format(need)) + if self.verbose: + print("need more data: {}".format(need)) more_data = self.__recieve_raw_data(need) - return b''.join([self.__data, more_data]) + return b"".join([self.__data, more_data]) else: - if self.verbose: print ("Enough data") + if self.verbose: + print("Enough data") return self.__data else: - if self.verbose: print ("_rc len is {}".format(len(self.__data))) + if self.verbose: + print("_rc len is {}".format(len(self.__data))) return self.__data elif self.__response == const.CMD_PREPARE_DATA: data = [] size = self.__get_data_size() - if self.verbose: print ("recieve chunk: prepare data size is {}".format(size)) + if self.verbose: + print("recieve chunk: prepare data size is {}".format(size)) if self.tcp: if len(self.__data) >= (8 + size): data_recv = self.__data[8:] @@ -1477,37 +1670,48 @@ def __recieve_chunk(self): else: data_recv = broken_header if len(data_recv) < 16: - print ("trying to complete broken ACK %s /16" % len(data_recv)) - if self.verbose: print (data_recv.encode('hex')) - data_recv += self.__sock.recv(16 - len(data_recv)) #TODO: CHECK HERE_! + print("trying to complete broken ACK %s /16" % len(data_recv)) + if self.verbose: + print(data_recv.encode("hex")) + data_recv += self.__sock.recv( + 16 - len(data_recv) + ) # TODO: CHECK HERE_! if not self.__test_tcp_top(data_recv): - if self.verbose: print ("invalid chunk tcp ACK OK") + if self.verbose: + print("invalid chunk tcp ACK OK") return None - response = unpack('HHHH', data_recv[8:16])[0] + response = unpack("HHHH", data_recv[8:16])[0] if response == const.CMD_ACK_OK: - if self.verbose: print ("chunk tcp ACK OK!") - return b''.join(data) - if self.verbose: print("bad response %s" % data_recv) - if self.verbose: print (codecs.encode(data,'hex')) + if self.verbose: + print("chunk tcp ACK OK!") + return b"".join(data) + if self.verbose: + print("bad response %s" % data_recv) + if self.verbose: + print(codecs.encode(data, "hex")) return None return resp while True: - data_recv = self.__sock.recv(1024+8) - response = unpack('<4H', data_recv[:8])[0] - if self.verbose: print ("# packet response is: {}".format(response)) + data_recv = self.__sock.recv(1024 + 8) + response = unpack("<4H", data_recv[:8])[0] + if self.verbose: + print("# packet response is: {}".format(response)) if response == const.CMD_DATA: data.append(data_recv[8:]) size -= 1024 elif response == const.CMD_ACK_OK: break else: - if self.verbose: print ("broken!") + if self.verbose: + print("broken!") break - if self.verbose: print ("still needs %s" % size) - return b''.join(data) + if self.verbose: + print("still needs %s" % size) + return b"".join(data) else: - if self.verbose: print ("invalid response %s" % self.__response) + if self.verbose: + print("invalid response %s" % self.__response) return None def __read_chunk(self, start, size): @@ -1516,7 +1720,7 @@ def __read_chunk(self, start, size): """ for _retries in range(3): command = 1504 - command_string = pack('= 8: - uid, status, timestamp, punch = unpack('HB4sB', attendance_data.ljust(8, b'\x00')[:8]) - if self.verbose: print (codecs.encode(attendance_data[:8], 'hex')) + uid, status, timestamp, punch = unpack( + "HB4sB", attendance_data.ljust(8, b"\x00")[:8] + ) + if self.verbose: + print(codecs.encode(attendance_data[:8], "hex")) attendance_data = attendance_data[8:] tuser = list(filter(lambda x: x.uid == uid, users)) if not tuser: @@ -1609,13 +1836,17 @@ def get_attendance(self): attendances.append(attendance) elif record_size == 16: while len(attendance_data) >= 16: - user_id, timestamp, status, punch, reserved, workcode = unpack('= 40: - uid, user_id, status, timestamp, punch, space = unpack(' Date: Tue, 18 Oct 2022 16:47:09 -0400 Subject: [PATCH 3/3] :bug:(issue-150) keep style --- zk/base.py | 956 ++++++++++++++++++++--------------------------------- 1 file changed, 364 insertions(+), 592 deletions(-) diff --git a/zk/base.py b/zk/base.py index fbaab87..af7dcc2 100644 --- a/zk/base.py +++ b/zk/base.py @@ -13,7 +13,7 @@ def safe_cast(val, to_type, default=None): - # https://stackoverflow.com/questions/6330071/safe-casting-in-python + #https://stackoverflow.com/questions/6330071/safe-casting-in-python try: return to_type(val) except (ValueError, TypeError): @@ -29,23 +29,31 @@ def make_commkey(key, session_id, ticks=50): session_id = int(session_id) k = 0 for i in range(32): - if key & (1 << i): - k = k << 1 | 1 + if (key & (1 << i)): + k = (k << 1 | 1) else: k = k << 1 k += session_id - k = pack(b"I", k) - k = unpack(b"BBBB", k) + k = pack(b'I', k) + k = unpack(b'BBBB', k) k = pack( - b"BBBB", k[0] ^ ord("Z"), k[1] ^ ord("K"), k[2] ^ ord("S"), k[3] ^ ord("O") - ) - k = unpack(b"HH", k) - k = pack(b"HH", k[1], k[0]) - - B = 0xFF & ticks - k = unpack(b"BBBB", k) - k = pack(b"BBBB", k[0] ^ B, k[1] ^ B, B, k[3] ^ B) + b'BBBB', + k[0] ^ ord('Z'), + k[1] ^ ord('K'), + k[2] ^ ord('S'), + k[3] ^ ord('O')) + k = unpack(b'HH', k) + k = pack(b'HH', k[1], k[0]) + + B = 0xff & ticks + k = unpack(b'BBBB', k) + k = pack( + b'BBBB', + k[0] ^ B, + k[1] ^ B, + B, + k[3] ^ B) return k @@ -69,18 +77,15 @@ def test_ping(self): :return: bool """ import subprocess, platform - # Ping parameters as function of OS - ping_str = "-n 1" if platform.system().lower() == "windows" else "-c 1 -W 5" + ping_str = "-n 1" if platform.system().lower()=="windows" else "-c 1 -W 5" args = "ping " + " " + ping_str + " " + self.ip - need_sh = False if platform.system().lower() == "windows" else True + need_sh = False if platform.system().lower()=="windows" else True # Ping - return ( - subprocess.call( - args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=need_sh - ) - == 0 - ) + return subprocess.call(args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=need_sh) == 0 def test_tcp(self): """ @@ -105,18 +110,7 @@ class ZK(object): """ ZK main class """ - - def __init__( - self, - ip, - port=4370, - timeout=60, - password=0, - force_udp=False, - ommit_ping=False, - verbose=False, - encoding="UTF-8", - ): + def __init__(self, ip, port=4370, timeout=60, password=0, force_udp=False, ommit_ping=False, verbose=False, encoding='UTF-8'): """ Construct a new 'ZK' object. @@ -134,7 +128,7 @@ def __init__( self.__sock = socket(AF_INET, SOCK_DGRAM) self.__sock.settimeout(timeout) self.__timeout = timeout - self.__password = password # passint + self.__password = password # passint self.__session_id = 0 self.__reply_id = const.USHRT_MAX - 1 self.__data_recv = None @@ -162,8 +156,8 @@ def __init__( self.users_av = 0 self.rec_av = 0 self.next_uid = 1 - self.next_user_id = "1" - self.user_packet_size = 28 # default zk6 + self.next_user_id='1' + self.user_packet_size = 28 # default zk6 self.end_live_capture = False def __nonzero__(self): @@ -186,23 +180,21 @@ def __create_tcp_top(self, packet): witch the complete packet set top header """ length = len(packet) - top = pack( - "= const.USHRT_MAX: reply_id -= const.USHRT_MAX - buf = pack("<4H", command, checksum, session_id, reply_id) + buf = pack('<4H', command, checksum, session_id, reply_id) return buf + command_string def __create_checksum(self, p): @@ -213,7 +205,7 @@ def __create_checksum(self, p): l = len(p) checksum = 0 while l > 1: - checksum += unpack("H", pack("BB", p[0], p[1]))[0] + checksum += unpack('H', pack('BB', p[0], p[1]))[0] p = p[2:] if checksum > const.USHRT_MAX: checksum -= const.USHRT_MAX @@ -229,34 +221,28 @@ def __create_checksum(self, p): while checksum < 0: checksum += const.USHRT_MAX - return pack("H", checksum) + return pack('H', checksum) def __test_tcp_top(self, packet): """ return size! """ - if len(packet) <= 8: - if self.verbose: - print("incomplete response? " + codecs.encode(packet, "hex")) + if len(packet)<=8: + if self.verbose: print('incomplete response? ' + codecs.encode(packet,'hex')) return 0 - tcp_header = unpack("= 80: - fields = unpack("20i", self.__data[:80]) + fields = unpack('20i', self.__data[:80]) self.users = fields[4] self.fingers = fields[6] self.records = fields[8] - self.dummy = fields[10] # ??? + self.dummy = fields[10] #??? self.cards = fields[12] self.fingers_cap = fields[14] self.users_cap = fields[15] @@ -703,10 +679,8 @@ def read_sizes(self): self.users_av = fields[18] self.rec_av = fields[19] self.__data = self.__data[80:] - if len(self.__data) >= 12: # face info - fields = unpack( - "3i", self.__data[:12] - ) # dirty hack! we need more information + if len(self.__data) >= 12: #face info + fields = unpack('3i', self.__data[:12]) #dirty hack! we need more information self.faces = fields[0] self.faces_cap = fields[2] return True @@ -722,21 +696,20 @@ def unlock(self, time=3): :return: bool """ command = const.CMD_UNLOCK - command_string = pack("I", int(time) * 10) + command_string = pack("I",int(time)*10) cmd_response = self.__send_command(command, command_string) - if cmd_response.get("status"): + if cmd_response.get('status'): return True else: raise ZKErrorResponse("Can't open door") - def get_lock_state(self): - """ + ''' :return: boolean thanks to https://github.com/icarome/pyzk/ - """ + ''' command = const.CMD_DOORSTATE_RRQ cmd_response = self.__send_command(command) - if cmd_response.get("status"): + if cmd_response.get('status'): return True else: return False @@ -745,22 +718,12 @@ def __str__(self): """ for debug """ - return ( - "ZK %s://%s:%s users[%i]:%i/%i fingers:%i/%i, records:%i/%i faces:%i/%i" - % ( - "tcp" if self.tcp else "udp", - self.__address[0], - self.__address[1], - self.user_packet_size, - self.users, - self.users_cap, - self.fingers, - self.fingers_cap, - self.records, - self.rec_cap, - self.faces, - self.faces_cap, - ) + return "ZK %s://%s:%s users[%i]:%i/%i fingers:%i/%i, records:%i/%i faces:%i/%i" % ( + "tcp" if self.tcp else "udp", self.__address[0], self.__address[1], + self.user_packet_size, self.users, self.users_cap, + self.fingers, self.fingers_cap, + self.records, self.rec_cap, + self.faces, self.faces_cap ) def restart(self): @@ -771,7 +734,7 @@ def restart(self): """ command = const.CMD_RESTART cmd_response = self.__send_command(command) - if cmd_response.get("status"): + if cmd_response.get('status'): self.is_connect = False self.next_uid = 1 return True @@ -785,13 +748,9 @@ def write_lcd(self, line_number, text): :param text: text to write """ command = const.CMD_WRITE_LCD - command_string = ( - pack(b"= 28: - ( - uid, - privilege, - password, - name, - card, - group_id, - timezone, - user_id, - ) = unpack(" max_uid: - max_uid = uid - password = (password.split(b"\x00")[0]).decode( - self.encoding, errors="ignore" - ) - name = ( - (name.split(b"\x00")[0]) - .decode(self.encoding, errors="ignore") - .strip() - ) + uid, privilege, password, name, card, group_id, timezone, user_id = unpack(' max_uid: max_uid = uid + password = (password.split(b'\x00')[0]).decode(self.encoding, errors='ignore') + name = (name.split(b'\x00')[0]).decode(self.encoding, errors='ignore').strip() group_id = str(group_id) user_id = str(user_id) - # TODO: check card value and find in ver8 + #TODO: check card value and find in ver8 if not name: name = "NN-%s" % user_id user = User(uid, name, privilege, password, group_id, user_id, card) users.append(user) - if self.verbose: - print( - "[6]user:", - uid, - privilege, - password, - name, - card, - group_id, - timezone, - user_id, - ) + if self.verbose: print("[6]user:",uid, privilege, password, name, card, group_id, timezone, user_id) userdata = userdata[28:] else: while len(userdata) >= 72: - uid, privilege, password, name, card, group_id, user_id = unpack( - " max_uid: - max_uid = uid + uid, privilege, password, name, card, group_id, user_id = unpack(' max_uid: max_uid = uid if not name: name = "NN-%s" % user_id user = User(uid, name, privilege, password, group_id, user_id, card) @@ -1305,7 +1176,7 @@ def cancel_capture(self): """ command = const.CMD_CANCELCAPTURE cmd_response = self.__send_command(command) - return bool(cmd_response.get("status")) + return bool(cmd_response.get('status')) def verify_user(self): """ @@ -1315,7 +1186,7 @@ def verify_user(self): """ command = const.CMD_STARTVERIFY cmd_response = self.__send_command(command) - if cmd_response.get("status"): + if cmd_response.get('status'): return True else: raise ZKErrorResponse("Cant Verify") @@ -1325,20 +1196,20 @@ def reg_event(self, flags): reg events """ command = const.CMD_REG_EVENT - command_string = pack("I", flags) + command_string = pack ("I", flags) cmd_response = self.__send_command(command, command_string) - if not cmd_response.get("status"): + if not cmd_response.get('status'): raise ZKErrorResponse("cant' reg events %i" % flags) def set_sdk_build_1(self): command = const.CMD_OPTIONS_WRQ command_string = b"SDKBuild=1" cmd_response = self.__send_command(command, command_string) - if not cmd_response.get("status"): + if not cmd_response.get('status'): return False return True - def enroll_user(self, uid=0, temp_id=0, user_id=""): + def enroll_user(self, uid=0, temp_id=0, user_id=''): """ start enroll user @@ -1349,105 +1220,86 @@ def enroll_user(self, uid=0, temp_id=0, user_id=""): """ command = const.CMD_STARTENROLL done = False - if not user_id: + if not user_id: users = self.get_users() - users = list(filter(lambda x: x.uid == uid, users)) + users = list(filter(lambda x: x.uid==uid, users)) if len(users) >= 1: user_id = users[0].user_id else: return False if self.tcp: - command_string = pack("<24sbb", str(user_id).encode(), temp_id, 1) + command_string = pack('<24sbb',str(user_id).encode(), temp_id, 1) else: - command_string = pack(" 16: - res = unpack("H", data_recv.ljust(24, b"\x00")[16:18])[0] - if self.verbose: - print("res %i" % res) + res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] + if self.verbose: print("res %i" % res) if res == 0 or res == 6 or res == 4: - if self.verbose: - print("posible timeout o reg Fallido") + if self.verbose: print ("posible timeout o reg Fallido") break else: if len(data_recv) > 8: - res = unpack("H", data_recv.ljust(16, b"\x00")[8:10])[0] - if self.verbose: - print("res %i" % res) + res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] + if self.verbose: print("res %i" % res) if res == 6 or res == 4: - if self.verbose: - print("posible timeout") + if self.verbose: print ("posible timeout") break - if self.verbose: - print("A:%i esperando 2do regevent" % attempts) + if self.verbose: print ("A:%i esperando 2do regevent" % attempts) data_recv = self.__sock.recv(1032) self.__ack_ok() - if self.verbose: - print(codecs.encode(data_recv, "hex")) + if self.verbose: print (codecs.encode(data_recv, 'hex')) if self.tcp: if len(data_recv) > 8: - res = unpack("H", data_recv.ljust(24, b"\x00")[16:18])[0] - if self.verbose: - print("res %i" % res) + res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] + if self.verbose: print("res %i" % res) if res == 6 or res == 4: - if self.verbose: - print("posible timeout o reg Fallido") + if self.verbose: print ("posible timeout o reg Fallido") break elif res == 0x64: - if self.verbose: - print("ok, continue?") + if self.verbose: print ("ok, continue?") attempts -= 1 else: if len(data_recv) > 8: - res = unpack("H", data_recv.ljust(16, b"\x00")[8:10])[0] - if self.verbose: - print("res %i" % res) + res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] + if self.verbose: print("res %i" % res) if res == 6 or res == 4: - if self.verbose: - print("posible timeout o reg Fallido") + if self.verbose: print ("posible timeout o reg Fallido") break elif res == 0x64: - if self.verbose: - print("ok, continue?") + if self.verbose: print ("ok, continue?") attempts -= 1 if attempts == 0: data_recv = self.__sock.recv(1032) self.__ack_ok() - if self.verbose: - print(codecs.encode(data_recv, "hex")) + if self.verbose: print (codecs.encode(data_recv, 'hex')) if self.tcp: - res = unpack("H", data_recv.ljust(24, b"\x00")[16:18])[0] + res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] else: - res = unpack("H", data_recv.ljust(16, b"\x00")[8:10])[0] - if self.verbose: - print("res %i" % res) + res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] + if self.verbose: print("res %i" % res) if res == 5: - if self.verbose: - print("finger duplicate") + if self.verbose: print ("finger duplicate") if res == 6 or res == 4: - if self.verbose: - print("posible timeout") - if res == 0: - size = unpack("H", data_recv.ljust(16, b"\x00")[10:12])[0] - pos = unpack("H", data_recv.ljust(16, b"\x00")[12:14])[0] - if self.verbose: - print("enroll ok", size, pos) + if self.verbose: print ("posible timeout") + if res == 0: + size = unpack("H", data_recv.ljust(16,b"\x00")[10:12])[0] + pos = unpack("H", data_recv.ljust(16,b"\x00")[12:14])[0] + if self.verbose: print("enroll ok", size, pos) done = True self.__sock.settimeout(self.__timeout) - self.reg_event(0) # TODO: test + self.reg_event(0) # TODO: test self.cancel_capture() self.verify_user() return done @@ -1462,54 +1314,46 @@ def live_capture(self, new_timeout=10): self.verify_user() if not self.is_enabled: self.enable_device() - if self.verbose: - print("start live_capture") + if self.verbose: print ("start live_capture") self.reg_event(const.EF_ATTLOG) self.__sock.settimeout(new_timeout) self.end_live_capture = False while not self.end_live_capture: try: - if self.verbose: - print("esperando event") + if self.verbose: print ("esperando event") data_recv = self.__sock.recv(1032) self.__ack_ok() if self.tcp: - size = unpack("= 12: if len(data) == 12: - user_id, status, punch, timehex = unpack("= 52: - user_id, status, punch, timehex, _other = unpack( - "<24sBB6s20s", data[:52] - ) + user_id, status, punch, timehex, _other = unpack('<24sBB6s20s', data[:52]) data = data[52:] if isinstance(user_id, int): user_id = str(user_id) else: - user_id = (user_id.split(b"\x00")[0]).decode(errors="ignore") + user_id = (user_id.split(b'\x00')[0]).decode(errors='ignore') timestamp = self.__decode_timehex(timehex) tuser = list(filter(lambda x: x.user_id == user_id, users)) if not tuser: @@ -1518,15 +1362,12 @@ def live_capture(self, new_timeout=10): uid = tuser[0].uid yield Attendance(user_id, timestamp, status, punch, uid) except timeout: - if self.verbose: - print("time out") - yield None # return to keep watching + if self.verbose: print ("time out") + yield None # return to keep watching except (KeyboardInterrupt, SystemExit): - if self.verbose: - print("break") + if self.verbose: print ("break") break - if self.verbose: - print("exit gracefully") + if self.verbose: print ("exit gracefully") self.__sock.settimeout(self.__timeout) self.reg_event(0) if not was_enabled: @@ -1539,124 +1380,96 @@ def clear_data(self): :return: bool """ command = const.CMD_CLEAR_DATA - command_string = b"" + command_string = b'' cmd_response = self.__send_command(command, command_string) - if cmd_response.get("status"): + if cmd_response.get('status'): self.next_uid = 1 return True else: raise ZKErrorResponse("can't clear data") def __recieve_tcp_data(self, data_recv, size): - """data_recv, raw tcp packet - must analyze tcp_length + """ data_recv, raw tcp packet + must analyze tcp_length - must return data, broken - """ + must return data, broken + """ data = [] tcp_length = self.__test_tcp_top(data_recv) - if self.verbose: - print("tcp_length {}, size {}".format(tcp_length, size)) + if self.verbose: print ("tcp_length {}, size {}".format(tcp_length, size)) if tcp_length <= 0: - if self.verbose: - print("Incorrect tcp packet") + if self.verbose: print ("Incorrect tcp packet") return None, b"" if (tcp_length - 8) < size: - if self.verbose: - print("tcp length too small... retrying") + if self.verbose: print ("tcp length too small... retrying") resp, bh = self.__recieve_tcp_data(data_recv, tcp_length - 8) data.append(resp) size -= len(resp) - if self.verbose: - print("new tcp DATA packet to fill misssing {}".format(size)) - data_recv = bh + self.__sock.recv(size + 16) - if self.verbose: - print("new tcp DATA starting with {} bytes".format(len(data_recv))) + if self.verbose: print ("new tcp DATA packet to fill misssing {}".format(size)) + data_recv = bh + self.__sock.recv(size + 16 ) + if self.verbose: print ("new tcp DATA starting with {} bytes".format(len(data_recv))) resp, bh = self.__recieve_tcp_data(data_recv, size) data.append(resp) - if self.verbose: - print( - "for misssing {} recieved {} with extra {}".format( - size, len(resp), len(bh) - ) - ) - return b"".join(data), bh + if self.verbose: print ("for misssing {} recieved {} with extra {}".format(size, len(resp), len(bh))) + return b''.join(data), bh recieved = len(data_recv) - if self.verbose: - print("recieved {}, size {}".format(recieved, size)) - response = unpack("HHHH", data_recv[8:16])[0] + if self.verbose: print ("recieved {}, size {}".format(recieved, size)) + response = unpack('HHHH', data_recv[8:16])[0] if recieved >= (size + 32): if response == const.CMD_DATA: resp = data_recv[16 : size + 16] - if self.verbose: - print("resp complete len {}".format(len(resp))) - return resp, data_recv[size + 16 :] + if self.verbose: print ("resp complete len {}".format(len(resp))) + return resp, data_recv[size + 16:] else: - if self.verbose: - print("incorrect response!!! {}".format(response)) + if self.verbose: print("incorrect response!!! {}".format(response)) return None, b"" else: - if self.verbose: - print("try DATA incomplete (actual valid {})".format(recieved - 16)) - data.append(data_recv[16 : size + 16]) + if self.verbose: print ("try DATA incomplete (actual valid {})".format(recieved-16)) + data.append(data_recv[16 : size + 16 ]) size -= recieved - 16 broken_header = b"" if size < 0: broken_header = data_recv[size:] - if self.verbose: - print("broken", (broken_header).encode("hex")) + if self.verbose: print ("broken", (broken_header).encode('hex')) if size > 0: data_recv = self.__recieve_raw_data(size) data.append(data_recv) - return b"".join(data), broken_header + return b''.join(data), broken_header def __recieve_raw_data(self, size): - """partial data ?""" + """ partial data ? """ data = [] - if self.verbose: - print("expecting {} bytes raw data".format(size)) + if self.verbose: print ("expecting {} bytes raw data".format(size)) while size > 0: data_recv = self.__sock.recv(size) recieved = len(data_recv) - if self.verbose: - print("partial recv {}".format(recieved)) - if recieved < 100 and self.verbose: - print(" recv {}".format(codecs.encode(data_recv, "hex"))) + if self.verbose: print ("partial recv {}".format(recieved)) + if recieved < 100 and self.verbose: print (" recv {}".format(codecs.encode(data_recv, 'hex'))) data.append(data_recv) size -= recieved - if self.verbose: - print("still need {}".format(size)) - return b"".join(data) + if self.verbose: print ("still need {}".format(size)) + return b''.join(data) def __recieve_chunk(self): - """recieve a chunk""" + """ recieve a chunk """ if self.__response == const.CMD_DATA: if self.tcp: - if self.verbose: - print( - "_rc_DATA! is {} bytes, tcp length is {}".format( - len(self.__data), self.__tcp_length - ) - ) + if self.verbose: print ("_rc_DATA! is {} bytes, tcp length is {}".format(len(self.__data), self.__tcp_length)) if len(self.__data) < (self.__tcp_length - 8): need = (self.__tcp_length - 8) - len(self.__data) - if self.verbose: - print("need more data: {}".format(need)) + if self.verbose: print ("need more data: {}".format(need)) more_data = self.__recieve_raw_data(need) - return b"".join([self.__data, more_data]) + return b''.join([self.__data, more_data]) else: - if self.verbose: - print("Enough data") + if self.verbose: print ("Enough data") return self.__data else: - if self.verbose: - print("_rc len is {}".format(len(self.__data))) + if self.verbose: print ("_rc len is {}".format(len(self.__data))) return self.__data elif self.__response == const.CMD_PREPARE_DATA: data = [] size = self.__get_data_size() - if self.verbose: - print("recieve chunk: prepare data size is {}".format(size)) + if self.verbose: print ("recieve chunk: prepare data size is {}".format(size)) if self.tcp: if len(self.__data) >= (8 + size): data_recv = self.__data[8:] @@ -1670,48 +1483,37 @@ def __recieve_chunk(self): else: data_recv = broken_header if len(data_recv) < 16: - print("trying to complete broken ACK %s /16" % len(data_recv)) - if self.verbose: - print(data_recv.encode("hex")) - data_recv += self.__sock.recv( - 16 - len(data_recv) - ) # TODO: CHECK HERE_! + print ("trying to complete broken ACK %s /16" % len(data_recv)) + if self.verbose: print (data_recv.encode('hex')) + data_recv += self.__sock.recv(16 - len(data_recv)) #TODO: CHECK HERE_! if not self.__test_tcp_top(data_recv): - if self.verbose: - print("invalid chunk tcp ACK OK") + if self.verbose: print ("invalid chunk tcp ACK OK") return None - response = unpack("HHHH", data_recv[8:16])[0] + response = unpack('HHHH', data_recv[8:16])[0] if response == const.CMD_ACK_OK: - if self.verbose: - print("chunk tcp ACK OK!") - return b"".join(data) - if self.verbose: - print("bad response %s" % data_recv) - if self.verbose: - print(codecs.encode(data, "hex")) + if self.verbose: print ("chunk tcp ACK OK!") + return b''.join(data) + if self.verbose: print("bad response %s" % data_recv) + if self.verbose: print (codecs.encode(data,'hex')) return None return resp while True: - data_recv = self.__sock.recv(1024 + 8) - response = unpack("<4H", data_recv[:8])[0] - if self.verbose: - print("# packet response is: {}".format(response)) + data_recv = self.__sock.recv(1024+8) + response = unpack('<4H', data_recv[:8])[0] + if self.verbose: print ("# packet response is: {}".format(response)) if response == const.CMD_DATA: data.append(data_recv[8:]) size -= 1024 elif response == const.CMD_ACK_OK: break else: - if self.verbose: - print("broken!") + if self.verbose: print ("broken!") break - if self.verbose: - print("still needs %s" % size) - return b"".join(data) + if self.verbose: print ("still needs %s" % size) + return b''.join(data) else: - if self.verbose: - print("invalid response %s" % self.__response) + if self.verbose: print ("invalid response %s" % self.__response) return None def __read_chunk(self, start, size): @@ -1720,7 +1522,7 @@ def __read_chunk(self, start, size): """ for _retries in range(3): command = 1504 - command_string = pack("= 8: - uid, status, timestamp, punch = unpack( - "HB4sB", attendance_data.ljust(8, b"\x00")[:8] - ) - if self.verbose: - print(codecs.encode(attendance_data[:8], "hex")) + uid, status, timestamp, punch = unpack('HB4sB', attendance_data.ljust(8, b'\x00')[:8]) + if self.verbose: print (codecs.encode(attendance_data[:8], 'hex')) attendance_data = attendance_data[8:] tuser = list(filter(lambda x: x.uid == uid, users)) if not tuser: @@ -1836,17 +1615,13 @@ def get_attendance(self): attendances.append(attendance) elif record_size == 16: while len(attendance_data) >= 16: - user_id, timestamp, status, punch, reserved, workcode = unpack( - "= 40: - uid, user_id, status, timestamp, punch, space = unpack( - "