Merge pull request #71 from ThomasRubini/refactor

This commit is contained in:
Thomas Rubini 2023-02-11 22:44:05 +01:00 committed by GitHub
commit dbf4086e56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 169 additions and 318 deletions

4
app.py
View File

@ -2,7 +2,9 @@
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv() load_dotenv()
from truthinquiry import APP as app # the variable 'app' is detected by `flask run` from truthinquiry import create_app
app = create_app()
if __name__ == "__main__": if __name__ == "__main__":
app.run() app.run()

View File

@ -6,8 +6,9 @@ from dotenv import load_dotenv
# Load dotenv file # Load dotenv file
load_dotenv() load_dotenv()
from truthinquiry import APP from truthinquiry import create_app
test_app = APP.test_client() app = create_app()
app_client = app.test_client()
class TestException(Exception): class TestException(Exception):
__test__ = False __test__ = False
@ -33,7 +34,7 @@ class User:
def create_game(user:User): def create_game(user:User):
data = {"username":user.username} data = {"username":user.username}
responseObject = test_app.post("/api/v1/createGame",data=data) responseObject = app_client.post("/api/v1/createGame",data=data)
if responseObject.status_code != 200: if responseObject.status_code != 200:
raise TestException("status code is not 200") raise TestException("status code is not 200")
content = responseObject.json content = responseObject.json
@ -47,7 +48,7 @@ def create_game(user:User):
def join_game(user:User,game_id:str): def join_game(user:User,game_id:str):
data = {"username":user.username,"game_id":game_id} data = {"username":user.username,"game_id":game_id}
responseObject = test_app.post("/api/v1/joinGame",data=data) responseObject = app_client.post("/api/v1/joinGame",data=data)
if responseObject.status_code != 200: if responseObject.status_code != 200:
raise TestException("status code is not 200") raise TestException("status code is not 200")
content = responseObject.json content = responseObject.json
@ -58,7 +59,7 @@ def join_game(user:User,game_id:str):
return True return True
def start_game(user:User): def start_game(user:User):
responseObject = test_app.post("/api/v1/startGame") responseObject = app_client.post("/api/v1/startGame")
if responseObject.status_code != 200: if responseObject.status_code != 200:
raise TestException("status code is not 200") raise TestException("status code is not 200")
content = responseObject.json content = responseObject.json
@ -101,7 +102,7 @@ def test_that_two_person_having_the_same_pseudo_creating_two_games_results_in_tw
def test_that_not_sending_a_username_results_in_an_error(): def test_that_not_sending_a_username_results_in_an_error():
responseObject = test_app.post("/api/v1/createGame") responseObject = app_client.post("/api/v1/createGame")
assert responseObject.status_code == 200 assert responseObject.status_code == 200
assert responseObject.json["error"] != 0 assert responseObject.json["error"] != 0
@ -150,20 +151,20 @@ def test_that_people_cant_join_if_the_username_is_already_used():
def test_that_people_joining_without_sending_any_data_results_in_an_error(): def test_that_people_joining_without_sending_any_data_results_in_an_error():
game_id = create_game(User("neoxyde")) game_id = create_game(User("neoxyde"))
responseObject = test_app.post("/api/v1/joinGame") responseObject = app_client.post("/api/v1/joinGame")
assert responseObject.status_code == 200 assert responseObject.status_code == 200
assert responseObject.json["error"] != 0 assert responseObject.json["error"] != 0
def test_that_people_joining_without_sending_a_game_id_results_in_an_error(): def test_that_people_joining_without_sending_a_game_id_results_in_an_error():
data={"username":"neomblic"} data={"username":"neomblic"}
responseObject = test_app.post("/api/v1/joinGame",data=data) responseObject = app_client.post("/api/v1/joinGame",data=data)
assert responseObject.status_code == 200 assert responseObject.status_code == 200
assert responseObject.json["error"] != 0 assert responseObject.json["error"] != 0
def test_that_people_joining_without_sending_an_username_still_results_in_an_error(): def test_that_people_joining_without_sending_an_username_still_results_in_an_error():
game_id = create_game(User("neonyx")) game_id = create_game(User("neonyx"))
data={"game_id":game_id} data={"game_id":game_id}
responseObject = test_app.post("/api/v1/joinGame",data=data) responseObject = app_client.post("/api/v1/joinGame",data=data)
assert responseObject.status_code == 200 assert responseObject.status_code == 200
assert responseObject.json["error"] != 0 assert responseObject.json["error"] != 0

View File

