def server_logs(client, severity: str, *args: str): if severity == "verbose": verbose("Server:", *args) elif severity == "info": info(*args) elif severity == "warning": warning('Server:', *args) elif severity == "error": error(*args) else: verbose("Server: unknown severity:", *args) warning("Received a message from the server, with unknown severity [", severity, "]")
def send(self, socket): """ Encodes this object and sends it in a Socket. :param socket: The socket in which to send this Message. """ s = self.name.encode() for arg in self.args: s += ESCAPE_CHARACTER + arg.encode() s += b"\n" try: verbose("Internal: Sending [", s.decode().replace('\n', ''), "]") socket.send(s) except OSError: error("Cannot send message, invalid connection.")
def ask_client(options: List[Tuple[str, str, str, str]]) -> str: """ Asks the client to choose between multiple Wikidata objects. :param options: A list of quadruplets: (q-code, name, description, URL on Wikidata) :return The one the user chose """ if len(options) == 0: error( "The server just requested to ask a question to the client, but didn't provide any possible answer! " "Skipping.") verbose("Requested a question without providing an answer") traceback.print_stack() return "" elif len(options) == 1: warning( 'Asking a question with only one possible answer, the client will not be prompted.' ) return options[0][0] from network.server import server tmp = [ str(i) + "|" + "|".join( [o.replace('|', '~').replace(' ', '~') for o in options[i][1:4]]) for i in range(len(options)) ] verbose("I'm going to ask the client to choose between [", tmp, "]") if len(server.clients) == 0: error("No clients are connected at this point.") raise Exception("Trying to ask the client, but there's no client.") elif len(server.clients) > 1: warning("Currently,", len(server.clients), "are connected; the first one will be selected.") client = server.clients[0] verbose("The question will be asked to client [", client, "]") client.send("choose", *tmp) client.receive_message() info('The client chose [', user_choice, ']') user = int(user_choice) return options[user][0]
def read_expressions(value: Expression, sentence: Sentence): """ Recursively reads an Expression and modifies the given Sentence to reflect what is seen. :param value: The Expression that needs to be parsed. :param sentence: The Sentence output. """ t = type(value) if t == ExistsExpression: sentence.add(value.variable.name) read_expressions(value.term, sentence) elif t == AndExpression: read_expressions(value.first, sentence) read_expressions(value.second, sentence) elif t == ApplicationExpression: sentence.add_tag( value.function.variable.name, value.argument.variable.name) elif t == EqualityExpression: first = type(value.first) if first == IndividualVariableExpression: # (x1 = x2) sentence.mark_as_equal( value.first.variable.name, value.second.variable.name) elif first == ApplicationExpression: # (link(e) = x) sentence.add_link(value.second.variable.name, value.first.argument.variable.name, value.first.function.variable.name) else: error( "Found an EqualityExpression but the first argument is a [", first, "], which is unforeseen!") raise Exception( "I do not know how to handle the type [", first, "] in a [", t, "] !") elif t == AllExpression: verbose("nltk2qo: Found a AllExpression") warning( "It looks like this sentence is a yes/no question, and they are not supported currently.") else: error("Type [", t, "] unknown, aborting.") raise Exception("I do not know how to handle the type [", t, "] !")
def pretty_print(self): """ Graphically display this Sentence, to make it easier to see what's going on. """ if len(self.__couples) != 0: error( "This sentence has not been fixed! There are still couples left: [", self.__couples, "]") if self.main is not None: info(" question marker:", self.main.id, "[", *self.main.tags, "]") else: info(" question marker not found, this sentence is not a question!") info(" events:") for e in self.events: info(" - " + e.id + ":", "[", *e.tags, "]") for v in e.variables: info(" - " + v[0] + ":", v[1].id, "[", *v[1].tags, "]")
def get_all_p_codes(words: str) -> List: """ gets the list of properties codes relevant to the searched words passed in parameters. :param words: string of searched words :return: list of p-codes with, for each, a short description of the linked page. """ answer = __get_wikidata_code(searched_words=words, object_type="property") properties = [] if 'search' in answer: for string in answer['search']: try: desc = string['description'] except KeyError: desc = "No description available" properties.append( (string['id'], string['label'], desc, string['url'])) if not properties: error("[ERROR]: Property \"" + words + "\" does not match any pages. Try another id!") return properties
def init_paths(): """ Searches for the tools in known location and finds their paths, or reports if they are missing. Searches in the submodule or in a Docker container. """ global PATHS_READY, TEMPLATE if PATHS_READY: verbose("Paths are already ready; exiting init_paths function") return info("\nSearching for the tools...") verbose("Working directory is [", os.getcwd(), "]") verbose("Project root is [", PROJECT_ROOT, "]") verbose("Server project root is [", SERVER_ROOT, "]") if test_directory(PROJECT_ROOT): verbose(" › Found the project root") else: error(" › Cannot find the project root!") if test_directory(SERVER_ROOT): verbose(" › Found the server root") else: error(" › Cannot find the server root!") if test_file(TEMPLATE): verbose(" › Found the template file") else: error(" › Template file not found") raise Exception("Couldn't find the template file.") verbose("Done initializing paths.\n") PATHS_READY = True
def get_all_q_codes(words: str) -> List: """ gets the list of items codes relevant to the searched words passed in parameters. :param words: string of searched words :return: list of q-codes with, for each, a short description of the linked page. """ # searches only on wikipedia network for now, as it is *usually* more efficient than Wikidata. # Might propose later to the user to choose between Wikipedia *and* # Wikidata results. title = __wikipedia_suggestion(words) items: List[Tuple[str, str, str, str]] = [] if not title.startswith("[ERROR]"): answer = __get_wikidata_code(searched_words=title, object_type="item") for string in answer['search']: try: desc: str = string['description'] except KeyError: desc = "No description available" items.append((string['id'], string['label'], desc, string['url'])) return items else: error(title) return items
def fix(self): for couple in self.__couples: variables = [self.__get_variable(variable) for variable in couple] first = variables[0] second = variables[1] verbose( " › Fixing equal variables [", first.id, "] and [", second.id, "]...") [first.tags.append(tag) for tag in second.tags] second.tags = first.tags second.id = first.id if first != second: error( "The two variables [", first, "] and [", second, "] should be equal, but they are not!") raise Exception("Variables that should be equal are not!") self.__couples.clear()
c.listen() self.clients.remove(c) verbose("Removed", c, "from the list of connected clients.") def register_command(self, name: str, callback): """ Registers a command that will be used by the server. :param name: The name of the command :param callback: The code to execute when that command is found. """ self.commands[name] = callback verbose("Server: Registered command [", name, "]") def kill(self): """ Closes this server and its socket. """ self.socket.close() self.is_running = False [client.close() for client in self.clients] info("Server: Disconnected.") try: server = Server(12800, 10) except OSError as e: error("Cannot run the server.", e)
def __not_loaded(options: List[Tuple[str, str, str, str]]) -> str: error("The 'ask_client' function has not been loaded!") warning("Falling back to the first choice provided.") return options[0][0]