#-*- coding: UTF-8 -*- #!/usr/bin/python import os import sys import fs import struct import json from collections import OrderedDict import zlib import pprint import hashlib from ctypes import * import platform current_abspath = os.path.dirname(os.path.realpath(__file__)) if platform.system() == 'Windows': pDll = CDLL(os.sep.join([current_abspath, "lib", "eheatshrink.dll"])) elif platform.system() == 'Linux': pDll = CDLL(os.sep.join([current_abspath, "lib", "libeheatshrink.so"])) pDll.ecompress_size.restype = c_uint32 pDll.ecompress_size.argtypes = [c_void_p, c_uint32] pDll.ecompress.restype = POINTER(c_uint8) pDll.ecompress.argtypes = [c_void_p, c_uint32] def heatshrink_compress(buf:bytes, level:int): count = len(buf) size = pDll.ecompress_size(buf, count) pDll.ecompress.restype = POINTER(c_uint8) pDll.ecompress.argtypes = [c_void_p, c_uint32] ret = pDll.ecompress(buf, count) arr = bytearray(size) i = 0 while i < size: arr[i] = ret[i] i = i+1 return arr def str_to_hex(s): return ' '.join([hex(ord(c)).replace('0x', '') for c in s]) def hex_to_str(s): return ''.join([chr(i) for i in [int(b, 16) for b in s.split(' ')]]) def str_to_bin(s): return ' '.join([bin(ord(c)).replace('0b', '') for c in s]) def bin_to_str(s): return ''.join([chr(i) for i in [int(b, 2) for b in s.split(' ')]]) class EpkApp(object): def __init__(self, appName, appDir, algorithm='zlib',appVersion="1.0", output="epks"): super(EpkApp, self).__init__() self._appName = appName self._appDir = os.path.abspath(appDir) self.algorithm = algorithm self._appVersion = appVersion self._appCRCCode = None self._files = [] self._infoPath = os.sep.join([self._appDir, "%s.json" % self._appName]) self._epksDir = output if not os.path.exists(self._epksDir): fs.open_fs(os.getcwd()).makedirs(output) self._epkName = os.sep.join([self._epksDir, "%s.epk" % self._appName]) def compress(self): if self.algorithm == 'h': return heatshrink_compress return zlib.compress def epkInfo(self): epkInfo = OrderedDict({ "appName": self._appName, "appVersion": self._appVersion, "files": self.fileinfos(self._appDir), }) infocontent = json.dumps(epkInfo) with open(self._infoPath, "w", encoding='utf-8') as f: f.write(infocontent) return epkInfo def fileinfos(self, path): path = os.path.abspath(path) home_fs = fs.open_fs(path) files = [] for jspath in home_fs.glob('*', namespaces=['details']): fpath = "C:/%s" % jspath.info.name fname = jspath.info.name fsize = jspath.info.size fbasename, fext = os.path.splitext(jspath.info.name) if fext in ["", ".exe", ".dll", ".nv", ".conf"]: continue finfo = { "path": fpath, "name": fname, "size": fsize, "basename": fbasename, "ext": fext } if self._infoPath == os.sep.join([path, fname]): files.insert(0, finfo) else: files.append(finfo) if fext == ".evue": self.fileMD5(finfo) return files def header(self, epk_start=0xAAAA, md5_offset=0, file_count=0): bytes_header = struct.pack("