@ -1,65 +1,34 @@
import os import os
import flask import flask
from flask_socketio import SocketIO
from truthinquiry import discord_bot
from sqlalchemy import engine as eg from sqlalchemy import engine as eg
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from truthinquiry.app import TruthInquiryApp
class TruthInquiryApp(flask.Flask): from truthinquiry.ext.database import db
""" from truthinquiry.ext.socketio import socket_io
Main class of the app from truthinquiry.ext.discord_bot import discord_bot
A single instance 'APP' of this class will be created and shared across the files
The class itself is a child class of flask.Flask and has property representing other services
:attr SocketIO socketio_app: the SocketIO service
:attr DiscordBot discord_bot: the Discord Bot service
"""
def __init__(self):
super().__init__("truthinquiry")
self.games_list = {}
self.config["SECRET_KEY"] = os.getenv("FLASK_SECRET")
self.setupdb()
self.socketio_app = SocketIO(
self,
cors_allowed_origins=(os.getenv("ORIGIN"), "http://127.0.0.1:5000", "http://localhost:5000")
)
self.discord_bot = discord_bot.DiscordBot()
token = os.getenv("DISCORD_BOT_TOKEN")
if token:
self.discord_bot.start(token)
else:
print("No token set. Not starting discord bot")
def setupdb(self):
db_url = eg.URL.create(
"mariadb+pymysql",
username=os.getenv("DB_USER"),
password=os.getenv("DB_PASSWORD"),
host=os.getenv("DB_HOST"),
port=os.getenv("DB_PORT"),
database=os.getenv("DB_DBNAME")
)
self.config["SQLALCHEMY_DATABASE_URI"] = db_url
self.db = SQLAlchemy(self)
APP = TruthInquiryApp()
from truthinquiry.routes import routes_api, routes_ui, routes_socketio from truthinquiry.routes import routes_api, routes_ui, routes_socketio
APP.register_blueprint(routes_api.routes_api, url_prefix="/api/v1") def register_extensions(app):
APP.register_blueprint(routes_ui.routes_ui, url_prefix="/") db.init_app(app)
socket_io.init_app(app)
discord_bot.try_start()
def register_routes(app):
app.register_blueprint(routes_api.routes_api, url_prefix="/api/v1")
app.register_blueprint(routes_ui.routes_ui, url_prefix="/")
def create_app():
app = TruthInquiryApp()
register_extensions(app)
register_routes(app)
return app

22
truthinquiry/app.py Normal file
View File

@ -0,0 +1,22 @@
import os
import flask
from truthinquiry.ext import discord_bot
class TruthInquiryApp(flask.Flask):
"""
Main class of the app
A single instance 'APP' of this class will be created and shared across the files
The class itself is a child class of flask.Flask and has property representing other services
:attr SocketIO socketio_app: the SocketIO service
:attr DiscordBot discord_bot: the Discord Bot service
"""
def __init__(self):
super().__init__("truthinquiry")
self.games_list = {}
self.config["SECRET_KEY"] = os.getenv("FLASK_SECRET")

View File

