1
0
mirror of https://github.com/JvanKatwijk/qt-dab.git synced 2025-10-06 00:02:40 +02:00
Files
SDR-DAB_Qt-DAB/sources/backend/data/epg/xml-extractor.cpp
2025-07-16 20:32:47 +02:00

271 lines
8.2 KiB
C++

#
/*
* Copyright (C) 2015 .. 2025
* Jan van Katwijk (J.vanKatwijk@gmail.com)
* Lazy Chair Computing
*
* This file is part of the Qt-DAB
*
* Qt-DAB is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Qt-DAB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Qt-DAB; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "xml-extractor.h"
#include <QStringList>
multimediaElement::multimediaElement () {
valid = false;
}
multimediaElement::~multimediaElement () {}
static inline
QStringList splitter (const QString &s, QString splitString) {
#if QT_VERSION >= QT_VERSION_CHECK (5, 15, 2)
QStringList list = s.split (splitString, Qt::SkipEmptyParts);
#else
QStringList list = s.split (splitString, QString::SkipEmptyParts);
#endif
return list;
}
static inline
int numValue (char c) {
if (('0' <= c) && (c <= '9'))
return c - (int)('0');
if (('a' <= c) && (c <= 'f'))
return (int)c - 'a' + 10;
return (int)c - 'A' + 10;
}
static inline
uint32_t toIntFrom (const QString &s, int base) {
uint32_t res = 0;
for (int i = 0; i < s. size (); i ++)
res = res * base + numValue (s [i]. toLatin1 ());
return res;
}
scheduleDescriptor::scheduleDescriptor () {}
scheduleDescriptor::~scheduleDescriptor () {}
xmlExtractor::xmlExtractor () {}
xmlExtractor::~xmlExtractor () {}
//
// The xml format for date is xxxx-xx-xxTyy:yy
QDate xmlExtractor::stringToDate (const QString &date) {
QStringList t = splitter (date, "T");
QStringList temp = splitter (t [0], QString ("-"));
int year = toIntFrom (temp [0], 10);
int month = toIntFrom (temp [1], 10);
int day = toIntFrom (temp [2], 10);
return QDate (year, month, day);
}
QDateTime xmlExtractor::stringToDateTime (const QString &date) {
QStringList t = splitter (date, "T");
QString pureDate = t [0];
QStringList temp = splitter (pureDate, QString ("-"));
int year = toIntFrom (temp [0], 10);
int month = toIntFrom (temp [1], 10);
int day = toIntFrom (temp [2], 10);
QDate datum = QDate (year, month, day);
QTime time;
if (t. size () < 2) { // should not happen
time = QTime::currentTime ();
}
else {
temp = splitter (t [1], QString (":"));
int hours = toIntFrom (temp [0], 10);
int minutes = toIntFrom (temp [1], 10);
time = QTime (hours, minutes);
}
return QDateTime (datum, time);
}
//
// duration has the form PTXXHXXM of PTXXM
int xmlExtractor::durationToInt (const QString &dur) {
int hours = 0;
int minutes = 0;
if (!dur. startsWith ("PT"))
return -1;
#if QT_VERSION >= QT_VERSION_CHECK (6, 1, 1)
QString ss = dur. last (dur. size () - 2);
#else
QString ss = dur;
ss. remove (0, 2);
#endif
if (ss. contains ('H')) { // hours and may be minutes
QStringList hh = splitter (ss, QString ("H"));
hours = toIntFrom (hh [0], 10);
if (hh [1]. size () > 1)
minutes = toIntFrom (hh [1]. left (hh [1]. size () - 1), 10);
}
else
minutes = toIntFrom (ss. left (ss. size () - 1), 10);
return 60 * hours + minutes;
}
programDescriptor xmlExtractor::
process_programme (const QDomElement &node) {
programDescriptor res;
res. valid = false;
QDomElement location =
node. firstChildElement ("location");
if (location. isNull ())
return res;
QDomElement time =
location. firstChildElement ("time");
if (time. isNull ())
return res;
QString tt = time. attribute ("time");
res. startTime = stringToDateTime (tt);
QString dd = time. attribute ("duration");
res. duration = durationToInt (dd);
QDomElement sn = node. firstChildElement ("shortName");
res. shortName = sn. text ();
QDomElement mn = node. firstChildElement ("mediumName");
res. mediumName = mn. text ();
QDomElement ln = node. firstChildElement ("longName");
res. longName = ln. text ();
QDomElement md = node. firstChildElement ("mediaDescription");
QDomElement sd = md. firstChildElement ("shortDescriptor");
res. shortDescriptor = sd. text ();
QDomElement ld = md. firstChildElement ("longDescriptor");
res. longDescriptor = ld. text ();
res. valid = true;
return res;
}
int xmlExtractor::getVersion (const QDomElement &node) {
if (!node. hasAttribute ("version"))
return 1;
QString version = node. attribute ("version");
return toIntFrom (version, 10);
}
scheduleDescriptor xmlExtractor::
getScheduleDescriptor (const QDomElement &node,
QDate &theDate,
uint32_t ensembleId,
uint32_t serviceId) {
scheduleDescriptor result;
result. valid = false;
result. Version = getVersion (node);
QDomElement name = node. firstChildElement ("mediumName");
if (name. isNull ())
name = node. firstChildElement ("longName");
result. name =
!name. isNull () ? name. text () : "";
//
QString startDate;
QString stopDate;
QString duration;
// The german schedule descriptions usually contain the scope element
QDomElement scope = node. firstChildElement ("scope");
if (!scope. isNull ()) {
if (scope. hasAttribute ("startTime"))
startDate = scope. attribute ("startTime");
if (scope. hasAttribute ("stopTime"))
stopDate = scope. attribute ("stopTime");
QDomElement serviceScope =
scope. firstChildElement ("serviceScope");
if (!serviceScope. isNull ()) {
QString identity = serviceScope. attribute ("id");
QStringList ident = splitter (identity, QString (":"));
ensembleId = toIntFrom (ident [1], 16);
serviceId = toIntFrom (ident [2], 16);
}
}
QDomElement location = node. firstChildElement ("location");
if (!location. isNull ()) {
QDomElement time = location. firstChildElement ("time");
if (!time. isNull ()) {
if (time. hasAttribute ("time"))
startDate = location. attribute ("time");
if (time. hasAttribute ("duration"))
duration = location. attribute ("duration");
}
}
QDateTime startTime;
QDateTime stopTime;
if (startDate == "") {
QTime beginTime = QTime (0, 0, 0);
QTime endTime = QTime (23, 59, 59);
startTime = QDateTime (theDate, beginTime);
stopTime = QDateTime (theDate, endTime);
}
else {
startTime = stringToDateTime (startDate);
if (duration != "") {
int minutes = durationToInt (duration);
stopTime = startTime. addSecs (minutes * 60);
}
else
stopTime = stringToDateTime (stopDate);
}
result. startTime = startTime;
result. stopTime = stopTime;
result. Eid = ensembleId;
result. Sid = serviceId;
result. valid = true;
return result;
}
multimediaElement xmlExtractor::extract_multimedia (const QDomElement &multimedia) {
multimediaElement res;
if (multimedia. hasAttribute ("url"))
res. url = multimedia. attribute ("url");
else
return res;
if (multimedia. hasAttribute ("width")) {
res. width = toIntFrom (multimedia. attribute ("width"), 10);
}
else
res. width = 0;
res. valid = true;
return res;
}
QString xmlExtractor::service_url (const QDomElement &service) {
QDomElement mediaDescription =
service. firstChildElement ("mediaDescription");
if (mediaDescription. isNull ())
return "";
QDomElement multimedia =
mediaDescription. firstChildElement ("multimedia");
if (multimedia. isNull ())
return "";
if (multimedia. hasAttribute ("url"))
return multimedia. attribute ("url");
return "";
}
uint32_t xmlExtractor::serviceSid (const QDomElement &service) {
QDomElement bearer = service. firstChildElement ("bearer");
if (bearer. isNull ())
return 0;
if (!bearer. hasAttribute ("id"))
return 0;
QString id = bearer. attribute ("id");
QStringList t = splitter (id, ":");
if (t. size () < 3)
return 0;
return toIntFrom (t [2], 16);
}