GShellAutomator/QWAccountServer/code/account_server.py

112 lines
4.5 KiB
Python
Raw Normal View History

''' 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))