@ -1,6 +1,31 @@
from truthinquiry import APP import os
db = APP.db import random
from sqlalchemy import engine as eg
from flask_sqlalchemy import SQLAlchemy
class Database(SQLAlchemy):
def __init__(self):
super().__init__()
def init_app(self, app):
db_url = eg.URL.create(
"mariadb+pymysql",
username=os.getenv("DB_USER"),
password=os.getenv("DB_PASSWORD"),
host=os.getenv("DB_HOST"),
port=os.getenv("DB_PORT"),
database=os.getenv("DB_DBNAME")
)
app.config["SQLALCHEMY_DATABASE_URI"] = db_url
super().init_app(app)
with app.app_context():
self.create_all()
db = Database()
class Locale(db.Model): class Locale(db.Model):
__tablename__ = 'T_LOCALE' __tablename__ = 'T_LOCALE'
@ -70,6 +95,7 @@ class Npc(db.Model):
__tablename__ = "T_NPC" __tablename__ = "T_NPC"
NPC_ID = db.Column(db.Integer, primary_key=True) NPC_ID = db.Column(db.Integer, primary_key=True)
NAME_LID = db.Column(db.Integer, db.ForeignKey("T_LOCALE.TEXT_ID")) NAME_LID = db.Column(db.Integer, db.ForeignKey("T_LOCALE.TEXT_ID"))
LOCALE = db.relationship("Locale")
def __init__(self, NPC_ID, NAME_LID): def __init__(self, NPC_ID, NAME_LID):
self.NPC_ID = NPC_ID self.NPC_ID = NPC_ID
@ -83,6 +109,11 @@ class Trait(db.Model):
__tablename__ = "T_TRAIT" __tablename__ = "T_TRAIT"
TRAIT_ID = db.Column(db.Integer, primary_key=True) TRAIT_ID = db.Column(db.Integer, primary_key=True)
NAME_LID = db.Column(db.Integer, db.ForeignKey("T_LOCALE.TEXT_ID")) NAME_LID = db.Column(db.Integer, db.ForeignKey("T_LOCALE.TEXT_ID"))
DESC_LID = db.Column(db.Integer, db.ForeignKey("T_LOCALE.TEXT_ID"))
Name = db.relationship("Locale",foreign_keys=[NAME_LID])
Desc = db.relationship("Locale",foreign_keys=[DESC_LID])
def __init__(self, TRAIT_ID, NAME_LID): def __init__(self, TRAIT_ID, NAME_LID):
self.TRAIT_ID = TRAIT_ID self.TRAIT_ID = TRAIT_ID
@ -92,21 +123,18 @@ class Trait(db.Model):
return f"{self.TRAIT_ID} {self.NAME_LID}" return f"{self.TRAIT_ID} {self.NAME_LID}"
class Reaction(db.db.Model): class Reaction(db.Model):
__tablename__ = "T_REACTION" __tablename__ = "T_REACTION"
REACTION_ID = db.Column(db.Integer, primary_key=True) REACTION_ID = db.Column(db.Integer, primary_key=True)
NPC_ID = db.Column(db.Integer, db.ForeignKey("T_NPC.NPC_ID"), primary_key=True) NPC_ID = db.Column(db.Integer, db.ForeignKey("T_NPC.NPC_ID"), primary_key=True)
TRAIT_ID = db.Column(db.Integer, db.ForeignKey("T_TRAIT.TRAIT_ID"), primary_key=True) TRAIT_ID = db.Column(db.Integer, db.ForeignKey("T_TRAIT.TRAIT_ID"), primary_key=True)
DESC_LID = db.Column(db.Integer, db.ForeignKey("T_LOCALE.TEXT_ID"))
LOCALE = db.relationship("Locale")
NPC = db.relationship("Npc") NPC = db.relationship("Npc")
TRAIT = db.relationship("Trait") TRAIT = db.relationship("Trait")
def __init__(self, REACTION_ID, DESC_LID, NPC_ID, TRAIT_ID): def __init__(self, REACTION_ID, NPC_ID, TRAIT_ID):
self.REACTION_ID = REACTION_ID self.REACTION_ID = REACTION_ID
self.DESC_LID = DESC_LID
self.NPC_ID = NPC_ID self.NPC_ID = NPC_ID
self.TRAIT_ID = TRAIT_ID self.TRAIT_ID = TRAIT_ID
def __str__(self) -> str: def __str__(self) -> str:
return f"{self.REACTION_ID} {self.DESC_LID} {self.NPC_ID} {self.TRAIT_ID}" return f"{self.REACTION_ID} {self.NPC_ID} {self.TRAIT_ID}"

View File

