File indexing completed on 2024-04-14 04:37:59

0001 /*
0002  * Copyright 2021 Aditya Mehra <aix.m@outlook.com>
0003  *
0004  * Licensed under the Apache License, Version 2.0 (the "License");
0005  * you may not use this file except in compliance with the License.
0006  * You may obtain a copy of the License at
0007  *
0008  *    http://www.apache.org/licenses/LICENSE-2.0
0009  *
0010  * Unless required by applicable law or agreed to in writing, software
0011  * distributed under the License is distributed on an "AS IS" BASIS,
0012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013  * See the License for the specific language governing permissions and
0014  * limitations under the License.
0015  *
0016  */
0017 
0018 #include "skillmanager.h"
0019 #include <QJsonObject>
0020 #include <QJsonArray>
0021 #include <QJsonDocument>
0022 
0023 SkillManager::SkillManager(QObject *parent): 
0024     QObject(parent),
0025     m_controller(Controller::instance())
0026 {
0027     m_controller->start();
0028     connect(m_controller, &Controller::socketStatusChanged, this,
0029             [this]() {
0030         if (m_controller->status() == Controller::Open){
0031             if (m_socketReady == true){
0032                 return;
0033             } else {
0034                 m_socketReady =  true;
0035             };
0036             emit socketReadyChanged(isSocketReady());
0037         }
0038     });
0039     
0040     connect(m_controller, &Controller::messageReceived, this, &SkillManager::onMainSocketMessageReceived);
0041 }
0042 
0043 SkillManager::~SkillManager()
0044 {
0045     deleteSkill();
0046     m_controller->disconnectSocket();
0047 }
0048 
0049 bool SkillManager::isSocketReady() const {
0050     return m_socketReady;
0051 }
0052 
0053 QString SkillManager::socketAddress() const
0054 {
0055     return m_controller->webSocketAddress();
0056 }
0057 
0058 void SkillManager::setSocketAddress(QString socketAddress)
0059 {
0060     if (m_controller->webSocketAddress() == socketAddress){
0061         return;
0062     }
0063     m_controller->setWebSocketAddress(socketAddress);
0064     emit socketAddressChanged();
0065 }
0066 
0067 QString SkillManager::skillNamespace() const
0068 {
0069     return m_settings.value(QStringLiteral("skillNamespace")).toString();
0070 }
0071 
0072 void SkillManager::setSkillNamespace(QString skillNamespace)
0073 {
0074     if (SkillManager::skillNamespace() == skillNamespace) {
0075         return;
0076     }
0077     m_settings.setValue(QStringLiteral("skillNamespace"), skillNamespace);
0078     emit skillNamespaceChanged();
0079 }
0080 
0081 QQmlListProperty<SkillEntry> SkillManager::items()
0082 {
0083     return QQmlListProperty<SkillEntry>(this, &this->m_items);
0084 }
0085 
0086 int SkillManager::itemsCount() const
0087 {
0088     return m_items.count();
0089 }
0090 
0091 SkillEntry *SkillManager::item(int index) const
0092 {
0093     return m_items.at(index);
0094 }
0095 
0096 QJsonObject SkillManager::toJson(SkillEntry* &item) const
0097 {
0098     return {{QStringLiteral("intent"), item->intent()}, {QStringLiteral("voc"), item->voc()}, {QStringLiteral("action"), item->action()}, {QStringLiteral("dialog"), item->dialog()}};
0099 }
0100 
0101 void SkillManager::createSkill()
0102 {
0103     QJsonObject root;
0104     root[QStringLiteral("namespace")] = m_settings.value(QStringLiteral("skillNamespace")).toString();
0105 
0106     QJsonArray array;
0107     for(int i = 0; i < m_items.count(); i++){
0108         array.append(toJson(m_items[i]));
0109     }
0110     root[QStringLiteral("parameters")] = array;
0111     
0112     if(m_socketReady){
0113         m_controller->sendRequest(QStringLiteral("mycroft.create.dynamic.skill"), root.toVariantMap());
0114     }
0115 }
0116 
0117 void SkillManager::deleteSkill()
0118 {
0119     QJsonObject root;
0120     root[QStringLiteral("namespace")] = m_settings.value(QStringLiteral("skillNamespace")).toString();
0121 
0122     QJsonArray array;
0123     for(int i = 0; i < m_items.count(); i++){
0124         array.append(toJson(m_items[i]));
0125     }
0126     root[QStringLiteral("parameters")] = array;
0127     
0128     if(m_socketReady){
0129         m_controller->sendRequest(QStringLiteral("mycroft.delete.dynamic.skill"), root.toVariantMap());
0130     }
0131 }
0132 
0133 void SkillManager::onMainSocketMessageReceived(const QString &message)
0134 {
0135     auto doc = QJsonDocument::fromJson(message.toUtf8());
0136 
0137     if (doc.isEmpty()) {
0138         qWarning() << "Empty or invalid JSON message arrived on the main socket:" << message;
0139         return;
0140     }
0141     
0142     auto type = doc[QStringLiteral("type")].toString();
0143     
0144     if(type == QStringLiteral("mycroft.dynamic.skill.intent")){
0145         QString intent_target = doc[QStringLiteral("data")][QStringLiteral("intent_target")].toString();
0146         QString intent_call = doc[QStringLiteral("data")][QStringLiteral("intent_call")].toString();
0147         auto intent_caller = doc[QStringLiteral("data")][QStringLiteral("intent_caller")].toVariant();
0148 
0149         for(int i = 0; i < m_items.count(); i++){
0150             if(intent_target == skillNamespace() && m_items[i]->intent() == intent_call){
0151                 emit intentResponse(doc.toJson(), m_items[i]->action());
0152                 if(m_items[i]->dialog() != QStringLiteral("")){
0153                     m_controller->sendRequest(QStringLiteral("mycroft.dynamic.skill.speak"), {{QStringLiteral("dialog"), m_items[i]->dialog()}});
0154                 }
0155             }
0156         }
0157     }
0158 }