''' This file needs to be run outside of the GShellAutomator script Starts a TCP server on localhost, to which GSA asks for accounts and reports problems Command list: givacc: Client is requesting a qwiklabs account to use. Take one from the available list and return it, then put it in the suspended list remacc: Client reported the account is not working anymore, and it needs to be delete (TODO: make this script test is the account is really unusable) ''' import time import json import socket import random import threading from multiprocessing import Process, Manager def qwprint(*s): msg = ''.join(a + " " for a in s) print("[QWAccountServer]", msg) def handle_clients(available_list, suspended_dict, todelete_list): while True: (clientsocket, address) = socket.accept() command = clientsocket.recv(1024).decode("utf-8").split("|") if command[0] != "": if command[0] == "givacc": account_valid = False while not account_valid: account = available_list[random.randint(0, len(available_list)-1)] if (not account in suspended_dict.keys() ) and (not account in todelete_list): account_valid = True suspended_dict[account] = time.time() clientsocket.send(account.encode("utf-8")) qwprint("Received a request for a new account, choose", account) elif command[0] == "remacc": if command[1]in suspended_dict: del suspended_dict[command[1]] todelete_list.append(command[1]) clientsocket.close() qwprint("Received a request to delete", command[1], "adding to list!") def openfiles(): available = open('/account_data/qwiklabs_available_accounts.txt', 'r+') suspended = open('/account_data/qwiklabs_suspended.txt', 'r+') todelete = open('/account_data/qwiklabs_todelete.txt', 'r+') return available, suspended, todelete if __name__ == "__main__": qwprint("Starting QWAccountServer") with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as socket: socket.bind(("0.0.0.0", 12345)) socket.listen(5) with Manager() as manager: available, suspended, todelete = openfiles() # create the list from the files available_list = manager.list([line.strip() for line in available.readlines()]) try: suspended_dict = manager.dict(json.loads(suspended.read())) except: suspended_dict = manager.dict({}) todelete_list = manager.list([line.strip() for line in todelete.readlines()]) p = Process(target=handle_clients, args=(available_list, suspended_dict, todelete_list)) p.start() last_update_time = time.time() while True: try: tounsuspend = [] for account in suspended_dict: if time.time()-suspended_dict[account] > 3600: #time is stored in seconds, so this is 3600 after an hour os first being suspened tounsuspend.append(account) qwprint("Unsuspend " + account+ " as enough time as passed") for account in tounsuspend: del suspended_dict[account] except: pass #update list if time.time() - last_update_time > 5: qwprint("Cyclic update of files") last_update_time = time.time() available, suspended, todelete = openfiles() #clear files, update with data loaded from the program available.truncate(0) suspended.truncate(0) todelete.truncate(0) #put data in there available.writelines([(l + "\n") for l in available_list]) suspended.write(json.dumps(dict(suspended_dict))) todelete.writelines([(l + "\n") for l in todelete_list]) #close files for it to take effect available.close() suspended.close() todelete.close() # else: # print("no time to update", str(time.time() - last_update_time))