@ -1,9 +1,4 @@
import os from truthinquiry.ext.database import *
import random
import truthinquiry.logic.data_persistance.tables as tables
from truthinquiry import APP
db = APP.db
def get_text_from_lid(lang: str, lid: int) -> str: def get_text_from_lid(lang: str, lid: int) -> str:
""" """
@ -13,23 +8,23 @@ def get_text_from_lid(lang: str, lid: int) -> str:
:param lid: the locale id the get the text from :param lid: the locale id the get the text from
:return: the text associated to the lang and lid :return: the text associated to the lang and lid
""" """
return db.session.query(tables.Locale).filter_by(LANG=lang, TEXT_ID=lid).one().TEXT return db.session.query(Locale).filter_by(LANG=lang, TEXT_ID=lid).one().TEXT
def get_random_place() -> tables.Place: def get_random_place() -> Place:
""" """
Returns a random place from the database. Returns a random place from the database.
:return: a Place object :return: a Place object
""" """
return random.choice(db.session.query(tables.Place).all()) return random.choice(db.session.query(Place).all())
def get_random_npc() -> tables.Npc : def get_random_npc() -> Npc :
""" """
Returns a random npc from the database Returns a random npc from the database
:return: a Npc object :return: a Npc object
""" """
return random.choice(db.session.query(tables.Npc).all()) return random.choice(db.session.query(Npc).all())
def get_npc_random_trait_id(npc_id: int) -> int: def get_npc_random_trait_id(npc_id: int) -> int:
""" """
@ -38,11 +33,11 @@ def get_npc_random_trait_id(npc_id: int) -> int:
:param npc_id: the npc to get the reaction from :param npc_id: the npc to get the reaction from
:return: a reaction identified by it's trait id :return: a reaction identified by it's trait id
""" """
reactions = db.session.query(tables.Reaction).filter_by(NPC_ID=npc_id.NPC_ID).all() reactions = db.session.query(Reaction).filter_by(NPC_ID=npc_id.NPC_ID).all()
reaction = random.choice(reactions) reaction = random.choice(reactions)
return reaction.TRAIT_ID return reaction.TRAIT_ID
def get_npc_random_answer(npc_id:int, qa_type:int) -> tables.Answer : def get_npc_random_answer(npc_id:int, qa_type:int) -> Answer :
""" """
Returns a random answser from a given npc and question type Returns a random answser from a given npc and question type
@ -50,17 +45,17 @@ def get_npc_random_answer(npc_id:int, qa_type:int) -> tables.Answer :
:param qa_type: the type of the question :param qa_type: the type of the question
:return: an Answer object :return: an Answer object
""" """
answers = db.session.query(tables.Answer).filter_by(QA_TYPE=qa_type,NPC_ID=npc_id.NPC_ID).all() answers = db.session.query(Answer).filter_by(QA_TYPE=qa_type,NPC_ID=npc_id.NPC_ID).all()
return random.choice(answers) return random.choice(answers)
def get_random_question(qa_type: int) -> tables.Question : def get_random_question(qa_type: int) -> Question :
""" """
Returns a random inspector question from a question type Returns a random inspector question from a question type
:param qa_type: the type of the question :param qa_type: the type of the question
:return: a Question object :return: a Question object
""" """
answers = db.session.query(tables.Question).filter_by(QUESTION_TYPE=qa_type).all() answers = db.session.query(Question).filter_by(QUESTION_TYPE=qa_type).all()
return random.choice(answers) return random.choice(answers)
def get_trait_from_text(text: str) -> int: def get_trait_from_text(text: str) -> int:
@ -70,20 +65,20 @@ def get_trait_from_text(text: str) -> int:
:param text: the text representation of the trait in any lang :param text: the text representation of the trait in any lang
:return: the trait_id linked to this text :return: the trait_id linked to this text
""" """
trait_lid = db.session.query(tables.Locale).filter_by(TEXT=text).one().TEXT_ID trait_lid = db.session.query(Locale).filter_by(TEXT=text).one().TEXT_ID
return db.session.query(tables.Trait).filter_by(NAME_LID=trait_lid).one().TRAIT_ID return db.session.query(Trait).filter_by(NAME_LID=trait_lid).one().TRAIT_ID
def get_trait_from_trait_id(trait_id: int) -> tables.Trait: def get_trait_from_trait_id(trait_id: int) -> Trait:
""" """
Gets a Trait object from a trait_id Gets a Trait object from a trait_id
:param trait_id: the id of the trait to search for :param trait_id: the id of the trait to search for
:return: a Trait object :return: a Trait object
""" """
trait = db.session.query(tables.Trait).filter_by(TRAIT_ID=trait_id).one() trait = db.session.query(Trait).filter_by(TRAIT_ID=trait_id).one()
return trait return trait
def get_reaction_description(lang,npc_id,trait_id) -> str: def get_reaction_description(lang, npc_id, trait_id) -> str:
""" """
Returns the description of the reaction of a given npc in the language specified by the parametter lang Returns the description of the reaction of a given npc in the language specified by the parametter lang
@ -92,8 +87,8 @@ def get_reaction_description(lang,npc_id,trait_id) -> str:
:trait_id: the trait associated to the reaction to get the description from :trait_id: the trait associated to the reaction to get the description from
:return: the description in the given language :return: the description in the given language
""" """
desc_lid = db.session.query(tables.Reaction).filter_by(NPC_ID=npc_id,TRAIT_ID=trait_id).one().DESC_LID desc_lid = db.session.query(Reaction).filter_by(NPC_ID=npc_id,TRAIT_ID=trait_id).one().DESC_LID
return get_text_from_lid(lang,desc_lid) return get_text_from_lid(lang, desc_lid)
def get_traits(lang: str) -> list: def get_traits(lang: str) -> list:
""" """
@ -103,6 +98,6 @@ def get_traits(lang: str) -> list:
:return: a list of string reprensentation of the reactions traits :return: a list of string reprensentation of the reactions traits
""" """
traits = [] traits = []
for trait in db.session.query(tables.Trait).all(): for trait in db.session.query(Trait).all():
traits.append(get_text_from_lid(lang,trait.NAME_LID)) traits.append(get_text_from_lid(lang,trait.NAME_LID))
return traits return traits

View File

