#!/usr/bin/python # -*- coding: utf-8 -*- # mule1.py: independent worker process # - a TCP server as an example import time import datetime from pathlib import Path import requests import logging import os import hashlib import zipfile import subprocess import json from cryptography.fernet import Fernet import psutil import sys logging.basicConfig(level=logging.INFO) log = logging.getLogger("updater") log.setLevel(logging.INFO) API_URL="http://host.docker.internal:8181" Config_File="/conf/server-conf.json" Version_File="/usr/share/nginx/html/version.json" # Example usage def check_sha256(filename, expect): """Check if the file with the name "filename" matches the SHA-256 sum in "expect".""" h = hashlib.sha256() # This will raise an exception if the file doesn't exist. Catching # and handling it is left as an exercise for the reader. try: with open(filename, 'rb') as fh: # Read and hash the file in 4K chunks. Reading the whole # file at once might consume a lot of memory if it is # large. while True: data = fh.read(4096) if len(data) == 0: break else: h.update(data) return expect == h.hexdigest() except Exception as e: return False def crypt_data(text,key): # Encryption: Encrypting password using Fernet symmetric encryption key = Fernet.generate_key() cipher_suite = Fernet(key) # Encrypting encrypted_password = cipher_suite.encrypt(text.encode()).decode() return encrypted_password def decrypt_data(text,key): # Encryption: Decrypting password using Fernet symmetric encryption cipher_suite = Fernet(key) # Decrypting password decrypted_password = cipher_suite.decrypt(text.encode()).decode() return decrypted_password def extract_zip_reload(filename,dst): """Extract the contents of the zip file "filename" to the directory "dst". Then reload the updated modules.""" with zipfile.ZipFile(filename, 'r') as zip_ref: zip_ref.extractall(dst) # run db migrate # dir ="/usr/share/nginx/html/" # cmd = "cd {}; PYTHONPATH={}py PYSRV_CONFIG_PATH={} python3 scripts/dbmigrate.py".format(dir, dir, "/conf/server-conf.json") # p = subprocess.Popen(cmd, shell=True) # (output, err) = p.communicate() #This makes the wait possible # p_status = p.wait() #touch server reload file /app/reload os.remove(filename) # Path('/app/reload').touch() def load_config_file(): try: with open(Config_File, 'r') as fh: config = json.load(fh) return config except Exception as e: log.error(e) return False def get_serial_from_api(): url=API_URL+"/api/get_version" config=load_config_file() key=False if config: key=config.get('PYSRV_CRYPT_KEY',False) else: return False if not key: return False try: response = requests.get(url) response = response.json() return json.loads(decrypt_data(response['result'],key)) except Exception as e: log.error(e) return False def get_version_from_file(): try: with open(Version_File, 'r') as fh: version = json.load(fh) return version.get('version', '0.0.0') except Exception as e: log.error(e) return '0.0.0' def main(): while True: pcount=0 for process in psutil.process_iter(): if '/front-update.py' in process.cmdline(): pcount=pcount+1 if pcount>=2: print("Already running") exit() try: next_hour = (time.time() // 3600 + 1) * 3600 sleep_time = next_hour - time.time() res=get_serial_from_api() hwid=res['serial'] username=res['username'] version=get_version_from_file() params={ "serial_number": hwid, "username": username.strip(), "front":True, "version": version } url="https://mikrowizard.com/wp-json/mikrowizard/v1/get_update" # send post request to server mikrowizard.com with params in json response = requests.post(url, json=params) # get response from server res = response try: if res.status_code == 200: res=res.json() if 'token' in res: params={ "token":res['token'], "file_name":res['filename'], "username":username.strip(), "front":True } log.info("Update available/Downloading...") else: log.info("Update not available") time.sleep(sleep_time) continue except Exception as e: log.error(e) # check if filename exist in /app/py and checksum is same then dont continue if check_sha256("/usr/share/nginx/"+res['filename'], res['sha256']): log.error("Checksum match, File exist") extract_zip_reload("/usr/share/nginx/"+res['filename'],"/usr/share/nginx/") time.sleep(sleep_time) continue download_url="https://mikrowizard.com/wp-json/mikrowizard/v1/download_update" # send post request to server mikrowizard.com with params in json r = requests.post(download_url,json=params,stream=True) if "invalid" in r.text or r.text=='false': log.error(r) log.error("Invalid response") time.sleep(30) continue with open("/usr/share/nginx/"+res['filename'], 'wb') as fd: for chunk in r.iter_content(chunk_size=128): fd.write(chunk) if check_sha256("/usr/share/nginx/"+res['filename'], res['sha256']): log.error("Update downloaded") log.error("/usr/share/nginx/"+res['filename']) extract_zip_reload("/usr/share/nginx/"+res['filename'],"/usr/share/nginx/") else: log.error("Checksum not match") os.remove("/usr/share/nginx/"+res['filename']) time.sleep(sleep_time) except Exception as e: log.error(e) time.sleep(30) if __name__ == '__main__': main()