File indexing completed on 2024-05-05 16:49:20

0001 /*
0002  * SPDX-FileCopyrightText: 2021 Anjani Kumar <anjanik012@gmail.com>
0003  * SPDX-FileCopyrightText: 2021 Han Young <hanyoung@protonmail.com>
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "capparser.h"
0008 #include "kweathercore_p.h"
0009 #include <QDateTime>
0010 #include <QDebug>
0011 #include <KLocalizedString>
0012 
0013 namespace KWeatherCore
0014 {
0015 CAPParser::CAPParser(const QByteArray &data)
0016     : m_xml(data)
0017 {
0018     bool flag = false;
0019     if (!data.isEmpty()) {
0020         while (m_xml.readNextStartElement()) {
0021             if (m_xml.name() == QStringLiteral("alert")) {
0022                 flag = true;
0023                 qDebug() << "valid cap file";
0024                 break;
0025             }
0026         }
0027         if (!flag) {
0028             qWarning() << "Not a CAP XML";
0029         }
0030     }
0031 }
0032 void CAPParser::setData(const QByteArray &data)
0033 {
0034     m_xml.clear();
0035     m_xml.addData(data);
0036 }
0037 std::unique_ptr<AlertEntry> CAPParser::parse()
0038 {
0039     auto entry = std::make_unique<AlertEntry>();
0040     while (m_xml.readNextStartElement()) {
0041         switch (tags[m_xml.name().toString()]) {
0042         case Tags::IDENTIFIER:
0043             entry->setIdentifier(m_xml.readElementText());
0044             break;
0045         case Tags::SENDER:
0046             entry->setSender(m_xml.readElementText());
0047             break;
0048         case Tags::SENT_TIME:
0049             entry->setSentTime(
0050                 QDateTime::fromString(m_xml.readElementText(), Qt::ISODate));
0051             break;
0052         case Tags::STATUS: {
0053             AlertEntry::Status status;
0054             auto elementText = m_xml.readElementText();
0055             if (elementText == QStringLiteral("Actual"))
0056                 status = AlertEntry::Status::Actual;
0057             else if (elementText == QStringLiteral("Excercise"))
0058                 status = AlertEntry::Status::Exercise;
0059             else if (elementText == QStringLiteral("System"))
0060                 status = AlertEntry::Status::System;
0061             else if (elementText == QStringLiteral("Test"))
0062                 status = AlertEntry::Status::Test;
0063             else if (elementText == QStringLiteral("Draft"))
0064                 status = AlertEntry::Status::Draft;
0065             else
0066                 qWarning() << "Unknown status field";
0067             entry->setStatus(status);
0068             break;
0069         }
0070         case Tags::MSG_TYPE: {
0071             AlertEntry::MsgType msgType;
0072             auto elementText = m_xml.readElementText();
0073             if (elementText == QStringLiteral("Alert"))
0074                 msgType = AlertEntry::MsgType::Alert;
0075             else if (elementText == QStringLiteral("Update"))
0076                 msgType = AlertEntry::MsgType::Update;
0077             else if (elementText == QStringLiteral("Cancel"))
0078                 msgType = AlertEntry::MsgType::Cancel;
0079             else if (elementText == QStringLiteral("Ack"))
0080                 msgType = AlertEntry::MsgType::Ack;
0081             else if (elementText == QStringLiteral("Error"))
0082                 msgType = AlertEntry::MsgType::Error;
0083             else
0084                 qWarning() << "Unknown msgType field";
0085             entry->setMsgType(msgType);
0086             break;
0087         }
0088         case Tags::SCOPE: {
0089             AlertEntry::Scope scope;
0090             auto elementText = m_xml.readElementText();
0091             if (elementText == QStringLiteral("Public"))
0092                 scope = AlertEntry::Scope::Public;
0093             else if (elementText == QStringLiteral("Private"))
0094                 scope = AlertEntry::Scope::Private;
0095             else if (elementText == QStringLiteral("Restricted"))
0096                 scope = AlertEntry::Scope::Restricted;
0097             else
0098                 qWarning() << "Unknown scope field";
0099 
0100             entry->setScope(scope);
0101             break;
0102         }
0103         case Tags::NOTE:
0104             entry->setNote(m_xml.readElementText());
0105             break;
0106         case Tags::INFO: {
0107             auto info = parseInfo();
0108             entry->addInfo(info);
0109             break;
0110         }
0111         default:
0112             m_xml.skipCurrentElement();
0113         }
0114     }
0115     return entry;
0116 }
0117 
0118 AlertInfo CAPParser::parseInfo()
0119 {
0120     AlertInfo info;
0121 
0122     if (m_xml.name() == QStringLiteral("info")) {
0123         while (!m_xml.atEnd() && !(m_xml.isEndElement() && m_xml.name() == QStringLiteral("info"))) {
0124             m_xml.readNext();
0125             if (m_xml.isStartElement() && infoTags.count(m_xml.name().toString())) {
0126                 qDebug() << m_xml.name();
0127                 switch (infoTags[m_xml.name().toString()]) {
0128                 case InfoTags::CATEGORY: {
0129                     auto s = m_xml.readElementText();
0130                     if (categoryMap.count(s))
0131                         info.addCategory(categoryMap[s]);
0132                     break;
0133                 }
0134                 case InfoTags::EVENT:
0135                     info.setEvent(m_xml.readElementText());
0136                     break;
0137                 case InfoTags::URGENCY:
0138                     info.setUrgency(urgencyStrToEnum(m_xml.readElementText()));
0139                     break;
0140                 case InfoTags::SEVERITY:
0141                     info.setSeverity(severityStrToEnum(m_xml.readElementText()));
0142                     break;
0143                 case InfoTags::CERTAINITY:
0144                     info.setCertainty(certaintyStrToEnum(m_xml.readElementText()));
0145                     break;
0146                 case InfoTags::EFFECTIVE_TIME:
0147                     info.setEffectiveTime(QDateTime::fromString(
0148                         m_xml.readElementText(), Qt::ISODate));
0149                     break;
0150                 case InfoTags::ONSET_TIME:
0151                     info.setOnsetTime(QDateTime::fromString(
0152                         m_xml.readElementText(), Qt::ISODate));
0153                     break;
0154                 case InfoTags::EXPIRE_TIME:
0155                     info.setExpireTime(QDateTime::fromString(
0156                         m_xml.readElementText(), Qt::ISODate));
0157                     break;
0158                 case InfoTags::HEADLINE:
0159                     info.setHeadline(m_xml.readElementText());
0160                     break;
0161                 case InfoTags::DESCRIPTION:
0162                     info.setDescription(m_xml.readElementText());
0163                     break;
0164                 case InfoTags::INSTRUCTION:
0165                     info.setInstruction(m_xml.readElementText());
0166                     break;
0167                 case InfoTags::PARAMETER: {
0168                     std::pair<QString, QString> p;
0169                     m_xml.readNextStartElement();
0170                     if (m_xml.name() == QStringLiteral("valueName"))
0171                         p.first = m_xml.readElementText();
0172                     m_xml.readNextStartElement();
0173                     if (m_xml.name() == QStringLiteral("value"))
0174                         p.second = m_xml.readElementText();
0175                     info.addParameter(p);
0176                     break;
0177                 }
0178                 case InfoTags::AREA: {
0179                     while (!(m_xml.isEndElement() &&
0180                              m_xml.name() == QStringLiteral("area"))) {
0181                         if (m_xml.name() == QStringLiteral("areaDesc") &&
0182                             !m_xml.isEndElement())
0183                             info.setAreaDesc(m_xml.readElementText());
0184                         else if (m_xml.name() == QStringLiteral("geocode") &&
0185                                  !m_xml.isEndElement()) {
0186                             std::pair<QString, QString> p;
0187                             m_xml.readNextStartElement();
0188                             if (m_xml.name() == QStringLiteral("valueName"))
0189                                 p.first = m_xml.readElementText();
0190                             m_xml.readNextStartElement();
0191                             if (m_xml.name() == QStringLiteral("value"))
0192                                 p.second = m_xml.readElementText();
0193                             info.addAreaCode(p);
0194                         } else if (m_xml.name() == QStringLiteral("polygon") &&
0195                                    !m_xml.isEndElement()) {
0196                             info.addPolygon(stringToPolygon(m_xml.readElementText()));
0197                         }
0198                         m_xml.readNext();
0199                     }
0200                     break;
0201                 }
0202                 case InfoTags::SENDERNAME: {
0203                     info.setSender(m_xml.readElementText());
0204                     break;
0205                 }
0206                 case InfoTags::LANGUAGE:
0207                     info.setLanguage(m_xml.readElementText());
0208                     break;
0209                 }
0210             } else {
0211                 if (m_xml.isStartElement())
0212                     qWarning() << "unlnown element: " << m_xml.name();
0213             }
0214         }
0215     }
0216     return info;
0217 }
0218 }