@ -1,8 +1,9 @@
import os
import threading import threading
import asyncio import asyncio
import discord import discord
import truthinquiry import truthinquiry.app as app
class DiscordBot: class DiscordBot:
@ -23,10 +24,10 @@ class DiscordBot:
print('Discord bot connected !') print('Discord bot connected !')
self.event_loop = asyncio.get_event_loop() self.event_loop = asyncio.get_event_loop()
self.__setup__channel__() self.__setup__channel()
self.update_games_presence() self.update_games_presence()
def __setup__channel__(self) -> None: def __setup__channel(self) -> None:
""" """
Setup the channel that the bot will send message in Setup the channel that the bot will send message in
""" """
@ -35,10 +36,18 @@ class DiscordBot:
else: else:
print("Could not find channel #bot") print("Could not find channel #bot")
def start(self, token): def try_start(self):
thr = threading.Thread(target=self.bot.run, args=(token,)) """
thr.start() Start the discord bot if the environment provides a token, else do nothing
return thr """
token = os.getenv("DISCORD_BOT_TOKEN")
if token:
thr = threading.Thread(target=self.bot.run, args=(token,))
thr.start()
return thr
else:
print("Token not present ! Discord bot not starting")
return None
def API(func): def API(func):
""" """
@ -56,7 +65,7 @@ class DiscordBot:
""" """
Update the bot's status using the app's current context Update the bot's status using the app's current context
""" """
games_n = len(truthinquiry.APP.games_list) games_n = len(app.APP.games_list)
activity_name = f"Handling {games_n} game{'' if games_n==1 else 's'} !" activity_name = f"Handling {games_n} game{'' if games_n==1 else 's'} !"
activity = discord.Activity(name=activity_name, type=discord.ActivityType.watching) activity = discord.Activity(name=activity_name, type=discord.ActivityType.watching)
await self.bot.change_presence(activity=activity) await self.bot.change_presence(activity=activity)
@ -70,3 +79,5 @@ class DiscordBot:
await self.__channel__.send(text) await self.__channel__.send(text)
else: else:
print("channel not defined, not sending discord message") print("channel not defined, not sending discord message")
discord_bot = DiscordBot()

View File

@ -0,0 +1,7 @@
import os
from flask_socketio import SocketIO
socket_io = SocketIO(
cors_allowed_origins=(os.getenv("ORIGIN"), "http://127.0.0.1:5000", "http://localhost:5000")
)

View File

@ -1,36 +0,0 @@
from tables import Answer
ANSWERS = [
Answer(1, 0, 1, 1),
Answer(2, 0, 1, 2),
Answer(3, 1, 1, 3),
Answer(4, 1, 1, 4),
Answer(5, 0, 2, 6),
Answer(6, 0, 2, 7),
Answer(7, 1, 2, 8),
Answer(8, 1, 2, 9),
Answer(9, 0, 3, 11),
Answer(10, 0, 3, 12),
Answer(11, 1, 3, 13),
Answer(12, 1, 3, 14),
Answer(13, 0, 4, 16),
Answer(14, 0, 4, 17),
Answer(15, 1, 4, 18),
Answer(16, 1, 4, 19),
Answer(17, 0, 5, 21),
Answer(18, 0, 5, 22),
Answer(19, 1, 5, 23),
Answer(20, 1, 5, 24),
Answer(21, 0, 6, 26),
Answer(22, 0, 6, 27),
Answer(23, 1, 6, 28),
Answer(24, 1, 6, 29),
Answer(25, 0, 7, 31),
Answer(26, 0, 7, 32),
Answer(27, 1, 7, 33),
Answer(28, 1, 7, 34),
Answer(29, 0, 8, 36),
Answer(30, 0, 8, 37),
Answer(31, 1, 8, 38),
Answer(32, 1, 8, 39)
]

View File

