This commit is contained in:
Mathieu B 2021-07-26 18:23:32 +02:00
commit 8131b046b2
15 changed files with 378 additions and 0 deletions

138
.gitignore vendored Normal file
View File

@ -0,0 +1,138 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
.idea
.idea/**
.idea/*
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
/ffmpeg/
/config/secrets.json

10
config/config.json Normal file
View File

@ -0,0 +1,10 @@
{
"HOMEASSISTANT_API_TOKEN": "!secret HOMEASSISTANT_API_TOKEN",
"HOMEASSISTANT_API_URL": "!secret HOMEASSISTANT_API_URL",
"API_KEY": "!secret API_KEY",
"SPOTIFY_CLIENT_ID": "!secret SPOTIFY_CLIENT_ID",
"SPOTIFY_CLIENT_SECRET": "!secret SPOTIFY_CLIENT_SECRET",
"PORT": 5000,
"CLIENT_URL": "http://127.0.0.1:5001",
"TRAIN_ON_START": false
}

1
get_path_file.py Normal file
View File

@ -0,0 +1 @@
# THIS FILE DOESN'T DO ANYTHING EXCEPT GIVE THE PROJECT MAIN PATH (i'm listening for better ideas)

0
intents/__init__.py Normal file
View File

View File

@ -0,0 +1,6 @@
{
"name": "Date and Time",
"languages": ["FR-FR", "EN-EN"],
"intents": ["what_time_is_it", "what_day_is_it"],
"variables": ["time", "day"]
}

View File

@ -0,0 +1,13 @@
import utils.intents_utils
def what_time_is_it():
return ""
def what_day_is_it():
return ""
if __name__ == '__main__':
print(utils.intents_utils.get_response("what_time_is_it"))

View File

@ -0,0 +1,27 @@
{
"what_time_is_it": {
"patterns": [
"What time is it",
"Show me the time",
"Tell me the time",
"What's the time",
"What is the time"
],
"responses": [
"It is {time}",
"It's {time} right now",
"The time is {time}"
]
},
"what_day_is_it": {
"patterns": [
"What's the day",
"Tell me the day of the week. ",
"What day are we"
],
"response": [
"{day}",
"Today is {day}"
]
}
}

View File

@ -0,0 +1,26 @@
{
"what_time_is_it": {
"patterns": [
"Il est quelle heure",
"C'est quelle heure",
"On vit quelle heure",
"Quelle heure est-il"
],
"responses": [
"Il est {time}",
"Il est actuellement {time}"
]
},
"what_day_is_it": {
"patterns": [
"On est quel jour",
"Quel jour est-on",
"C'est quel jour aujourd'hui"
],
"response": [
"Nous somme le {day}",
"Aujourd'hui nous sommes {day}",
"On est {day}"
]
}
}

38
intents/intents.py Normal file
View File

@ -0,0 +1,38 @@
import glob
import json
import os
import get_path_file
intents = dict()
path = os.path.dirname(get_path_file.__file__)
def register_all_intents():
global intents
result = {}
files = glob.glob(path + "/intents/**/info.json", recursive=True)
for f in files:
with open(f, "rb") as infile:
intent_info_json = json.load(infile)
intents_in_info = intent_info_json['intents']
intent_path = str(f).replace('info.json', '')
for intent in intents_in_info:
result[intent] = intent_path
intents = result
def get_all_intents():
if len(intents) >= 1:
return intents
else:
register_all_intents()
return get_all_intents()
if __name__ == '__main__':
print(get_all_intents())

23
main.py Normal file
View File

@ -0,0 +1,23 @@
import flask
from flask import Flask, request, jsonify, Response
from utils import config_utils, flask_utils
app = Flask(__name__)
@app.route("/process", methods=['POST'])
def process_request():
data = flask_utils.get_data_in_request(request)
if 'sentence' not in data:
flask.abort(Response('You must provide a \'sentence\' parameter!'))
print(data)
return jsonify(data)
if __name__ == '__main__':
# start the flask server
app.config['JSON_AS_ASCII'] = False
app.run(port=config_utils.get_in_config("PORT"), debug=False, host='0.0.0.0', threaded=True)

1
requirements.txt Normal file
View File

@ -0,0 +1 @@
flask

0
utils/__init__.py Normal file
View File

29
utils/config_utils.py Normal file
View File

@ -0,0 +1,29 @@
import json
import os
import get_path_file
path = os.path.dirname(get_path_file.__file__)
def get_in_config(name):
config_json = json.load(open(path + "/config/config.json", encoding='utf-8', mode='r'))
if name in config_json:
if isinstance(config_json.get(name), str):
if "!secret" in config_json.get(name):
# secret_name = config_json.get(name).removeprefix('!secret ')
secret_name = config_json.get(name).replace('!secret ', '')
return get_in_secret(secret_name)
else:
return config_json.get(name)
else:
return config_json.get(name)
def get_in_secret(secret_name):
secrets_json = json.load(open(path + "/config/secrets.json", encoding='utf-8', mode='r'))
if secret_name in secrets_json:
return secrets_json.get(secret_name)
else:
return "Not found!"

16
utils/flask_utils.py Normal file
View File

@ -0,0 +1,16 @@
import json
def get_data_in_request(request):
data_str = str(request.data.decode('utf8')).replace('"', '\"').replace("\'", "'")
# if no data return an empty json to avoid error with json.loads below
if not data_str:
return {}
data_json = json.loads(data_str)
if not isinstance(data_json, dict):
data_json = json.loads(data_json)
return data_json

50
utils/intents_utils.py Normal file
View File

@ -0,0 +1,50 @@
import json
import os
import random
import intents.intents
def get_patterns(intent_tag):
if exists(intent_tag):
patterns = get_lang_for_intent(intent_tag).get(intent_tag).get('patterns')
return patterns
else:
return {}
def get_responses(intent_tag):
if exists(intent_tag):
responses = get_lang_for_intent(intent_tag).get(intent_tag).get('responses')
return responses
else:
return {}
def get_response(intent_tag):
if exists(intent_tag):
responses = get_responses(intent_tag)
return random.choice(responses)
def get_lang_for_intent(intent_tag):
language = "fr-fr" # TODO: use config value
# first we check the intent
if exists(intent_tag):
lang_path = str(intents.intents.get_all_intents().get(intent_tag))
lang_path = lang_path + 'lang/' + language + '.json'
if os.path.exists(lang_path):
lang_file = open(lang_path)
json_lang = json.load(lang_file)
return json_lang
else:
return {}
def exists(intent_tag):
if intent_tag in intents.intents.get_all_intents():
return True
else:
return False