class Singleton: def __init__(self): self.lang = Language() self.array = {} self.num = 0 self.database = Database() data = self.database.get('/bots/students', '') for topic in data: self.array[topic] = BotStudent(topic) def set_super_user_lang(self, chat_id, topic, new_lang): self.array[topic].set_super_user_lang(chat_id, new_lang) def send_notification_teacher(self, bot): for topic in self.array: self.array[topic].send_notification(bot, self.lang) def read_ban(self): return self.database.read_ban() def get_lang(self): return self.lang def get_database(self): return self.database def check_lang_str(self, txt, string): return self.lang.check_lang_str(txt, string) def get_best_resp(self, txt, lang, topic): list1 = {} json_array = self.array[topic].get_json_array(self.lang, lang) for question in json_array: num = self.lang.calculate_similarity(txt, question, lang) if num > 0.8: list1[question] = num return self.normalize_vect(list1) def normalize_vect(self, vect): array = sorted(vect.items(), key=operator.itemgetter(1), reverse=True) i = 0 list1 = [] for elem in array: if i == 4: break for e in elem: list1.append(e) break i += 1 return list1 def delete_bot(self, topic): self.database.del_bot(topic) del self.array[topic] def write_pwd(self, array): self.database.write_pwd(array) def get_banned_users(self): return self.database.get_banned_users() def get_username_by_topic(self, topic): return self.array[topic].get_username() def get_creation_keyboard(self, topic): return InlineKeyboardMarkup( inline_keyboard=[[ InlineKeyboardButton(text="Go to the teacher bot", url="https://t.me/" + self.database.get_bot_teacher( ).get_bot().getMe()["username"] + "?start=foo") ], [ InlineKeyboardButton( text="Go to the student " + topic + " bot", url="https://t.me/" + self.get_username_by_topic(topic) + "?start=foo") ]]) def read_pwd(self): return self.database.read_pwd() def change_pwd(self, topic, pwd): self.array[topic].change_pwd(pwd) def send_notification(self, teacher, student, topic): self.array[topic].sendRestartNotify(teacher, student, self.lang) def add_collaborators(self, vett, topic, lang): self.array[topic].add_collaborators(lang, vett) def change_role(self, chat_id, topic): return self.array[topic].change_role(chat_id) def get_hint(self, topic, lang): vett = [] for elem in ["it", "de", "en", "es", "fr"]: if elem != lang: vett += self.array[topic].get_trans_array(elem, lang) return vett def get_student_id(self): data = {} for elem in self.array: vett = self.array[elem].get_student_id() if len(vett) > 0: data[elem] = vett return data def new_bot(self, token, topic, hash): self.database.new_topic(token, topic, hash) self.array[topic] = BotStudent(topic) def get_pwd_admin(self): return self.database.get_pwd_admin() def get_token_list(self): list1 = [] for topic in self.array: list1.append(self.array[topic].get_token()) return list1 def get_topic_list(self): list1 = [] for topic in self.array: list1.append(topic) return list1 def get_flag_list(self): return self.lang.get_flag_list() def switcherflag(self, flag): return self.lang.get_lang_by_flag(flag) def set_student_id(self, vett): for elem in vett: self.array[elem].set_student_id(vett[elem]) def verify_password(self, topic, password): return self.array[topic].verify_password(password) def add_question_by_hint(self, lang, question, response, chat_id, from_id, topic): self.set_question(question, lang, topic, chat_id) self.set_qid(chat_id, from_id, question, topic) self.set_res(chat_id, from_id, response, lang, topic) def topic_keyboard(self): return create_reply_keyboard(array_to_matrix( self.get_topic_list())) def delete_tc(self, chat_id, topic): self.array[topic].del_teachers([chat_id]) self.array[topic].del_collaborators([chat_id]) def add_teachers(self, vett, topic, lang): self.array[topic].add_teachers(lang, vett) def get_bot_by_topic(self, topic): return self.array[topic].get_bot() def get_bot_pwd(self): return self.database.get_bot_pwd().get_bot() def get_ids_array(self, topic, lang, txt): array = self.array[topic].get_json_array(lang) return array[txt]["ids"] def add_admins(self, lang, vett): self.lang.add_admins(lang, vett) def get_admins(self, lang): return self.lang.get_admins(lang) def set_hash(self, topic, hash): self.array[topic].set_hash(hash) self.write_data() def set_qid(self, chat_id, from_id, txt, topic): self.array[topic].set_qid(chat_id, from_id, txt) def get_hash(self, topic): return self.array[topic].get_hash() def get_sent(self, lang, text): return self.lang.question_sent(lang, text) def get_q_array(self, chat_id, lang, topic): list_q = self.array[topic].get_json_array(self.lang, lang, True) list_u = [] for elem in list_q: if chat_id in list_q[elem]["id"]: list_u.append(elem) return list_u def get_qid(self, chat_id, from_id, topic): return self.array[topic].get_qid(chat_id, from_id) def del_qid(self, chat_id, from_id, topic): self.array[topic].del_qid(chat_id, from_id) def set_res(self, chat_id, from_id, txt, lang, topic): question = self.array[topic].get_qid(chat_id, from_id) if question != None: return self.array[topic].set_response(lang, question, txt) return None def set_ban(self, txt, lang, topic): jarray = self.array[topic].get_json_array(lang) e = self.lang.match_array(txt, lang, jarray) if e != None and jarray[e]["answer"] == "": self.array[topic].set_response(lang, e, "BANNED") self.array[topic].set_banned_stud() def set_sban(self, txt, lang, topic): jarray = self.array[topic].get_json_array(lang) e = self.lang.match_array(txt, lang, jarray) if e != None and jarray[e]["answer"] == "BANNED": self.array[topic].set_response(lang, e, "") self.array[topic].set_banned_stud() def set_nlp(self, lang): self.lang.set_nlp(lang) def set_lang_resp(self, id, lang, bot): self.lang.set_lang_resp(id, lang, bot) def add_id(self, from_id, chat_id, num, topic): return self.array[topic].add_id(from_id, chat_id, num) def get_res_array(self, topic, lang, condition): return self.array[topic].get_res_array(lang, condition) def check_id(self, from_id, chat_id, topic): return self.array[topic].check_id(from_id, chat_id) def del_id(self, from_id, chat_id, topic): return self.array[topic].del_id(from_id, chat_id) def get_topic(self, chat_id): for node in self.array: if chat_id in self.array[node].get_teach_coll(): return node return None def write_data(self): for elem in self.array: self.array[elem].set_formatted_data() def set_question(self, txt, lang, topic, chat_id): self.array[topic].add_question(txt, lang) self.array[topic].add_chat_id(txt, lang, chat_id) def get_response(self, txt, lang, topic, chat_id=None): json_array = self.array[topic].get_json_array(lang) val = 0 q = "" for question in json_array: num = self.lang.calculate_similarity(txt, question, lang) if num > val: val = num q = question if val > 0.8: if chat_id != None: self.array[topic].add_chat_id(q, lang, chat_id) self.write_data() return json_array[q]["answer"] else: return None def get_lang_board(self, lang, array): return self.lang.get_lang_board(lang, array) def set_keyboard(self, lang_array): return self.lang.set_keyboard(lang_array, False) def get_string(self, lang, string, xxx=None, yyy=None): return self.lang.get_string(lang, string, xxx, yyy) def get_user_lang(self, id, topic): return self.array[topic].getStudentLang(id) def get_super_user_lang(self, id, topic): return self.array[topic].get_toc_lang(id) def check_coll(self, lang, text): return self.lang.check_coll(lang, text) def check_teach(self, lang, text): return self.lang.check_teach(lang, text)
class Node: def __init__(self, node_name): self.name = node_name self.database = Database() self.json_array = self.database.get_questions_array(node_name) self.lang = Language() self.questions = {} self.hash = self.database.get_hash(node_name) def verify_password(self, provided_password): stored_password = self.hash salt = stored_password[:64] stored_password = stored_password[64:] pwdhash = hashlib.pbkdf2_hmac('sha512', provided_password.encode('utf-8'), salt.encode('ascii'), 100000) pwdhash = binascii.hexlify(pwdhash).decode('ascii') return pwdhash == stored_password def change_pwd(self, password): self.hash = password self.database.set_new_pwd(self.name, password) def set_teach_ids(self, array, lang): self.database.set_teach_ids(array, self.name, lang) def set_coll_ids(self, array, lang): self.database.set_coll_ids(array, self.name, lang) def get_topic_name(self): return self.name def get_json_array(self, lang): if lang not in self.json_array: return None return self.json_array[lang] def get_response(self, txt, lang): if lang in self.json_array and txt in self.json_array[lang]: return self.json_array[lang][txt]["answer"] return None def normalize_vect(self, vect): array = sorted(vect.items(), key=operator.itemgetter(1), reverse=True) i = 0 list1 = [] for elem in array: if i == 4: break for e in elem: list1.append(e) break i += 1 return list1 def get_best_resp(self, txt, lang): list1 = {} for question in self.json_array[lang]: num = self.lang.calculate_similarity(txt, question, lang) if num > 0.8: list1[question] = num return self.normalize_vect(list1) def get_bot_teacher(self): return self.database.get_bot_teacher() def set_question(self, question, lang, chat_id): if lang not in self.json_array: self.json_array[lang] = {} self.json_array[lang][question] = {} self.json_array[lang][question]["ids"] = [chat_id] self.json_array[lang][question]["answer"] = "" self.database.set_questions_array(self.json_array[lang], self.name, lang) def get_sent(self, lang, txt): return self.lang.question_sent(lang, txt) def check_lang_str(self, txt, string): return self.lang.check_lang_str(txt, string) def set_nlp(self, lang): self.lang.set_nlp(lang) def get_flag_list(self): return self.lang.get_flag_list() def get_lang_by_flag(self, flag): return self.lang.get_lang_by_flag(flag) def get_q_array(self, chat_id, lang): data = [] for elem in self.json_array[lang]: string = elem if "answer" in self.json_array[lang][elem] and self.json_array[ lang][elem]["answer"] != "BANNED" and self.json_array[ lang][elem]["answer"] != "": string += " -> " + self.json_array[lang][elem]["answer"] if chat_id in self.json_array[lang][elem]["ids"]: data.append(string) return data def set_lang_keyboard(self, array): return self.lang.set_keyboard(array) def write_data(self): self.database.write_data() def write_stud_lang(self, students, lang): self.database.write_stud_lang(self.name, students, lang) def get_lang(self): return self.lang def get_database(self): return self.database def get_string(self, lang, string, xxx=None, yyy=None): return self.lang.get_string(lang, string, xxx, yyy) def get_questions_array(self, array): data = {} lang_array = ["it", "de", "en", "es", "fr"] for lang in lang_array: if lang in array: data[lang] = array[lang]["questions"] return data def get_real_node(self, lang, question, lang_class): if lang in self.json_array: elem = self.lang.match_array(question, lang, self.json_array[lang]) if elem != None: return self.name, elem for node in self.parents: node.get_real_node(lang, question, lang_class) return None, None def add_chat_id(self, question, lang, id): if lang in self.json_array and question in self.json_array[lang]: if id not in self.json_array[lang][question]["ids"]: self.json_array[lang][question]["ids"].append(id) return True for p in self.parents: if p.add_chat_id(question, lang, id): return True return False def set_student_id(self, vett): self.id_commands = vett def get_student_id(self): return self.id_commands def set_formatted_data(self): data = {} data["banned"] = self.bannedUser data["hash"] = self.hash data["token"] = self.token lang_array = ["it", "de", "en", "es", "fr"] for lang in lang_array: data[lang] = {} if lang in self.students: data[lang]["students"] = self.students[lang] if lang in self.teachers: data[lang]["teachers"] = self.teachers[lang] if lang in self.collaborators: data[lang]["collaborators"] = self.collaborators[lang] data[lang]["questions"] = self.json_array[lang] self.database.put("/bots/students", name=self.node_name, data=data) def sub_set_banned_users(self, lang_str, elem, users): if "answer" in self.json_array[lang_str][elem] and self.json_array[ lang_str][elem]["answer"] == "BANNED": for chat_id in self.json_array[lang_str][elem]["ids"]: if chat_id in users: users[chat_id] += 1 else: users[chat_id] = 1 return users def set_banned_stud(self): users = {} banned = [] for lang_str in self.json_array: for elem in self.json_array[lang_str]: users = self.sub_set_banned_users(lang_str, elem, users) for chat_id in users: if users[chat_id] > 10: banned.append(chat_id) self.database.set_banned_stud(self.name, banned) return banned def set_qid(self, chat_id, from_id, txt): if chat_id not in self.questions: self.questions[chat_id] = {} self.questions[chat_id][from_id] = txt def set_rv_comment(self, question, comment, lang): if lang not in self.json_array or question not in self.json_array[lang]: return False if "revision" not in self.json_array[lang][question]: self.json_array[lang][question]["revision"] = [] if self.lang.match_array( comment, lang, self.json_array[lang][question]["revision"]) == None: self.json_array[lang][question]["revision"].append(comment) self.database.set_questions_array(self.json_array[lang], self.name, lang) return True return False def set_response(self, lang, question, txt): if lang not in self.json_array: return None if question not in self.json_array[lang]: return None self.json_array[lang][question]["answer"] = txt self.database.set_questions_array(self.json_array[lang], self.name, lang) return question def get_qid(self, chat_id, from_id): if chat_id not in self.questions: return None if from_id not in self.questions[chat_id]: return None return self.questions[chat_id][from_id] def del_qid(self, chat_id, from_id): del self.questions[chat_id][from_id] if len(self.questions[chat_id]) == 0: del self.questions[chat_id] def get_ancestors(self): data = [] data.append(self) for elem in self.parents: data += elem.get_ancestors() return data def get_heirs(self): data = [] data.append(self) for elem in self.sons: data += elem.get_heirs() return data def get_teach_coll(self): data = [] for lang in self.teachers: data += self.teachers[lang] for lang in self.collaborators: data += self.collaborators[lang] return data def get_res_array(self, lang, condition): data = [] if lang not in self.json_array: return data for elem in self.json_array[lang]: if (condition == "FREE" and self.json_array[lang][elem]["answer"] == '') or ( condition == "BANNED" and self.json_array[lang][elem]["answer"] == "BANNED"): data.append(elem) elif condition == "ANSWER" and self.json_array[lang][elem][ "answer"] != '' and self.json_array[lang][elem][ "answer"] != "BANNED": data.append(elem + " -> " + self.json_array[lang][elem]["answer"]) return data def sub_del_teachers(self, data, elem, lang, lang_class, bot): if elem not in self.teachers[lang] and len(self.teachers[lang]) > 0: data[lang] = self.teachers[lang] if elem in self.teachers[lang]: if len(self.teachers[lang]) > 1: data[lang] = [] for id in self.teachers[lang]: if id != elem: data[lang].append(id) else: self.send_notification(lang_class, lang, bot, False) return data def del_teachers(self, vett, lang_class, bot): for elem in vett: data = {} for lang in self.teachers: data = self.sub_del_teachers(data, elem, lang, lang_class, bot) self.teachers = data def sub_del_collaborators(self, data, elem, lang, lang_class, bot): if elem not in self.collaborators[lang] and len( self.collaborators[lang]) > 0: data[lang] = self.collaborators[lang] if elem in self.collaborators[lang]: if len(self.collaborators[lang]) > 1: data[lang] = [] for id in self.collaborators[lang]: if id != elem: data[lang].append(id) else: self.send_notification(lang_class, lang, bot, False) return data def del_collaborators(self, vett, lang_class, bot): for elem in vett: data = {} for lang in self.collaborators: data = self.sub_del_collaborators(data, elem, lang, lang_class, bot) self.collaborators = data def sub_del_students(self, data, elem, lang): if elem not in self.students[lang] and len(self.students[lang]) > 0: data[lang] = self.students[lang] if elem in self.students[lang] and len(self.students[lang]) > 1: data[lang] = [] for id in self.students[lang]: if id != elem: data[lang].append(id) return data def del_students(self, vett): for elem in vett: data = {} for lang in self.students: data = self.sub_del_students(data, elem, lang) self.students = data def add_teachers(self, vett, lang_str, lang, bot=None): if bot != None: self.del_teachers(vett, lang, bot) self.del_collaborators(vett, lang, bot) if len(vett) == 0: return if bot != None: self.send_notification(lang, lang_str, bot) if lang_str not in self.teachers: self.teachers[lang_str] = [] for elem in vett: if elem not in self.teachers[lang_str]: self.teachers[lang_str].append(elem) def add_collaborators(self, vett, lang_str, lang, bot=None): if bot != None: self.del_teachers(vett, lang, bot) self.del_collaborators(vett, lang, bot) if len(vett) == 0: return if bot != None: self.send_notification(lang, lang_str, bot) if lang_str not in self.collaborators: self.collaborators[lang_str] = [] for elem in vett: if elem not in self.collaborators[lang_str]: self.collaborators[lang_str].append(elem) def add_students(self, vett, lang): self.del_students(vett) if len(vett) == 0: return if lang not in self.students: self.students[lang] = [] for elem in vett: if elem not in self.students[lang]: self.students[lang].append(elem) def get_toc_lang(self, id): for lang in self.collaborators: if id in self.collaborators[lang]: return lang for lang in self.teachers: if id in self.teachers[lang]: return lang return None def set_hash(self, hash): self.hash = hash def get_hash(self): return self.hash def change(self, node1, node2): for num in range(0, len(self.sons)): if self.sons[num] == node1: self.sons[num] = node2 for num in range(0, len(self.sons)): if self.parents[num] == node1: self.parents[num] = node2 def is_in_array(self, string, array, lang, lang_str): for elem in array: if lang.calculate_similarity(string, elem, lang_str) > 0.8: return True return False def merge_arrays(self, array1, array2, lang, lang_str): if len(array1) == 0: return array2 data = {} data = array1 for elem in array2: val = [] for e_data in data: if lang.calculate_similarity(e_data, elem, lang_str) < 0.8: val.append(elem) for e_val in val: data[e_val] = array2[e_val] return data def send_notification(self, lang, lang_str, bot, new=True): string = "" if new: string = "new_lang" else: string = "del_lang" if (lang_str not in self.collaborators or len(self.collaborators[lang_str]) == 0) and (lang_str not in self.teachers or len(self.teachers[lang_str]) == 0): for elem in self.students: for chat_id in self.students[elem]: bot.sendMessage( chat_id, lang.get_string(elem, string, xxx=lang.get_string(elem, lang_str))) def calc_distance(self, lang, lang_str): data = {} if lang_str in self.json_array: data[0] = self.json_array[lang_str] for elem in self.parents: array = elem.calc_distance(lang_str) for num in array: if num + 1 not in array: data[num + 1] = {} data[num + 1] = self.merge_arrays(data[num + 1], array[num], lang, lang_str) return data def add_question(self, txt, lang, res=""): if lang not in self.json_array: self.json_array[lang] = {} self.json_array[lang][txt] = {} self.json_array[lang][txt]["answer"] = res self.json_array[lang][txt]["ids"] = [] def add_id(self, from_id, chat_id, num): if from_id == chat_id: self.id_commands[chat_id] = num else: if chat_id not in self.id_commands: self.id_commands[chat_id] = {} self.id_commands[chat_id][from_id] = num else: self.id_commands[chat_id][from_id] = num def del_id(self, from_id, chat_id): if from_id == chat_id: if chat_id in self.id_commands: del self.id_commands[chat_id] else: if chat_id in self.id_commands and from_id in self.id_commands[ chat_id]: del self.id_commands[chat_id][from_id] if len(self.id_commands[chat_id]) == 0: del self.id_commands[chat_id] def check_id(self, from_id, chat_id): ret_val = 0 if from_id == chat_id: if chat_id in self.id_commands: ret_val = self.id_commands[chat_id] else: if chat_id in self.id_commands and from_id in self.id_commands[ chat_id]: ret_val = self.id_commands[chat_id][from_id] return ret_val def ret_q_vett(self, lang): vett = [] if lang in self.json_array: vett = self.json_array[lang] return vett def get_trans_array(self, src, dst): vett = self.ret_q_vett(src) vett1 = self.ret_q_vett(dst) array = [] for elem in vett: string = self.lang.translate(elem, src, dst) if vett[elem]["answer"] != "BANNED" and vett[elem][ "answer"] != "" and not self.is_in_array( string, vett1, self.lang, dst): string = "\"" + string + "\" -> \"" + self.lang.translate( vett[elem]["answer"], src, dst) + "\"" array.append(string) return array