@ -1,66 +0,0 @@
from tables import Locale
LOCALES = [
Locale(0,"FR","Le Médecin"),
Locale(1,"FR","Il y avait {SALLE} ça m'a intrigué."),
Locale(2,"FR","{SALLE} avait l'air sympa donc j'y suis allé."),
Locale(3,"FR","Il me semble qu'il y avait {NPC}."),
Locale(4,"FR","Je suis pratiquement sûr que j'étais avec {NPC}."),
Locale(5,"FR","Le Diplomate"),
Locale(6,"FR","Je profitais d'une collation dans {SALLE}."),
Locale(7,"FR","J'admirais la décoration subtile de {SALLE} ... je m'en inspirerais pour chez moi."),
Locale(8,"FR","Je m'instruisais auprès de {NPC}."),
Locale(9,"FR","Avec {NPC} pour exposer nos différents points de vus sur divers sujets."),
Locale(10,"FR","Le Combattant"),
Locale(11,"FR","{SALLE} nous a servi de salle de duel."),
Locale(12,"FR","J'ai festoyé dans {SALLE}."),
Locale(13,"FR","On faisait un bras de fer avec {NPC}."),
Locale(14,"FR","{NPC} et moi nous sommes engagés dans une joute verbale des plus palpitante."),
Locale(15,"FR","La Duchesse"),
Locale(16,"FR","Pour votre gouverne je me trouvais dans {SALLE}."),
Locale(17,"FR","Si vous voulez le savoir ... j'étais en train de me reposer dans {SALLE}."),
Locale(18,"FR","{NPC} me tenait compagnie."),
Locale(19,"FR","J'étais avec {NPC}."),
Locale(20,"FR","La Diva"),
Locale(21,"FR","{SALLE} me semblait être la plus belle pièce de la maison."),
Locale(22,"FR","Je buvais un verre dans {SALLE}."),
Locale(23,"FR","Je profitais de la compagnie de {NPC}."),
Locale(24,"FR","J'étais avec {NPC} à partager une délicieuse conversation ainsi qu'une coupe de champagne."),
Locale(25,"FR","La Parieuse"),
Locale(26,"FR","J'avais monté une table de jeu dans {SALLE}."),
Locale(27,"FR","{SALLE} est tout de même plus agréable une fois changé(e), en casino."),
Locale(28,"FR","Vous saviez que {NPC} était incroyable avec des cartes à la main ?"),
Locale(29,"FR","Si vous tenez à votre argent ne jouez jamais au poker avec {NPC}."),
Locale(30,"FR","L'Agent"),
Locale(31,"FR","On pouvait me retrouver dans {SALLE}."),
Locale(32,"FR","{SALLE}"),
Locale(33,"FR","J'étais avec {NPC} au moment des faits."),
Locale(34,"FR","{NPC}"),
Locale(35,"FR","La Voyageuse"),
Locale(36,"FR","{SALLE} me semblait un bon endroit pour me poser"),
Locale(37,"FR","{SALLE} me rappelait mes voyages."),
Locale(38,"FR","Nous organisions notre prochain voyage avec {NPC}."),
Locale(39,"FR","Avec {NPC} on parlait des lieux que lon avait visités. Cétait très instructif."),
Locale(100,"FR","Ce manoir est plutôt grand ... vous pouvez me dire où vous étiez?"),
Locale(101,"FR","Vous étiez où au moment des faits?"),
Locale(102,"FR","Dans quelle salle étiez-vous pendant que le coffre était subtilisé ?"),
Locale(105,"FR","Etiez-vous seul au moment des faits ?"),
Locale(106,"FR","Quelquun peu valider vous alibi pour la soirée ?"),
Locale(107,"FR","Vous étiez accompagné ce soir-là ?"),
Locale(120,"FR","méfiant(e),"),
Locale(110,"FR","Un maintien rigide des traits du visage, un regard de travers. Une crispation des sourcils et parfois des rides autour de la bouche. Ces caractéristiques sont synonymes d'incompréhension ou de peur de ce que peut nous annoncer la personne en face."),
Locale(121,"FR","heureux(se),"),
Locale(111,"FR","Un visage décontracté et ouvert, les muscles des joues contractés qui laissent apparaître un sourire. On le détermine aussi par des yeux plissés en accord avec les sourcils qui marquent la différence avec un faux sourire où les sourcils ne sont pas contractés. Cela montre une complicité avec l'interlocuteur ou un moyen de ne pas laisser paraître ses réelles émotions."),
Locale(122,"FR","triste"),
Locale(112,"FR","Des sourcils contractés et resserrés vers le centre du visage auxquels s'ajoute un regard vide ou fuyant de l'interlocuteur, soit en fermant les yeux soit en évitant un contact visuel. Ces caractéristiques témoignent d'un sentiment puissant ou du fait d'être atteint par les propos ou accusations de son interlocuteur."),
Locale(123,"FR","stressé(e),"),
Locale(113,"FR","Un visage crispé qui s'accompagne habituellement de sourcils froncés, un regard perdu qui se détourne de celui de son interlocuteur. Cela s'accompagne souvent de mouvements de la tête et de la bouche en se mordant les lèvres par exemple. Tout cela traduit une difficulté de concentration ou une peur de ce qu'annonce ou peut nous annoncer l'interlocuteur en face."),
Locale(124,"FR","surpris(e),"),
Locale(114,"FR","Généralement par des yeux écarquillés et un haussement des sourcils. Cela peut également se distinguer par une bouche ouverte ou, au contraire, des dents serrées et parfois par un relâchement du visage. Ces caractéristiques correspondent à un choc, une incompréhension ou encore un étonnement de ce que voit ou entend la personne."),
Locale(130,"FR","Le salon"),
Locale(131,"FR","La salle de réception"),
Locale(132,"FR","Le hall d'entrée"),
Locale(133,"FR","La cuisine"),
Locale(134,"FR","La chambre du maître"),
Locale(135,"FR","Le jardin")
]

View File

@ -1,12 +0,0 @@
from tables import Npc
NPCS = [
Npc(1, 0),
Npc(2, 5),
Npc(3, 10),
Npc(4, 15),
Npc(5, 20),
Npc(6, 25),
Npc(7, 30),
Npc(8, 35)
]

View File

@ -1,10 +0,0 @@
from tables import Place
PLACES = [
Place(1, 130),
Place(2, 131),
Place(3, 132),
Place(4, 133),
Place(5, 134),
Place(6, 135)
]

View File

@ -1,10 +0,0 @@
from tables import Question
QUESTIONS = [
Question(1, 0, 100),
Question(2, 0, 101),
Question(3, 0, 102),
Question(4, 1, 105),
Question(5, 1, 106),
Question(6, 1, 107)
]

View File

