135 "object.item.videoItem" )
172 QObject::tr(
"All Recordings"),
186 QObject::tr(
"Movies"),
200 QObject::tr(
"Title"),
230 QObject::tr(
"Genre"),
244 QObject::tr(
"Channel"),
258 QObject::tr(
"Recording Group"),
284 if (currentToken.isEmpty())
286 LOG(VB_GENERAL, LOG_ERR, QString(
"UPnpCDSTV::LoadMetadata: Final " 287 "token missing from id: %1")
293 if (tokens[currentToken].isEmpty())
304 pResults->
Add(container);
309 LOG(VB_GENERAL, LOG_ERR, QString(
"UPnpCDSTV::LoadMetadata: Requested " 310 "object cannot be found: %1")
313 else if (currentToken ==
"recording")
317 else if (currentToken ==
"title")
319 return LoadTitles(pRequest, pResults, tokens);
321 else if (currentToken ==
"date")
323 return LoadDates(pRequest, pResults, tokens);
325 else if (currentToken ==
"genre")
327 return LoadGenres(pRequest, pResults, tokens);
329 else if (currentToken ==
"recgroup")
333 else if (currentToken ==
"channel")
337 else if (currentToken ==
"movie")
339 return LoadMovies(pRequest, pResults, tokens);
342 LOG(VB_GENERAL, LOG_ERR,
343 QString(
"UPnpCDSTV::LoadMetadata(): " 344 "Unhandled metadata request for '%1'.").arg(currentToken));
357 if (currentToken.isEmpty() || currentToken ==
m_sExtensionId.toLower())
364 else if (currentToken ==
"title")
366 if (!tokens[
"title"].isEmpty())
369 return LoadTitles(pRequest, pResults, tokens);
371 else if (currentToken ==
"date")
373 if (!tokens[
"date"].isEmpty())
376 return LoadDates(pRequest, pResults, tokens);
378 else if (currentToken ==
"genre")
380 if (!tokens[
"genre"].isEmpty())
383 return LoadGenres(pRequest, pResults, tokens);
385 else if (currentToken ==
"recgroup")
387 if (!tokens[
"recgroup"].isEmpty())
392 else if (currentToken ==
"channel")
394 if (tokens[
"channel"].toInt() > 0)
399 else if (currentToken ==
"movie")
401 return LoadMovies(pRequest, pResults, tokens);
403 else if (currentToken ==
"recording")
408 LOG(VB_GENERAL, LOG_ERR,
409 QString(
"UPnpCDSTV::LoadChildren(): " 410 "Unhandled metadata request for '%1'.").arg(currentToken));
455 LOG(VB_UPNP, LOG_INFO,
456 "UPnpCDSTv::IsBrowseRequestForUs - Not sure... Calling base class.");
539 QString sql =
"SELECT SQL_CALC_FOUND_ROWS " 540 "r.title, r.inetref, r.recordedid, COUNT(*) " 542 "LEFT JOIN recgroups g ON r.recgroup=g.recgroup " 546 "LIMIT :OFFSET,:COUNT";
550 query.
prepare(sql.arg(whereString));
561 QString sTitle = query.
value(0).toString();
562 QString sInetRef = query.
value(1).toString();
563 int nRecordingID = query.
value(2).toInt();
564 int nTitleCount = query.
value(3).toInt();
575 pContainer->
SetPropValue(
"description", QObject::tr(
"%n Episode(s)",
"", nTitleCount));
576 pContainer->
SetPropValue(
"longdescription", QObject::tr(
"%n Episode(s)",
"", nTitleCount));
585 pResults->
Add(pContainer);
591 newTokens.insert(
"recording", QString::number(nRecordingID));
598 if (query.
size() > 0)
602 query.
prepare(
"SELECT FOUND_ROWS()");
626 QString sql =
"SELECT SQL_CALC_FOUND_ROWS " 627 "r.starttime, COUNT(r.recordedid) " 629 "LEFT JOIN recgroups g ON g.recgroup=r.recgroup " 631 "GROUP BY DATE(CONVERT_TZ(r.starttime, 'UTC', 'SYSTEM')) " 632 "ORDER BY r.starttime DESC " 633 "LIMIT :OFFSET,:COUNT";
637 query.
prepare(sql.arg(whereString));
648 QDate dtDate = query.
value(0).toDate();
649 int nRecCount = query.
value(1).toInt();
659 pResults->
Add(pContainer);
665 if (query.
size() > 0)
669 query.
prepare(
"SELECT FOUND_ROWS()");
693 QString sql =
"SELECT SQL_CALC_FOUND_ROWS " 694 "r.category, COUNT(r.recordedid) " 696 "LEFT JOIN recgroups g ON g.recgroup=r.recgroup " 698 "GROUP BY r.category " 699 "ORDER BY r.category " 700 "LIMIT :OFFSET,:COUNT";
704 query.
prepare(sql.arg(whereString));
715 QString sGenre = query.
value(0).toString();
716 int nRecCount = query.
value(1).toInt();
719 QString sDisplayGenre = sGenre.isEmpty() ? QObject::tr(
"No Genre") : sGenre;
720 sGenre = sGenre.isEmpty() ?
"MYTH_NO_GENRE" : sGenre;
730 pResults->
Add(pContainer);
736 if (query.
size() > 0)
740 query.
prepare(
"SELECT FOUND_ROWS()");
764 QString sql =
"SELECT SQL_CALC_FOUND_ROWS " 765 "r.recgroupid, g.displayname, g.recgroup, COUNT(r.recordedid) " 767 "LEFT JOIN recgroups g ON g.recgroup=r.recgroup " 769 "GROUP BY r.recgroup " 770 "ORDER BY g.displayname " 771 "LIMIT :OFFSET,:COUNT";
776 query.
prepare(sql.arg(whereString));
790 QString sDisplayName = query.
value(1).toString();
791 QString sName = query.
value(2).toString();
792 int nRecCount = query.
value(3).toInt();
796 sDisplayName.isEmpty() ? sName : sDisplayName,
802 pResults->
Add(pContainer);
808 if (query.
size() > 0)
812 query.
prepare(
"SELECT FOUND_ROWS()");
836 QString sql =
"SELECT SQL_CALC_FOUND_ROWS " 837 "r.chanid, c.channum, c.name, COUNT(r.recordedid) " 839 "JOIN channel c ON c.chanid=r.chanid " 840 "LEFT JOIN recgroups g ON g.recgroup=r.recgroup " 842 "GROUP BY c.channum " 843 "ORDER BY LPAD(CAST(c.channum AS UNSIGNED), 10, 0), " 844 " LPAD(c.channum, 10, 0)" 845 "LIMIT :OFFSET,:COUNT";
850 query.
prepare(sql.arg(whereString));
862 int nChanID = query.
value(0).toInt();
863 QString sChanNum = query.
value(1).toString();
864 QString sName = query.
value(2).toString();
865 int nRecCount = query.
value(3).toInt();
867 QString sFullName = QString(
"%1 %2").arg(sChanNum).arg(sName);
877 pResults->
Add(pContainer);
883 if (query.
size() > 0)
887 query.
prepare(
"SELECT FOUND_ROWS()");
902 tokens[
"category_type"] =
"movie";
946 if (tokens[
"recording"].toInt() > 0)
956 QString sql =
"SELECT SQL_CALC_FOUND_ROWS " 957 "r.chanid, r.starttime, r.endtime, r.title, " 958 "r.subtitle, r.description, r.category, " 959 "r.hostname, r.recgroup, r.filesize, " 960 "r.basename, r.progstart, r.progend, " 961 "r.storagegroup, r.inetref, " 962 "p.category_type, c.callsign, c.channum, " 963 "p.episode, p.totalepisodes, p.season, " 964 "r.programid, r.seriesid, r.recordid, " 965 "c.default_authority, c.name, " 966 "r.recordedid, r.transcoded, p.videoprop+0, p.audioprop+0, " 967 "f.video_codec, f.audio_codec, f.fps, f.width, f.height, " 970 "LEFT JOIN channel c ON r.chanid=c.chanid " 971 "LEFT JOIN recordedprogram p ON p.chanid=r.chanid " 972 " AND p.starttime=r.progstart " 973 "LEFT JOIN recgroups g ON r.recgroup=g.recgroup " 974 "LEFT JOIN recordedfile f ON r.recordedid=f.recordedid " 977 "LIMIT :OFFSET,:COUNT";
980 QString orderByString =
"ORDER BY r.starttime DESC, r.title";
982 if (!tokens[
"title"].isEmpty())
983 orderByString =
"ORDER BY p.season, p.episode, r.starttime ASC";
988 query.
prepare(sql.arg(whereString).arg(orderByString));
1000 int nChanid = query.
value( 0).toInt();
1003 QString sTitle = query.
value( 3).toString();
1004 QString sSubtitle = query.
value( 4).toString();
1005 QString sDescription = query.
value( 5).toString();
1006 QString sCategory = query.
value( 6).toString();
1007 QString sHostName = query.
value( 7).toString();
1008 QString sRecGroup = query.
value( 8).toString();
1009 uint64_t nFileSize = query.
value( 9).toULongLong();
1010 QString sBaseName = query.
value(10).toString();
1012 QDateTime dtProgStart =
1014 QDateTime dtProgEnd =
1016 QString sStorageGrp = query.
value(13).toString();
1018 QString sInetRef = query.
value(14).toString();
1019 QString sCatType = query.
value(15).toString();
1020 QString sCallsign = query.
value(16).toString();
1021 QString sChanNum = query.
value(17).toString();
1023 int nEpisode = query.
value(18).toInt();
1024 int nEpisodeTotal = query.
value(19).toInt();
1025 int nSeason = query.
value(20).toInt();
1027 QString sProgramId = query.
value(21).toString();
1028 QString sSeriesId = query.
value(22).toString();
1029 int nRecordId = query.
value(23).toInt();
1031 QString sDefaultAuthority = query.
value(24).toString();
1032 QString sChanName = query.
value(25).toString();
1034 int nRecordedId = query.
value(26).toInt();
1036 bool bTranscoded = query.
value(27).toBool();
1037 int nVideoProps = query.
value(28).toInt();
1040 QString sVideoCodec = query.
value(30).toString();
1041 QString sAudioCodec = query.
value(31).toString();
1042 double dVideoFrameRate = query.
value(32).toDouble();
1043 int nVideoWidth = query.
value(33).toInt();
1044 int nVideoHeight = query.
value(34).toInt();
1045 QString sContainer = query.
value(35).toString();
1062 URIBase.setScheme(
"http");
1072 QString sRefIDBase = QString(
"%1/Recording").arg(
m_sExtensionId);
1075 QString sRefId = QString(
"%1=%2")
1077 .arg( nRecordedId );
1097 if (!sSubtitle.isEmpty())
1100 pItem->
SetPropValue(
"description", sDescription.left(128).append(
" ..."));
1101 pItem->
SetPropValue(
"longDescription", sDescription );
1105 pItem->
SetPropValue(
"channelID" , sChanNum,
"DIGITAL");
1109 int nChanNum = sChanNum.toInt();
1111 pItem->
SetPropValue(
"channelNr" , QString::number(nChanNum) );
1113 if (sCatType !=
"movie")
1121 if ( nEpisode > 0 || nSeason > 0 )
1123 pItem->
SetPropValue(
"episodeNumber" , QString::number(nEpisode));
1124 pItem->
SetPropValue(
"episodeCount" , QString::number(nEpisodeTotal));
1129 int msecs = dtProgEnd.toMSecsSinceEpoch() - dtProgStart.toMSecsSinceEpoch();
1133 pItem->
SetPropValue(
"srsRecordScheduleID" , QString::number(nRecordId));
1135 if (!sSeriesId.isEmpty())
1139 QString sIdType =
"mythtv.org_XMLTV";
1140 if (sSeriesId.contains(sDefaultAuthority))
1141 sIdType =
"mythtv.org_EIT";
1146 if (!sProgramId.isEmpty())
1150 QString sIdType =
"mythtv.org_XMLTV";
1151 if (sProgramId.contains(sDefaultAuthority))
1152 sIdType =
"mythtv.org_EIT";
1154 pItem->
SetPropValue(
"programID", sProgramId, sIdType );
1173 QString sFilePath = sg.
FindFile(sBaseName);
1176 if ( QFile::exists(sFilePath) )
1196 uint32_t nDurationMS = 0;
1208 if (nDurationMS == 0)
1210 #if QT_VERSION < QT_VERSION_CHECK(5,8,0) 1211 uint uiStart = dtStartTime.toTime_t();
1212 uint uiEnd = dtEndTime.toTime_t();
1213 nDurationMS = (uiEnd - uiStart) * 1000;
1215 qint64 uiStart = dtStartTime.toMSecsSinceEpoch();
1216 qint64 uiEnd = dtEndTime.toMSecsSinceEpoch();
1217 nDurationMS = (uiEnd - uiStart);
1219 nDurationMS = (nDurationMS > 0) ? nDurationMS : 0;
1225 QSize resolution = QSize(nVideoWidth, nVideoHeight);
1229 if (sContainer.isEmpty())
1232 if (sMimeType ==
"video/mp2p")
1235 sContainer =
"MPEG2-PS";
1237 sContainer =
"MPEG2-TS";
1239 else if (sMimeType ==
"video/mp2t")
1241 sMimeType =
"video/mp2p";
1242 sContainer =
"MPEG2-TS";
1247 if (sVideoCodec.isEmpty())
1249 if (sMimeType ==
"video/mp2p" || sMimeType ==
"video/mp2t")
1250 sVideoCodec = (nVideoProps &
VID_AVC) ?
"H264" :
"MPEG2VIDEO";
1251 else if (sMimeType ==
"video/mp4")
1252 sVideoCodec =
"MPEG4";
1258 if (sMimeType ==
"video/mp2t" || sMimeType ==
"video/mp2p")
1259 sMimeType =
"video/mpeg";
1261 QUrl resURI = URIBase;
1263 resURI.setPath(
"/Content/GetRecording");
1264 resQuery.addQueryItem(
"RecordedId", QString::number(nRecordedId));
1265 resURI.setQuery(resQuery);
1279 if (nDurationMS > 0)
1281 if (nVideoHeight > 0 && nVideoWidth > 0)
1282 pRes->
AddAttribute (
"resolution" , QString(
"%1x%2").arg(nVideoWidth).arg(nVideoHeight) );
1283 pRes->
AddAttribute (
"size" , QString::number( nFileSize) );
1290 QUrl previewURI = URIBase;
1291 QUrlQuery previewQuery;
1292 previewURI.setPath(
"/Content/GetPreviewImage");
1293 previewQuery.addQueryItem(
"RecordedId", QString::number(nRecordedId));
1294 previewQuery.addQueryItem(
"Width",
"160");
1295 previewQuery.addQueryItem(
"Format",
"JPG");
1296 previewURI.setQuery(previewQuery);
1300 pItem->
AddResource( sProtocol, previewURI.toEncoded());
1305 if (!sInetRef.isEmpty())
1310 pResults->
Add( pItem );
1316 if (query.
size() > 0)
1320 query.
prepare(
"SELECT FOUND_ROWS()");
1332 int nSeason,
const QUrl& URIBase)
1334 QUrl artURI = URIBase;
1335 artURI.setPath(
"/Content/GetRecordingArtwork");
1336 QUrlQuery artQuery(artURI.query());
1337 artQuery.addQueryItem(
"Inetref", sInetRef);
1338 artQuery.addQueryItem(
"Season", QString::number(nSeason));
1339 artURI.setQuery(artQuery);
1353 QUrl thumbURI = artURI;
1354 QUrlQuery thumbQuery(thumbURI.query());
1355 thumbQuery.addQueryItem(
"Type",
"screenshot");
1356 thumbQuery.addQueryItem(
"Width",
"160");
1357 thumbQuery.addQueryItem(
"Height",
"160");
1358 thumbURI.setQuery(thumbQuery);
1362 QUrl smallURI = artURI;
1363 QUrlQuery smallQuery(smallURI.query());
1364 smallQuery.addQueryItem(
"Type",
"coverart");
1365 smallQuery.addQueryItem(
"Width",
"640");
1366 smallQuery.addQueryItem(
"Height",
"480");
1367 smallURI.setQuery(smallQuery);
1371 QUrl mediumURI = artURI;
1372 QUrlQuery mediumQuery(mediumURI.query());
1373 mediumQuery.addQueryItem(
"Type",
"coverart");
1374 mediumQuery.addQueryItem(
"Width",
"1024");
1375 mediumQuery.addQueryItem(
"Height",
"768");
1376 mediumURI.setQuery(mediumQuery);
1381 QUrl largeURI = artURI;
1382 QUrlQuery largeQuery(largeURI.query());
1383 largeQuery.addQueryItem(
"Type",
"fanart");
1384 largeURI.setQuery(largeQuery);
1386 QList<Property*> propList = pItem->
GetProperties(
"albumArtURI");
1387 if (propList.size() >= 4)
1392 pProp->
SetValue(mediumURI.toEncoded());
1394 pProp->
AddAttribute(
"xmlns:dlna",
"urn:schemas-dlna-org:metadata-1-0");
1397 pProp = propList.at(1);
1400 pProp->
SetValue(thumbURI.toEncoded());
1402 pProp->
AddAttribute(
"xmlns:dlna",
"urn:schemas-dlna-org:metadata-1-0");
1405 pProp = propList.at(2);
1408 pProp->
SetValue(smallURI.toEncoded());
1410 pProp->
AddAttribute(
"xmlns:dlna",
"urn:schemas-dlna-org:metadata-1-0");
1413 pProp = propList.at(3);
1416 pProp->
SetValue(largeURI.toEncoded());
1418 pProp->
AddAttribute(
"xmlns:dlna",
"urn:schemas-dlna-org:metadata-1-0");
1422 if (pItem->
m_sClass.startsWith(
"object.item.videoItem"))
1427 "image/jpeg", QSize(1024, 768));
1428 pItem->
AddResource( sProtocol, mediumURI.toEncoded());
1436 "image/jpeg", QSize(640, 480));
1437 pItem->
AddResource( sProtocol, smallURI.toEncoded());
1440 "image/jpeg", QSize(1920, 1080));
1441 pItem->
AddResource( sProtocol, largeURI.toEncoded());
1460 clauses.append(
"g.password=''");
1465 clauses.append(QString(
"g.recgroup != '%1'").arg(liveTVGroup));
1467 clauses.append(QString(
"g.recgroup != '%1'").arg(deletedGroup));
1469 if (tokens[
"recording"].toInt() > 0)
1470 clauses.append(
"r.recordedid=:RECORDED_ID");
1471 if (!tokens[
"date"].isEmpty())
1472 clauses.append(
"DATE(CONVERT_TZ(r.starttime, 'UTC', 'SYSTEM'))=:DATE");
1473 if (!tokens[
"genre"].isEmpty())
1474 clauses.append(
"r.category=:GENRE");
1475 if (!tokens[
"recgroup"].isEmpty())
1476 clauses.append(
"r.recgroup=:RECGROUP");
1477 if (!tokens[
"title"].isEmpty())
1478 clauses.append(
"r.title=:TITLE");
1479 if (!tokens[
"channel"].isEmpty())
1480 clauses.append(
"r.chanid=:CHANNEL");
1482 if (!tokens[
"category_type"].isEmpty())
1483 clauses.append(
"p.category_type=:CATTYPE");
1485 QString whereString;
1486 if (!clauses.isEmpty())
1488 whereString =
" WHERE ";
1489 whereString.append(clauses.join(
" AND "));
1502 if (tokens[
"recording"].toInt() > 0)
1503 query.
bindValue(
":RECORDED_ID", tokens[
"recording"]);
1504 if (!tokens[
"date"].isEmpty())
1505 query.
bindValue(
":DATE", tokens[
"date"]);
1506 if (!tokens[
"genre"].isEmpty())
1507 query.
bindValue(
":GENRE", tokens[
"genre"] ==
"MYTH_NO_GENRE" ?
"" : tokens[
"genre"]);
1508 if (!tokens[
"recgroup"].isEmpty())
1509 query.
bindValue(
":RECGROUP", tokens[
"recgroup"]);
1510 if (!tokens[
"title"].isEmpty())
1511 query.
bindValue(
":TITLE", tokens[
"title"]);
1512 if (tokens[
"channel"].toInt() > 0)
1513 query.
bindValue(
":CHANNEL", tokens[
"channel"]);
1514 if (!tokens[
"category_type"].isEmpty())
1515 query.
bindValue(
":CATTYPE", tokens[
"category_type"]);
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
bool LoadRecordings(const UPnpCDSRequest *pRequest, UPnpCDSExtensionResults *pResults, IDTokenMap tokens)
void SetValue(const QString &value)
void bindValue(const QString &placeholder, const QVariant &val)
virtual CDSObject * GetRoot()
bool LoadGenres(const UPnpCDSRequest *pRequest, UPnpCDSExtensionResults *pResults, IDTokenMap tokens)
bool LoadMovies(const UPnpCDSRequest *pRequest, UPnpCDSExtensionResults *pResults, IDTokenMap tokens)
QString BuildWhereClause(QStringList clauses, IDTokenMap tokens)
bool IsBrowseRequestForUs(UPnpCDSRequest *pRequest) override
QString NamedDayFormat(const QDateTime &dateTime)
Named-Day Format.
CDSObject * AddChild(CDSObject *pChild)
uint32_t QueryTotalDuration(void) const
If present this loads the total duration in milliseconds of the main video stream from recordedmarkup...
QString GetBackendServerIP(void)
Returns the IP address of the locally defined backend IP.
bool LoadMetadata(const UPnpCDSRequest *pRequest, UPnpCDSExtensionResults *pResults, IDTokenMap tokens, QString currentToken) override
Fetch just the metadata for the item identified in the request.
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Holds information on a TV Program one might wish to record.
static CDSObject * CreateContainer(QString sId, QString sTitle, QString sParentId, CDSObject *pObject=nullptr)
void SetChildCount(uint32_t nCount)
Allows the caller to set childCount without having to load children.
QString resDurationFormat(uint32_t msec)
res@duration Format B.2.1.4 res@duration - UPnP ContentDirectory Service 2008, 2013
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
bool LoadTitles(const UPnpCDSRequest *pRequest, UPnpCDSExtensionResults *pResults, IDTokenMap tokens)
void BindValues(MSqlQuery &query, IDTokenMap tokens)
bool LoadRecGroups(const UPnpCDSRequest *pRequest, UPnpCDSExtensionResults *pResults, IDTokenMap tokens)
QString ProtocolInfoString(UPNPProtocol::TransferProtocol protocol, const QString &mimeType, const QSize &resolution, double videoFrameRate, const QString &container, const QString &videoCodec, const QString &audioCodec, bool isTranscoded)
Create a properly formatted string for the 4th field of res@protocolInfo.
uint16_t m_nRequestedCount
QVariant value(int i) const
void SetChildContainerCount(uint32_t nCount)
Allows the caller to set childContainerCount without having to load children.
Add year only if different from current year.
static QString TestMimeType(const QString &sFileName)
static CDSObject * CreateMovieGenre(QString sId, QString sTitle, QString sParentId, CDSObject *pObject=nullptr)
static CDSObject * CreateAlbum(QString sId, QString sTitle, QString sParentId, CDSObject *pObject=nullptr)
QString DateTimeFormat(const QDateTime &dateTime)
Date-Time Format.
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
void AddAttribute(const QString &sName, const QString &sValue)
Resource * AddResource(QString sProtocol, QString sURI)
QList< Property * > GetProperties(const QString &sName)
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Do Today/Yesterday/Tomorrow transform.
static CDSObject * CreateVideoItem(QString sId, QString sTitle, QString sParentId, CDSObject *pObject=nullptr)
void Add(CDSObject *pObject)
uint32_t GetChildCount(void) const
Return the number of children in this container.
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
void AddAttribute(const QString &sName, const QString &sValue)
CDSObject * GetChild(const QString &sID)
QString CreateIDString(const QString &RequestId, const QString &Name, int Value)
virtual bool IsBrowseRequestForUs(UPnpCDSRequest *pRequest)
QMap< QString, int > m_mapBackendPort
void SetChanID(uint _chanid)
int GetBackendStatusPort(void)
Returns the locally defined backend status port.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QString DurationFormat(uint32_t msec)
Duration Format.
#define LOG(_MASK_, _LEVEL_, _STRING_)
void SetPropValue(const QString &sName, const QString &sValue, const QString &type="")
QStringMap m_mapBackendIp
QString FindFile(const QString &filename)
uint16_t m_nStartingIndex
static QString GetRecgroupString(uint recGroupID)
Temporary helper during transition from string to ID.
CDSShortCutList m_shortcuts
void SetRecordingStartTime(const QDateTime &dt)
bool LoadChildren(const UPnpCDSRequest *pRequest, UPnpCDSExtensionResults *pResults, IDTokenMap tokens, QString currentToken) override
Fetch the children of the container identified in the request.
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
virtual bool IsSearchRequestForUs(UPnpCDSRequest *pRequest)
bool IsSearchRequestForUs(UPnpCDSRequest *pRequest) override
bool LoadDates(const UPnpCDSRequest *pRequest, UPnpCDSExtensionResults *pResults, IDTokenMap tokens)
QMap< QString, QString > IDTokenMap
void PopulateArtworkURIS(CDSObject *pItem, const QString &sInetRef, int nSeason, const QUrl &URIBase)
void CreateRoot() override
bool LoadChannels(const UPnpCDSRequest *pRequest, UPnpCDSExtensionResults *pResults, IDTokenMap tokens)