def __init__(self): """ Initiates the UpdateManager, reads and parses the package JSON file """ self.logger = Logger("UpdateManager") self.packages = [] with open("Resources/packages.json") as f: data = json.load(f) self.parsePackages(data) self.logger.log("Found %d package(s)" % len(self.packages))
class UpdateManager: def __init__(self): """ Initiates the UpdateManager, reads and parses the package JSON file """ self.logger = Logger("UpdateManager") self.packages = [] with open("Resources/packages.json") as f: data = json.load(f) self.parsePackages(data) self.logger.log("Found %d package(s)" % len(self.packages)) def getPackageById(self, packageId): """ Gets a package, raises an error if the package does not exist :param packageId: The package id :return: The Package object """ for p in self.packages: if p.id == packageId: return p raise InvalidPackageId() def getPackageFile(self, packageId): """ Gets the file name for a package :param packageId: The package id :return: File name as a string """ package = self.getPackageById(packageId) return "Packages/%d.zip" % package.id def parsePackages(self, jsonData): """ Parses the package JSON file :param jsonData: The JSON string :return: A list of Package objects """ for jsonPackage in jsonData: package = Package() package.id = jsonPackage["id"] package.name = jsonPackage["name"] package.version = jsonPackage["version"] package.checksum = jsonPackage["checksum"] package.date = jsonPackage["date"] package.dependency = jsonPackage["dependency"] self.packages.append(package)
from ThinService.Common import Constants from ThinService.Common.Logger import Logger from ThinService.Server.ServerLogic import ServerLogic from ThinService.Server.ServerService import ServerService def printInitMessage(): """ Prints the welcome message """ print("THINSERVICE SERVER") print("Port: %d" % Constants.SERVER_PORT) print("=====================") printInitMessage() logger = Logger("Server") serverLogic = ServerLogic() serverService = ServerService(serverLogic) logger.log("Starting server...") serverService.startServer()
def printInitMessage(): """ Prints the welcome message """ print("THINSERVICE CLIENT") print("Host: %s" % Constants.SERVER_HOST) print("Port: %d" % Constants.SERVER_PORT) print("Client Info: %s" % getClientInfo()) print("=====================") printInitMessage() logger = Logger("Client") clientService = ClientService() try: clientService.connectToServer() logger.log("Successfully connected to the server.") except: logger.log("Could not connect to the server!") clientService.login(getClientInfo()) logger.log("Logged in on the server.") commandInterpreter = CommandInterpreter(clientService) while 1: print() command = input("Enter command: ")
def __init__(self, clientService): self.logger = Logger("CommandInterpreter") self.clientService = clientService
def __init__(self): self.logger = Logger("ServerLogic") self.clientList = ClientList() self.updateManager = UpdateManager()
class CommandInterpreter: def __init__(self, clientService): self.logger = Logger("CommandInterpreter") self.clientService = clientService def executeCommand(self, commandString): """ Interprets and executes a command string :param commandString: The raw command string including parameters """ self.logger.log("Executing command '%s'" % commandString) commandParts = commandString.split(" ") if commandParts[0] == "quit": self.logger.log("Goodbye.") sys.exit() if commandParts[0] == "hello": self.logger.log("Can't execute 'hello' method manually!") return try: method = getattr(self.clientService, commandParts[0]) params = self.getParamsList(commandParts) except: self.printError("Invalid command!") return try: result = method(*params) print("Result = %s" % result) except ClientAlreadyRegisteredError: self.printError( "A client with the same id is already registered on the server!" ) except InvalidClientId: self.printError("This client id does not exist!") except InvalidPackageId: self.printError("This package id does not exist!") except: self.logger.log("Error executing command!") raise def printError(self, err): """ Prints an error :param err: The error string """ print("Error = %s" % err) def getParamsList(self, commandParts): """ Extracs the parameters of a command and converts them if necessary :param commandParts: The parts of the command :return: List of parameters """ paramsRaw = commandParts[1:] params = [] for r in paramsRaw: try: params.append(int(r)) except: params.append(r) return params
class ServerLogic: def __init__(self): self.logger = Logger("ServerLogic") self.clientList = ClientList() self.updateManager = UpdateManager() def listClients(self): """ Lists all active clients :return: List of client ids """ self.logger.logRequest("list clients", "") return self.clientList.getActiveIds() def show(self, clientId): """ Shows client information :param clientId: The client id :return: A ClientDetails object """ self.logger.logRequest("show client", "id: %d" % clientId) if not self.clientList.isClientRegistered(clientId): raise InvalidClientId() return self.clientList.getClientDetails(clientId) def hello(self, clientId, clientInfo): """ Registers a client, raises an error if an active client is already registered for the client id :param clientId: The client id :param clientInfo: The client's hardware information """ self.logger.logRequest("hello", "id: %d info: %s" % (clientId, clientInfo)) if self.clientList.isClientRegistered(clientId): if self.clientList.isClientActive( self.clientList.getClient(clientId)): raise ClientAlreadyRegisteredError() else: self.logger.log("Re-registering client with id %d" % clientId) self.clientList.registerClient(clientId, clientInfo) def alive(self, clientId): """ Updates the lastSeen information :param clientId: The client id """ self.logger.logRequest("alive", "id: %d" % clientId) if not self.clientList.isClientRegistered(clientId): raise InvalidClientId() self.clientList.updateLastSeen(clientId) def update(self, clientId): """ Gets information about available packages :param clientId: The client id :return: A list of package information """ self.logger.logRequest("update", "id: %d" % clientId) return self.updateManager.packages def upgrade(self, clientId, packageId): """ Gets the binary package file contents :param clientId: The client id :param packageId: The package id :return: The binary string """ self.logger.logRequest("upgrade", "id: %d package: %d" % (clientId, packageId)) fileName = self.updateManager.getPackageFile(packageId) self.clientList.updateCurrentPackage(clientId, packageId) with open(fileName, "rb") as file: data = file.read() return data
def __init__(self): self.logger = Logger("ClientConnector") self.id = self.calculateClientId() self.upgradeManager = UpgradeManager() self.logger.log("Client id: %d" % self.id)
class ClientService: def __init__(self): self.logger = Logger("ClientConnector") self.id = self.calculateClientId() self.upgradeManager = UpgradeManager() self.logger.log("Client id: %d" % self.id) def calculateClientId(self): """ Calculates a unique hardware id :return: The id as an integer """ return int(uuid.getnode() / 1000000) def connectToServer(self): """ Sets up the server connection and opens it """ self.transport = TSocket.TSocket(Constants.SERVER_HOST, Constants.SERVER_PORT) self.transport = TTransport.TBufferedTransport(self.transport) protocol = TBinaryProtocol.TBinaryProtocol(self.transport) self.client = ThinService.Client(protocol) self.transport.open() def closeConnection(self): """ Closes the server connection """ self.transport.close() def list(self): """ Lists all active clients :return: List of client ids """ return self.client.listClients() def show(self, id): """ Shows client information :param id: The client id :return: A ClientDetails object """ return self.client.show(id) def login(self, clientInfo): """ Registers the client on the server :param clientInfo: The client's hardware information """ self.client.hello(self.id, clientInfo) def alive(self): """ Updates the lastSeen information on the server """ self.client.alive(self.id) def update(self): """ Gets information about available packages :return: A list of package information """ return self.client.update(self.id) def upgrade(self, packageId): """ Downloads a package and installs it :param packageId: The package id """ data = self.client.upgrade(self.id, packageId) self.upgradeManager.applyUpgrade(self.id, packageId, data)
def __init__(self): self.logger = Logger("ClientList") self.clients = dict()
class ClientList: def __init__(self): self.logger = Logger("ClientList") self.clients = dict() def registerClient(self, clientId, clientInfo): """ Registers a new client or replaces the current :param clientId: The new client id :param clientInfo: Client's hardware information """ self.clients[clientId] = Client(clientId, clientInfo) self.logger.log("Registered client with id %d" % clientId) self.updateLastSeen(clientId) def updateLastSeen(self, id): """ Sets the lastSeen information for a client to the current timestamp :param id: The client id """ timestamp = int(time.time()) self.clients[id].lastSeen = timestamp self.logger.log("Updated lastSeen for client %d to %d" % (id, timestamp)) def updateCurrentPackage(self, id, packageId): """ Updates the information about the installed package for a client :param id: The client id :param packageId: The package id """ self.clients[id].currentPackage = packageId self.logger.log("Updated currentPackage for client %d to %d" % (id, packageId)) def isClientRegistered(self, id): """ Checks if a client is registeres :param clientId: The client id to check :return: Boolean value """ return id in self.clients.keys() def getActiveIds(self): """ Lists the ids of the active clients :return: List of ids """ ret = [] for client in self.clients: if self.isClientActive(self.getClient(client)): ret.append(client) return ret def getClient(self, id): """ Gets information about a client :param id: The client id :return: The Client object """ return self.clients[id] def getClientDetails(self, id): """ Builds a ClientDetails object :param id: The client id :return: The filled ClientDetails object """ client = self.getClient(id) details = ClientDetails() details.info = client.info details.lastSeen = client.lastSeen details.packageId = client.currentPackage return details def isClientActive(self, client): """ Checks if a client is active :param client: The client id :return: Boolean value """ return client.lastSeen >= (int(time.time()) - Constants.SERVER_LASTSEEN_THRESHOLD)