@ -1,44 +0,0 @@
from tables import Reaction
REACTIONS = [
Reaction(1, 110, 1, 1),
Reaction(2, 110, 2, 1),
Reaction(3, 110, 3, 1),
Reaction(4, 110, 4, 1),
Reaction(5, 110, 5, 1),
Reaction(6, 110, 6, 1),
Reaction(7, 110, 7, 1),
Reaction(8, 110, 8, 1),
Reaction(9, 111, 1, 2),
Reaction(10, 111, 2, 2),
Reaction(11, 111, 3, 2),
Reaction(12, 111, 4, 2),
Reaction(13, 111, 5, 2),
Reaction(14, 111, 6, 2),
Reaction(15, 111, 7, 2),
Reaction(16, 111, 8, 2),
Reaction(17, 112, 1, 3),
Reaction(18, 112, 2, 3),
Reaction(19, 112, 3, 3),
Reaction(20, 112, 4, 3),
Reaction(21, 112, 5, 3),
Reaction(22, 112, 6, 3),
Reaction(23, 112, 7, 3),
Reaction(24, 112, 8, 3),
Reaction(25, 113, 1, 4),
Reaction(26, 113, 2, 4),
Reaction(27, 113, 3, 4),
Reaction(28, 113, 4, 4),
Reaction(29, 113, 5, 4),
Reaction(30, 113, 6, 4),
Reaction(31, 113, 7, 4),
Reaction(32, 113, 8, 4),
Reaction(33, 114, 1, 5),
Reaction(34, 114, 2, 5),
Reaction(35, 114, 3, 5),
Reaction(36, 114, 4, 5),
Reaction(37, 114, 5, 5),
Reaction(38, 114, 6, 5),
Reaction(39, 114, 7, 5),
Reaction(40, 114, 8, 5)
]

View File

@ -1,9 +0,0 @@
from tables import Trait
TRAITS = [
Trait(1, 120),
Trait(2, 121),
Trait(3, 122),
Trait(4, 123),
Trait(5, 124)
]

View File

@ -2,9 +2,10 @@ import string
import random import random
from typing import Union from typing import Union
from truthinquiry.logic.data_persistance.data_access import * from truthinquiry.ext.database import *
from truthinquiry import APP from truthinquiry.ext.database import dbutils
games_list = {}
def random_string(length: int) -> str: def random_string(length: int) -> str:
""" """
@ -81,9 +82,9 @@ class Game:
npcs[npc_id] = {} npcs[npc_id] = {}
npcs[npc_id]["name"] = self.gamedata["npcs"][npc_id]["name"] npcs[npc_id]["name"] = self.gamedata["npcs"][npc_id]["name"]
trait_id = self.reaction_table[npc_id] trait_id = self.reaction_table[npc_id]
trait = get_trait_from_trait_id(trait_id) trait = dbutils.get_trait_from_trait_id(trait_id)
npcs[npc_id]["reaction"] = get_text_from_lid("FR", trait.NAME_LID) npcs[npc_id]["reaction"] = dbutils.get_text_from_lid("FR", trait.NAME_LID)
npcs[npc_id]["description"] = get_reaction_description("FR", npc_id, trait.TRAIT_ID) npcs[npc_id]["description"] = dbutils.get_reaction_description("FR", npc_id, trait.TRAIT_ID)
player_results = data["player"] = {} player_results = data["player"] = {}
for member in self.members: for member in self.members:
player_results[member.username] = member.results player_results[member.username] = member.results
@ -179,7 +180,7 @@ def create_game(owner: str) -> Game:
game.owner = owner game.owner = owner
game.members.append(Member(owner)) game.members.append(Member(owner))
game.game_id = random_string(6) game.game_id = random_string(6)
APP.games_list[game.game_id] = game games_list[game.game_id] = game
return game return game
@ -190,8 +191,8 @@ def get_game(game_id: str) -> Union[Game, None]:
:param game_id: the id of the game to search :param game_id: the id of the game to search
:return: the Game object or None if not found :return: the Game object or None if not found
""" """
if game_id in APP.games_list: if game_id in games_list:
return APP.games_list[game_id] return games_list[game_id]
else: else:
return None return None
@ -216,7 +217,7 @@ def check_username(username: str) -> bool:
return True return True
def generate_npc_text(npc: tables.Npc, lang: str) -> dict: def generate_npc_text(npc: Npc, lang: str) -> dict:
""" """
Creates the dictionnary of a npc names and dialogs, it searches the npc's pool of answser for both question Creates the dictionnary of a npc names and dialogs, it searches the npc's pool of answser for both question
types types
@ -226,9 +227,9 @@ def generate_npc_text(npc: tables.Npc, lang: str) -> dict:
:return: a dictionnary object containing the npc's name and both answers :return: a dictionnary object containing the npc's name and both answers
""" """
data = {} data = {}
data["name"] = get_text_from_lid(lang, npc.NAME_LID) data["name"] = dbutils.get_text_from_lid(lang, npc.NAME_LID)
data["QA_0"] = get_text_from_lid(lang, get_npc_random_answer(npc, 0).TEXT_LID) data["QA_0"] = dbutils.get_text_from_lid(lang, dbutils.get_npc_random_answer(npc, 0).TEXT_LID)
data["QA_1"] = get_text_from_lid(lang, get_npc_random_answer(npc, 1).TEXT_LID) data["QA_1"] = dbutils.get_text_from_lid(lang, dbutils.get_npc_random_answer(npc, 1).TEXT_LID)
return data return data
@ -246,7 +247,7 @@ def generate_place_data(npc_list: list, places: list, lang: str) -> dict:
random.shuffle(npc_list) random.shuffle(npc_list)
for place in places: for place in places:
placedata = data[str(place.PLACE_ID)] = {} placedata = data[str(place.PLACE_ID)] = {}
placedata["name"] = get_text_from_lid(lang, place.NAME_LID) placedata["name"] = dbutils.get_text_from_lid(lang, place.NAME_LID)
placedata["npcs"] = [] placedata["npcs"] = []
for _ in npc_list: for _ in npc_list:
placedata["npcs"].append(npc_list.pop().NPC_ID) placedata["npcs"].append(npc_list.pop().NPC_ID)
@ -269,24 +270,24 @@ def generate_game_data(lang: str) -> tuple[dict, dict]:
reactions_table = {} reactions_table = {}
npcs = [] npcs = []
while len(npcs) != 5: while len(npcs) != 5:
npc = get_random_npc() npc = dbutils.get_random_npc()
if npc not in npcs: if npc not in npcs:
npcs.append(npc) npcs.append(npc)
for npc in npcs: for npc in npcs:
data["npcs"][str(npc.NPC_ID)] = generate_npc_text(npc, lang) data["npcs"][str(npc.NPC_ID)] = generate_npc_text(npc, lang)
reactions_table[str(npc.NPC_ID)] = get_npc_random_trait_id(npc) reactions_table[str(npc.NPC_ID)] = dbutils.get_npc_random_trait_id(npc)
places = [] places = []
while len(places) != 3: while len(places) != 3:
place = get_random_place() place = dbutils.get_random_place()
if place not in places: if place not in places:
places.append(place) places.append(place)
data["rooms"] = generate_place_data(npcs, places, lang) data["rooms"] = generate_place_data(npcs, places, lang)
data["questions"] = {} data["questions"] = {}
data["questions"]["QA_0"] = get_text_from_lid("FR", get_random_question(0).TEXT_LID) data["questions"]["QA_0"] = dbutils.get_text_from_lid("FR", dbutils.get_random_question(0).TEXT_LID)
data["questions"]["QA_1"] = get_text_from_lid("FR", get_random_question(1).TEXT_LID) data["questions"]["QA_1"] = dbutils.get_text_from_lid("FR", dbutils.get_random_question(1).TEXT_LID)
data["traits"] = get_traits(lang) data["traits"] = dbutils.get_traits(lang)
return data, reactions_table return data, reactions_table
@ -311,7 +312,7 @@ def get_trait_id_from_string(trait: str) -> int:
:param text: the text representation of the trait in any lang :param text: the text representation of the trait in any lang
:return: the trait_id linked to this text :return: the trait_id linked to this text
""" """
return get_trait_from_text(trait) return dbutils.get_trait_from_text(trait)
def get_npc_image(npc_id: int): def get_npc_image(npc_id: int):

View File

@ -1,7 +1,9 @@
import json import json
import json
import flask import flask
from truthinquiry import APP from truthinquiry.ext.discord_bot import discord_bot
from truthinquiry.ext.socketio import socket_io
from truthinquiry.logic import game_logic from truthinquiry.logic import game_logic
@ -24,7 +26,7 @@ def create_game():
flask.session["is_owner"] = True flask.session["is_owner"] = True
flask.session["username"] = username flask.session["username"] = username
APP.discord_bot.update_games_presence() discord_bot.update_games_presence()
return response return response
@ -61,7 +63,7 @@ def join_game():
flask.session["is_owner"] = False flask.session["is_owner"] = False
flask.session["username"] = username flask.session["username"] = username
APP.socketio_app.emit("playersjoin", [flask.session["username"]], room="game."+game.game_id) socket_io.emit("playersjoin", [flask.session["username"]], room="game."+game.game_id)
return {"error": 0} return {"error": 0}

View File

@ -2,11 +2,11 @@ import socketio
from flask_socketio import join_room from flask_socketio import join_room
from truthinquiry import APP
from truthinquiry.logic import game_logic from truthinquiry.logic import game_logic
from truthinquiry.ext.socketio import socket_io
@APP.socketio_app.on('connect') @socket_io.on('connect')
def connect(auth): def connect(auth):
if not (auth and "game_id" in auth): if not (auth and "game_id" in auth):
raise socketio.exceptions.ConnectionRefusedError("Invalid connection data passed") raise socketio.exceptions.ConnectionRefusedError("Invalid connection data passed")